현재 웹서버 Nginx는 http 서버로서의 역할을 하고 있기 때문에 HTTP(기본 포트번호 80)로 들어오는 요청을 HTTPS(기본 포트번호 443)로 리다이렉션 하는 작업을 해줘야한다.
즉, Nginx에서 Certbot을 통해 SSL을 발급받아 Https적용해야한다.
Let's Encrypt와 Certbot이란?
- Let's Encrypt는 무료 SSL인증서를 발급해주는 곳이고, Certbot는 Let's Encrypt 인증서를 자동으로 발급 및 갱신을 해주는 프로그램이다.
- Certbot을 이용해 인증서를 받기위해선 서비스를 운용하는 서버 & 서비스할 도메인 주소 가 필수적으로 필요하다.
- Certbot으로 받은 인증서(Encrypt)는 3개월 유효기간이 있으므로 주기에 맞추어 갱신이 필요하다.
Docker-compose로 flask+gunicorn+react+nginx 모든 서비스를 한번에 올리는 상황이었기 때문에 기존에 구성했던 docker-compose.prod.yml파일과 nginx.conf를 수정해야한다.
진행해야할 작업 순서
Cloud network 방화벽 설정 (443포트 열기) => docker-compose 파일 수정 => nginx.conf파일 수정 => ssl 인증서 발급 => 자동 인증서 갱신
1. docker-compose파일 수정
- nginx 서비스에 443 포트 추가
- certbot 컨테이너 추가
- certbot 컨테이너에서 인증서를 발급받아 로컬 서버에 마운트 된 디렉토리에 저장하고, nginx 컨테이너는 동일한 디렉토리를 마운트해 동일한 인증서 파일을 공유받을수 있도록 volume설정 추가
nginx:
build: ./nginx
container_name: nginx
ports:
- "80:80"
- "443:443" # nginx에 443 포트 추가
restart: "on-failure"
volumes:
# - ./nginx/nginx.conf:/etc/nginx/conf.d
- build_folder:/var/www/Frontend
- ./certbot/conf:/etc/letsencrypt #동일한 디렉토리를 마운트
- ./certbot/www:/var/www/certbot
command : "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'"
depends_on:
- flask-app
- react-app
certbot: #certbot 컨테이너 추가
image: certbot/certbot
restart: unless-stopped
container_name: certbot
volumes:
- ./certbot/conf:/etc/letsencrypt #nginx컨테이너에 certbot컨테이너 연결
- ./certbot/www:/var/www/certbot
depends_on:
- nginx
entrypoint : "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'"
2. nginx.conf파일 수정
- https를 위한 서버를 하나더 생성하여 ssl내용으로 수정
- 기존 nginx.conf에서 80포트를 listen하던 서버 설정을 새로만든 서버 블록으로 옮김 (react와 flask 관련 설정을 443포트 서버에서 처리)
- 80포트에선 들어오는 모든 요청을 443포트로 리다이렉트 시킴
upstream api { server flask-app:5000; } #http server { listen 80; server_name weirdmuseum.ml; #우리 도메인 이름으로 설정 server_tokens off; # Allow only for register SSL (Certbot) location /.well-known/acme-challenge/ { allow all; root /var/www/certbot; } # Http로 들어온 요청을 Https로 Redirect location / { return 301 https://$host$request_uri; } } #https server { listen 443 ssl; server_name weirdmuseum.ml; server_tokens off; ssl_certificate /etc/letsencrypt/live/weirdmuseum.ml/fullchain.pem; # ssl 인증서 사용 ssl_certificate_key /etc/letsencrypt/live/weirdmuseum.ml/privkey.pem; include /etc/letsencrypt/options-ssl-nginx.conf; ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; location / { root /var/www/Frontend; index index.html index.htm; try_files $uri $uri/ /index.html?q=$uri&$args; } location /api/ { proxy_pass http://api; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header Host $http_host; proxy_redirect off; add_header 'Access-Control-Allow-Origin' *; } }
3. SSL인증서 발급
- 이상태 에서 docker-compose up을 하면 실행되지 않는다.
- 문제 : 현재 설정에서 nginx서버를 올리기 위해선 SSL인증서가 필요한데, SSL인증서를 발급받기위해는 nginx서버가 올라가있어야 되는 모순인 상황이다.
- 해결방법 : 더미증명서를 발급 => nginx서버 시작 => 더미증명서 삭제 및 실제 증명서 요청
- 이 방법을 자동화시킨 스크립트 파일을 이용하면 된다. 적용시, domain , data_path, email을 우리것으로 바꾸면된다.
- 해당 스크립트 파일에 실행가능한 권한을 부여후 실행하면 위의 과정을 통해 인증서 발급이 되며 docker-compose의 정의해놓은 서비스들이 컨테이너에 띄워진다.
4. 자동 인증서 갱신
- 아까 말했듯이, Let's Encrypt에서 발급받은 인증서는 30일후에 만료되기 때문에 자동 인증서 갱신이 필요하다.
- 아래의 코드를 docker-compose파일에 추가해주면 끝
entrypoint: "/bin/sh -c 'trap exit TERM; while :; do certbot renew; sleep 12h & wait $${!}; done;'" # certbot에서 12시간마다 갱신여부 판별
command: "/bin/sh -c 'while :; do sleep 6h & wait $${!}; nginx -s reload; done & nginx -g \"daemon off;\"'" # nginx에서 6시간마다 설정을 다시 로드
여기까지 하면 Nginx + Certbot를 이용해 HTTPS 프로토콜 적용이 가능하다.
'Develop > Docker' 카테고리의 다른 글
Docker(도커)란 무엇인가? (0) | 2021.08.29 |
---|
댓글