Docker + Nginx에 Https 제대로 적용하기

HwangDo·2025년 1월 18일
0

DevOps

목록 보기
2/3

지난 편에서, Cloudflare https 프록싱이 정말 느리다는걸 알았다.
이번엔, 제대로 인증서를 발급받아 직접 적용해보자.


먼저 내 환경은 Docker + Nginx다. 도커 위에 여러 서비스가 있고, 이를 Nginx가 리버스 프록싱해준다.
그러니, Nginx단에다가 https를 적용하면 된다.
이를 위해 CloudFlare API와 Let's encrypt를 이용해보자.
혹시 인터넷에서 init_letsencrypt.sh 를 이용하는 방법을 봤다면, 그거는 서브도메인 (abc.domain.com)이 적용이 안 되니 이 방법을 써야한다.

도메인 사오세요

혹시 몰라 하는 말이지만, IP에는 HTTPS를 적용 할 수 없으니 도메인을 사오자.
HTTPS을 위한 SSL 인증서는 보통 유료거나, 제약있는 무료가 많은데
Let's encrypt는 무료고, 서브도메인도 무제한이다. 다만 3개월마다 갱신해야 하지만, 이정도면 감동적인 수준.

나야, Cloudflare


지난 시간에 Cloudflare를 신나게 욕했지만, 미워도 다시한번 이용해보자.
다만, 이번에는 프록싱을 이용하지 않을것이다.
CloudFlare의 API를 이용해 간편하게 HTTPS 인증서를 발급받자.

도메인 등록하기

먼저, Cloudflare에서 여러분의 도메인을 등록해주자.
타사 (가비아, 호스팅케이알, route53...)에 등록이 되어있더라도, cloudflare가 스캔해서 dns들을 옮겨주니 편하다.

계속을 눌러 진행하면, 어렵지 않게 등록이 완료된다. 네임서버 이전 잊지말자!

API Token 받기

https://dash.cloudflare.com/profile/api-tokens 링크로 이동해, API 토큰을 만들어야 한다.

[ 토큰 생성 ] -> [ 영역 DNS 편집 ]을 눌러주고, API 토큰을 발급받자.

발급받은 토큰은 다시 보여주지 않으니 잘 가지고 있자.

Token 저장하기

Docker-compose가 있는 디렉토리로 오자.
그 다음, cloudflare.ini 파일을 만들고 안에 다음과 같이 적어주자.

dns_cloudflare_api_token = <발급받은_API_TOKEN>

이후에 터미널에서 권한을 600으로 맞춰주자. 권한 높으면 실행시 오류가 발생한다! (보안 이슈)

chmod 600 cloudflare.ini

docker-compose 작성

  certbot:
    container_name: certbot
    image: certbot/dns-cloudflare:latest
    volumes:
      - ./certs:/etc/letsencrypt
      - ./letsencrypt-var:/var/lib/letsencrypt
      - ./cloudflare.ini:/etc/letsencrypt/cloudflare.ini:ro
    environment:
      - TZ=Asia/Seoul
    command: >
      certonly --dns-cloudflare --dns-cloudflare-credentials /etc/letsencrypt/cloudflare.ini
      --email <YOUR_EMAIL_HERE> --agree-tos --no-eff-email
      -d *.domain.com -d domain.com
      --preferred-challenges dns-01 --expand
      --dns-cloudflare-propagation-seconds 120

이제 docker-compose 파일에 certbot 컨테이너를 정의해주자.
하나하나 설명해보겠다.
1. certbot/dns-cloudflare

  • 우리가 cloudflare api를 통해 인증서를 발급받을거라, 그에 맞는 이미지다.

2 . volumes

  • ./certs 인증서가 저장될 디렉토리다. 직접 만들지 않아도 된다.
  • /letsencrypt-var let's encrypt 관련 변수들이 스쳐 지나갈 곳.. 직접 만들지 않아도 된다.
  • /cloudflare.ini 바로 위에서 만든 ini 파일 경로를 지정해주면 된다.

그리고 커맨드에
--preferred-challenges dns-01 라는 문구가 있다. dns챌린징인데, 특정 TXT 레코드를 추가하게 요구하는 방식이다. 이 dns 챌린징 방식을 써야 서브도메인도 일괄 인증받을 수 있다.

만약 도메인에 특정 경로 (./well-known/acme-challenge)에 파일을 업로드하는 방식이면 Webroot고, 서브도메인 인증 안된다. 각각 해야한다.

바꿀 점

commands에서는 딱 두 가지만 바꾸면 된다.
1. email
2. 도메인

<YOUR_EMAIL_HERE>에 당신의 이메일을 적고, -d *.domain.com -d domain.com에서 당신의 도메인을 적절히 넣어준다.
*.domain.com으로 하면 모든 서브 도메인이 등록된다.
그런데 당황스러운게 루트 도메인은 포함이 안된다. 그래서 뒤에 따로 domain.com으로 포함시켜준다.

실행

docker-compose up certbot으로 돌려보자.

docker 로그를 보면 120초를 기다린다. 2분동안 겸허하게 기다리자.

2분 뒤에 다음처럼 Success가 나왔다면, 성공했다!

갱신?

갱신은 command를 다음처럼 그냥 renew로 바꾸면 자동으로 이루어진다.
command: renew
이를 Crontab등 이용해 자동 갱신되게 하면 된다.

Nginx 설정

이제 Nginx conf를 수정하자.

http 블록에 인증서를 import해주자.

http {
    ssl_certificate /etc/letsencrypt/live/hwangdo.kr/fullchain.pem; 
    ssl_certificate_key /etc/letsencrypt/live/hwangdo.kr/privkey.pem; 
    ...

그 다음, server 블록에서 443 포트를 받아주자.

    server {
        listen 443 ssl;
        listen [::]:443 ssl;
        ...

마지막으로, nginx compose에서 443 포트를 열어주자.

이러면 설정이 완료되었다 :)

적용 확인

https://www.ssllabs.com/ssltest/로 이동해서, 도메인을 넣고 테스트해보자.

A등급을 받을 수 있다!

해치웠나?

CloudFlare 프록시 기능으로 HTTPS 기능 사용할 때

426ms이 걸렸다. 25kb짜리 이미지인데, 절망적인 수치다.
그렇다면 직접 적용한 뒤엔?

14ms. 3042%가 빠르다..!!!

클라우드 플레어의 프록시는 나중에 돈 많이 벌면 유료로 쓰자. (돈내면 서울리전 서버로 연결해준다..)

0개의 댓글