운영체제는 RedHat 기반의 RockyLinux 9.1을 사용했습니다.
기본적으로 80포트는 개방되어 있어야합니다.
// 80포트 개방
firewall-cmd --permanent --zone=public --add-port=80/tcp
//방화벽 재가동
firewall-cmd –-reload
(네트워크 포트 포워딩은 시리즈 게시글 중에 있습니다)
yum install epel-release
EPEL은 Extra Packages for Enterprise Linux 의 약자로 RHEL/CentOS 에 포함되지 않은 여러 패키지들을 설치할 수 있는 community 기반의 저장소입니다.
EPEL 은 fedora 에서 관리하고 있으며 제공되는 패키지들은 IT Automation 도구인 ansible, 성능 수집 도구인 collectd, Message Broker 인 RabbitMQ 등이 있습니다.
yum install certbot
cerbot은 SSL 인증서를 유료로 발급받을 수 있도록 도와주는 라이브러리입니다.
cerbot과 Let's Encrypt를 사용해서 무료로 SSL을 받을 수 있습니다.
firewall-cmd --permanent --add-service=https
firewall-cmd --reload
https는 기본적으로 443포트를 사용합니다. 포트는 사용자가 변경할 수 있지만 저는 그대로 443을 사용하겠습니다.
docker stop 컨테이너 ID or 컨테이너 이름
–standalone 옵션으로 인증서 생성 시 오류가 나기 때문에 잠깐 nginx를 꺼야 합니다.
저는 도커를 사용하기 때문에 컨테이너를 종료시켰습니다.
# 1. 도메인이 한개일때
certbot certonly --standalone -d 생성할 도메인
# 2. 도메인이 여러개일때
certbot certonly --standalone -d 생성할 도메인1 -d 생성할 도메인2
모두 yes를 입력하고 넘어갑니다.
발급이 완료되면 /etc/letsencrypt/live/도메인 이름 폴더가 생성되고 그 안에는 .pem 키들이 있는 것을 확인하실 수 있습니다.
/etc/letsencrypt/ 위치에 options-ssl-nginx.conf파일을 생성합니다.
vim options-ssl-nginx.conf
아래 내용을 넣습니다.
# This file contains important security parameters. If you modify this file
# manually, Certbot will be unable to automatically provide future security
# updates. Instead, Certbot will print and log an error message with a path to
# the up-to-date file that you will need to refer to when manually updating
# this file. Contents are based on https://ssl-config.mozilla.org
ssl_session_cache shared:le_nginx_SSL:10m;
ssl_session_timeout 1440m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384";
nginx 설정을 위해 nginx 컨테이너와 연결된 볼륨을 만들고 거기에 설정 파일을 작성해 준다.
# 볼륨 생성
docker volume create 사용할 볼륨 이름
ex) docker volume create nginx
# 볼륨 주소 확인
docker volume inspect 볼륨 이름
ex) docker volume inspect nginx
#결과
[
{
"CreatedAt": "2023-03-19T00:54:55+09:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/nginx/_data",
"Name": "nginx",
"Options": null,
"Scope": "local"
}
]
# 볼륨 위치로 이동
cd /var/lib/docker/volumes/nginx/_data
# 설정 파일 생성
vim default.conf
# 파일 내용
upstream app {
least_conn;
server 서버 ip주소:포트 번호;
server 서버 ip주소:포트 번호;
}
server {
listen 443 ssl;
server_tokens off;
server_name 도메인 이름;
ssl_certificate /etc/letsencrypt/live/you-have-to.duckdns.org/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/you-have-to.duckdns.org/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
location / {
proxy_pass https://app;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
저는 로드밸런싱을 해주느라
upstream app {
least_conn;
server 서버 ip주소:포트 번호;
server 서버 ip주소:포트 번호;
}
내용이 추가되었습니다.
로드밸런싱을 하지 않는다면 proxy_pass에 https://서버 ip주소:포트 번호를 적어주시면 됩니다.
docker run --name nginx -d -p 443:443 -e TZ=Asia/Seoul -v nginx:/etc/nginx/conf.d/ -v /etc/letsencrypt:/etc/letsencrypt nginx
-p는 포트 번호 입니다.
-e TZ=Asia/Seoul는 컨테이너의 시간대를 한국으로 맞춥니다.
-v nginx:/etc/nginx/conf.d/ nginx설정 파일을 적용시키기 위해 아까 만들었던 볼륨과 컨테이너 내부의 설정파일 위치를 연결합니다.
-v /etc/letsencrypt:/etc/letsencrypt ssl 인증서 위치를 nginx에 적용시키기 위해 컨테이너 밖에 있는 ssl 인증서 위치와 컨테이너 내부 ssl 인증서가 있어야 될 위치를 연결합니다.
ssl 인증서는 3개월의 유효기간을 가지기 때문에 그전에 재발급이 필요합니다.
리눅스의 crontab을 활용해서 매월 재발급하도록 설정하겠습니다.
crontab -e
0 4 1 * * /bin/bash -l -c 'certbot renew --force-renew --cert-name 도메인 이름'
해당 명령어는 매월 1일 새벽 4시에 ssl 인증서를 재발급하는 명령어입니다.
--force-renew 옵션은 유효기간이 남은 인증서가 있더라도 강제로 재발급되도록 해줍니다.
기본적으로는 유효기간이 1달 이내일 때 재발급이 가능합니다.
https://jinsiri.tistory.com/605#recentComments
https://www.lesstif.com/system-admin/epel-yum-100205250.html