Nginx에 SSL 인증서를 적용한 내용을 공유합니다.
컨테이너 상의 Nginx에 인증서를 적용하다 보니 방법이 잘 이해가 가지 않아 생각해보다 헤매었네요 😲
Let’s Encrypt 유효성 검사를 완료하려면 Nginx가 필요하지만 인증서가 없으면 nginx가 시작되지 않습니다.
그래서 임시로 https를 사용하지 않는 척 nginx를 실행한 다음 인증서를 발급받고
https를 사용한 nginx에 인증서를 적용하면 됩니다.
준비물
- docker-compose
- 도메인 주소
💡 SSL이란?
https를 통한 인터넷 접속은 서버와의 암호화를 통신하고 있는 것을 의미합니다.
이때 사용하는 보안 프로토콜이 SSL(Secure Socket Layer)이며 보안이 향상된 통신을 할 수 있게 됩니다.
- http 뒤에 붙는 s가 secure!
- SSL과 TLS는 같은 의미의 단어(TLS가 후속 버전)
- http는 80번 포트, https는 443번 포트 사용
SSL을 위해 필요한 것이 SSL 인증서입니다.
👀 https를 적용하지 않고 SSL 인증서 발급받기
docker-compose.yml
nginx.conf 파일은 사용자 환경에 맞게 경로를 잡아주시면 됩니다.
./data 폴더는 수동으로 생성하지 않아도 됩니다.
version: '3'
services:
nginx:
image: nginx:latest
restart: unless-stopped
volumes:
- ./conf/nginx.conf:/etc/nginx/nginx.conf
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
ports:
- 80:80
- 443:443
certbot:
image: certbot/certbot
restart: unless-stopped
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
conf/nginx.conf
server {
listen 80;
listen [::]:80;
server_name domain; // 등록한 도메인으로 변경
location /.well-known/acme-challenge/ {
allow all;
root /var/www/certbot;
}
}
docker-compose를 실행합니다.
docker-compose -f docker-compose.yml up -d
docker ps // nginx와 certbot 컨테이너가 살아있는지 확인
인증서 발급받는 스크립트를 다운로드하고 도메인, 이메일 주소, 디렉터리를 변경합니다.
인증서 발급에 실패한 경우 실패 시 메시지나 docker log를 통해 원인을 찾을 수 있습니다.
curl -L <https://raw.githubusercontent.com/wmnnd/nginx-certbot/master/init-letsencrypt.sh> > init-letsencrypt.sh
chmod +x init-letsencrypt.sh
vi init-letsencrypt.sh // 도메인, 이메일, 디렉토리 수정
sudo ./init-letsencrypt.sh // 인증서 발급
👌 HTTPS 적용하기
이제 인증서를 발급받았으니 HTTPS를 적용할 수 있습니다.
nginx.conf 수정
server {
listen 80;
server_name example.org; # 도메인으로 변경
server_tokens off;
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
location / {
return 301 https://$host$request_uri;
}
}
server {
listen 443 ssl;
server_name example.org; # 도메인으로 변경
server_tokens off;
ssl_certificate /etc/letsencrypt/live/example.org/fullchain.pem; # example.org를 도메인으로 변경
ssl_certificate_key /etc/letsencrypt/live/example.org/privkey.pem; # example.or를 도메인으로 변경
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
location / {
proxy_pass <http://example.org>;
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;
}
}
인증서를 자동으로 갱신하도록 설정하지 않으면 만료될 때마다 다시 발급을 해주어야 합니다.
자동으로 인증서가 갱신되도록 docker-compose.yml 파일을 수정합니다.
version: '3'
services:
nginx:
image: nginx:1.15-alpine
restart: unless-stopped
volumes:
- ./data/nginx:/etc/nginx/conf.d
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
ports:
- "80:80"
- "443:443"
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \\"daemon off;\\"'"
certbot:
image: certbot/certbot
restart: unless-stopped
volumes:
- ./data/certbot/conf:/etc/letsencrypt
- ./data/certbot/www:/var/www/certbot
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
마무리
이제 HTTPS이 적용되었습니다!
이 글은 Nginx and Let’s Encrypt with Docker in Less Than 5 Minutes를 참고하여 작성되었으며 예제는 아래 깃헙에서 확인하실 수 있습니다. :)
'기타' 카테고리의 다른 글
[Github] Fork해온 저장소에 잔디 심는 방법(커밋해도 잔디가 안심어질때) (0) | 2022.12.07 |
---|---|
Sentry로 쉽고 안전하게 서비스 운영하기 (0) | 2022.01.23 |
[Macbook] 맥북 외장모니터 연결 문제 임시 해결(모니터 깜빡임) (2) | 2022.01.09 |
[Docker] Docker, Nginx, Node.js 환경에서 서비스 무중단 배포하기 (0) | 2021.12.19 |
[Docker] Docker 호스트에 원격으로 배포하기(docker compose 이용) (1) | 2021.12.18 |