docker + Nginx Reverse-proxy + Wildcard SSL
2021. 6. 20. 00:02ㆍ개발노트
Wildcard SSL이란?
- 도메인 뿐만이 아니라 서브 도메인 모두 인증지원하는 인증서
예를 들어 도메인이 devgno.me 일 때 이 인증서를 발급, 적용하면
site1.devgno.me, site2.devgno.me ....
모든 서브 도메인도 ssl인증이 적용된다.
도메인 준비
ssl인증서 발급을 위해 도메인을 구한다.
이 글에서는 무료 도메인인 freenom을 사용
인증서 발급
- certbot 설치
sudo apt install certbot
- Wildcard ssl 발급
sudo certbot certonly --manual --preferred-challenges=dns --email \ jinho021712@gmail.com --server https://acme-v02.api.letsencrypt.org/directory --agree-tos -d devgno.me -d \*.devgno.me - 발급 받을 서버에 위 명령어를 입력한다. 이메일과 도메인 입력에 주의
- IP주소 수집, 로그로 기록됨을 동의
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for hiseon.me
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NOTE: The IP of this machine will be publicly logged as having requested this
certificate. If you're running certbot in manual mode on a machine that is not
your server, please ensure you're okay with that.
Are you OK with your IP being logged?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
- 도메인 인증
인증이 된 후 엔터를 치고 넘어가야한다.
도메인 인증을 위해 위 값을 freenom DNS Management에서 아래와 같이 등록 - 인증 확인
watch dig -t txt \_acme-challenge.devgno.me +short
도메인 인증에 시간이 걸릴 수 있으므로 위 명령어로 도메인 인증되었는지 모니터링
docker-compose.yml
version: '3'
services:
reverse-proxy:
image: nginx:1.17.10
container_name: reverse_proxy_demo
depends_on:
- ex-page1
- ex-page2
volumes:
- ./reverse_proxy/conf.d:/etc/nginx/conf.d
- ./reverse_proxy/nginx.conf:/etc/nginx/nginx.conf
- /etc/letsencrypt:/etc/letsencrypt
- /etc/ssl/certs/dhparam.pem:/etc/ssl/certs/dhparam.pem
ports:
- 80:80
- 443:443
ex-page1:
image: ex-page1
container_name: ex-page1
build:
context: ./ex-page1
ports:
- 5001:5001
restart: on-failure
ex-page2:
image: ex-page2
container_name: ex-page2
build:
context: ./ex-page2
ports:
- 5001:5002
restart: on-failure
기존에 docker-compose를 사용하고 있었다면 port에 443포트만 매핑시켜주고
ssh인증서 폴더 "/etc/letsencrypt"를 volumes에 매핑한다. (개별 파일을 매핑하면 링크파일로 매핑 될 수 있다. 폴더를 매핑시켜주자)
nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log warn;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
server_names_hash_bucket_size 64;
server_names_hash_max_size 8192;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
server_tokens off; # 응답 헤더에서 서버 버전 숨기기
keepalive_timeout 65;
include /etc/nginx/conf.d/*.conf;
}
conf.d 폴더의 conf확장자 파일을 모두 include하도록 한다.
Nginx conf 작성 참고
[
NGINX Docs | Creating NGINX Plus and NGINX Configuration Files
Understand the basic elements in an NGINX or NGINX Plus configuration file, including directives and contexts.
docs.nginx.com
](https://docs.nginx.com/nginx/admin-guide/basic-functionality/managing-configuration-files/)
conf.d > default.conf
conf.d폴더 안에 페이지별 conf 파일을 작성한다.
return을 줘서 http로 연결하면 https로 연결을 유도한다.
https를 사용하기 위해 인증서 위치를 적어준다.
# ex-page1
server {
listen 80;
server_name ex-page1.devgno.ga www.ex-page1.devgno.ga;
charset utf-8;
# https로 연결
location / {
return 307 https://ex-page1.devgno.ga$request_uri;
}
}
server {
listen 443;
listen [::]:443;
ssl on;
server_name ex-page1.devgno.ga www.ex-page1.devgno.ga;
# ssl인증서 위치
ssl_certificate /etc/letsencrypt/live/devgno.ga/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/devgno.ga/privkey.pem;
ssl_dhparam /etc/ssl/certs/dhparam.pem;
location / {
# include proxy_params;
proxy_pass http://172.17.0.1:5001;
}
}