LBS V2 Nginx reverse proxy server setting 및 Let's Encrypt 를 사용한 SSL 인증서 발급
파일 설정 중 [{}] 형식으로 표시된 부분이 있다면 자신의 설정 환경에 맞게 바꿔 주어야 하는 부분입니다.
docker 를 사용하여 nginx, certbot 을 실행시키기 위한 스크립트 코드가 들어있습니다.
nginx 와 certbot container 의 /etc/letsencrypt, /var/www/certbot directory 를 ./certbot/conf
./certbot/data 로 동일한 설정을 가질 수 있도록 볼륨 마운팅 설정을 진행합니다.
# nginx volume mounting
- ./certbot/conf:/etc/letsencrypt
- ./certbot/data:/var/www/certbot
# certbot volume mounting
- ./certbot/conf:/etc/letsencrypt
- ./certbot/data:/var/www/certbot
services.nginx.command nginx에서 6시간마다 설정을 다시 로드하도록 command 를 설정합니다.
services.certbot.entrypoint 에서 12시간마다 갱신 여부를 판별하게 하는 동작을 설정합니다.
# nginx command
command : "/bin/sh -c 'while :; do sleep 6h & wait $${!p}; nginx -s reload; done & nginx -g \"daemon off;\"'"
# certbot entrypoint
entrypoint : "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
conf.d/default.conf 파일에서는 다음 설정을 진행합니다.
- ssl 인증서 발급을 위한 certbot webroot 설정
- http -> https redirect 설정
- 발급 받은 ssl 인증서를 사용한 ssl 인증 프로토콜 설정
- ssl host index 요청 시 내부 was 로의 proxy_pass 설정
server {
listen [::]:80;
listen 80;
# nginx connection host configuration
server_name domain.com www.domain.com;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/certbot;
}
}
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
server {
listen [::]:80;
listen 80;
# nginx connection host configuration
server_name domain.com www.domain.com;
location ~ /.well-known/acme-challenge {
allow all;
root /var/www/certbot;
}
# http to https redirect config. Comment processing during initial setting.
location / {
return 301 https://$host$request_uri;
}
}
아래 설정 부분에서
- listen 443 ssl;
- ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
- ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
이 세줄은 certbot ssl 인증서 발급 전 nginx 실행 시 주석 처리가 필요한 부분입니다.
아래 실행 파트에서 좀 더 자세히 설명하겠습니다.
server {
listen 443 ssl;
# The location of the ssl pem key issued by certbot.
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
server_name domain.com www.domain.com;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 20m;
# Specifies the SSL-TLS version to use.
ssl_protocols TLSv1.2 TLSv1.3;
# Specifies the encryption algorithm to use in the SSL authentication method.
# Apply general-purpose algorithms.
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-DSS-AES128-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA:AES256-SHA:AES:CAMELLIA:!DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!DHE-RSA-AES128-GCM-SHA256:!DHE-RSA-AES256-GCM-SHA384:!DHE-RSA-AES128-SHA256:!DHE-RSA-AES256-SHA:!DHE-RSA-AES128-SHA:!DHE-RSA-AES256-SHA256:!DHE-RSA-CAMELLIA128-SHA:!DHE-RSA-CAMELLIA256-SHA:!DHE-RSA-3DES";
# In the SSL-TLS negotiation process, the encryption algorithm set on the server takes precedence, and if it is off, the algorithm can be weakened and attacked.
ssl_prefer_server_ciphers on;
}
# aws 사용 시 private ip 주소와 port 정보를 사용하여도 무방합니다.
upstream was {
ip_hash;
server ip:port;
}
# Setting up registration of ssl authentication key generated by certbot.
# Comment processing during initial setting.
server {
listen 443 ssl;
# The location of the ssl pem key issued by certbot.
ssl_certificate /etc/letsencrypt/live/domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/domain.com/privkey.pem;
server_name domain.com www.domain.com;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 20m;
# Specifies the SSL-TLS version to use.
ssl_protocols TLSv1.2 TLSv1.3;
# Specifies the encryption algorithm to use in the SSL authentication method.
# Apply general-purpose algorithms.
ssl_ciphers "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-DSS-AES128-SHA256:DHE-DSS-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA:AES256-SHA:AES:CAMELLIA:!DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA:!DHE-RSA-AES128-GCM-SHA256:!DHE-RSA-AES256-GCM-SHA384:!DHE-RSA-AES128-SHA256:!DHE-RSA-AES256-SHA:!DHE-RSA-AES128-SHA:!DHE-RSA-AES256-SHA256:!DHE-RSA-CAMELLIA128-SHA:!DHE-RSA-CAMELLIA256-SHA:!DHE-RSA-3DES";
# In the SSL-TLS negotiation process, the encryption algorithm set on the server takes precedence, and if it is off, the algorithm can be weakened and attacked.
ssl_prefer_server_ciphers on;
# proxy pass setting.
# redirect to spring application server
location / {
#proxy_redirect off;
proxy_buffering off;
#proxy_pass_header Server;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Because docker is used, do not set proxy pass with localhost, but set proxy pass using private IP of ec2 instance
proxy_pass http://was;
# proxy http protocol version. 1.1 Recommended
proxy_http_version 1.1;
}
}
Certbot 을 사용하여 인증서 발급 절차를 자동화 처리를 하기 위한 파일입니다.
해당 파일에 실행 권한을 부여한 뒤 실행시키면 내부 스크립트에 따라 ssl 인증에 필요한 설정 파일을 다운로드 받은 뒤 docker nginx 를 실행하여 ssl 인증키를 발급 받습니다.
해당 부분에 대한 자세한 설명은 실행 파트에서 추가로 설명하겠습니다.
해당 파일에서 유의해야할 부분은 다음과 같습니다.
domains="domain.com"
rsa_key_size=4096
data_path="./certbot"
email="my-email@email.com" # Adding a valid address is strongly recommended
staging=0 # Set to 1 if you're testing your setup to avoid hitting request limits
init-letsencrypt.sh 파일의 위 코드 블록 부분을 자신의 도메인, email 에 맞게 재 설정해야 합니다.
data_pass 부분은 볼륨 마운트 설정에 맞게, certbot 인증서에 대한 볼륨 마운트 디렉토리 패스를 잡으면 됩니다.
본 설정에서는 init-letsencrypt.sh 파일이 위치하는 root 디렉토리에 certbot 디렉토리가 생성되므로, 추가적인 변경 사항은 없습니다.
해당 git 소스코드를 clone 하여 바로 nginx 를 실행시키면 ssl_certificate_key 를 찾을 수 없다는 에러 메세지와 함께 nginx 가 실행되지 않습니다.
default.conf 파일에는 이미 ssl 인증서를 발급 받았다는 가정하에 ssl 인증서를 사용한 https 요청 처리까지 미리 완료되어 있기 때문입니다.
이를 해결하기 위해서는 default.conf 파일에서 다음 코드 블록에 대한 부분을 주석 처리해준 뒤 init-letsencrypt.sh 파일을 실행해야 합니다.
listen 443 ssl;
# The location of the ssl pem key issued by certbot.
ssl_certificate /etc/letsencrypt/live/dev-admin-lbs.indoorplus.io/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dev-admin-lbs.indoorplus.io/privkey.pem;
--->
# listen 443 ssl;
# The location of the ssl pem key issued by certbot.
# ssl_certificate /etc/letsencrypt/live/dev-admin-lbs.indoorplus.io/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/dev-admin-lbs.indoorplus.io/privkey.pem;
init-letsencrypt.sh 파일을 실행합니다.
chmod +x init-letsencrypt.sh
sudo ./init-letsencrypt.sh
실행 권한 부여 명령은 한 번만 진행합니다.
init-letsencrypt.sh 를 실행시키면 ssl 인증서 발급에 필요한 conf 파일을 다운로드 받은 뒤 docker nginx 를 실행하여 webroot 를 띄우고 ssl 인증 키 발급을 진행합니다.
실행 중 yes, no 선택 시 y 옵션으로 진행하면 됩니다.
인증서가 발급되었다면, 아까 주석 처리했던 default.conf 파일의 주석을 해제합니다.
# listen 443 ssl;
# The location of the ssl pem key issued by certbot.
# ssl_certificate /etc/letsencrypt/live/dev-admin-lbs.indoorplus.io/fullchain.pem;
# ssl_certificate_key /etc/letsencrypt/live/dev-admin-lbs.indoorplus.io/privkey.pem;
--->
listen 443 ssl;
# The location of the ssl pem key issued by certbot.
ssl_certificate /etc/letsencrypt/live/dev-admin-lbs.indoorplus.io/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/dev-admin-lbs.indoorplus.io/privkey.pem;
주석을 해제했다면, 실행되고 있는 nginx 를 종료합니다.
docker-compose down
마지막으로 다음 명령어를 사용하여 nginx, certbot 을 재 실행합니다.
docker-compose up -d
고생하셨습니다.
저도 nginx reverse proxy 설정 및 ssl 인증서 발급을 처음한 것이기 때문에 중간 중간 틀리거나 설명이 누락된 부분이 있을 수 있습니다.
추후 인수인계 받으시는 개발자 분께 해당 문서에 대한 현행화를 부탁 드리며 마무리 하겠습니다.
감사합니다.