한번 해두면 잊지않을 ssl 적용기

Gomi·2022년 7월 27일
0

📋 문제상황



  개인 프로젝트는 재껴두고 새로 참여한 팀 프로젝트인 래빗홀이 최종 배포단계에 돌입했다. 현재 도메인 구매 후 AWS Route53과 로드벨런서에 도메인 등록과 https를 위한 세팅을 완료해놓은 상태이다. 도커 이미지를 통해 간편하게(?) 무료 ssl인증서를 발급받고 https로 무장한 도메인을 제공하려했으나.....

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    upstream docker-server {
        server server:4000;
    }
    
    server {
        listen 80;
        listen [::]:80;
        server_name 도메인;
        location /.well-known/acme-challenge/ {
            allow all;
            root /var/www/certbot;
        } 
        location / {
            return 301 https://$host$request_uri;
        }
    }

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

        # ssl 설정

        ssl_protocols TLSv1.1 TLSv1.2;
        ssl_certificate /etc/letsencrypt/live/도메인/fullchain.pem;
        ssl_certificate_key /etc/letsencrypt/live/도메인/privkey.pem;
        ssl_prefer_server_ciphers on;
        ssl_session_timeout 1d;
        ssl_session_cache shared:SSL:50m;
        ssl_stapling on;
        ssl_stapling_verify on;
        add_header Strict-Transport-Security max-age=15768000;

        server_name localhost;
 
        location / {
            root /usr/share/nginx/html;
            index index.html index.htm;
            try_files $uri $uri/ /index.html =404;
        }

처음부터 nginx상에 ssl 설정을 해놓고 certbot 이미지를 컨테이너에 올리면 ssl인증서가 없는 클라이언트 프로그램이 다음 코드때문에

ssl_certificate /etc/letsencrypt/live/도메인/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/도메인/privkey.pem;

돌아가지 않기 때문에 certbot의 인증을 받는게 불가능하다.
그래서 내가 시도한 방법은 다음과 같다.

💊솔루션: 인증용 클라이언트 이미지 빌드



현재 도커 컴포즈 파일은 다음과 같이 짜여있다. 서버 폴더에 있고 클라이언트 이미지는 빌드 후 도커허브에 푸쉬해 운영한다.
version: '3'
services:
  server:
    build: ./
    env_file:
      - ./.env
    expose:
      - '4000'
    restart: "unless-stopped"
  client:
    image: 클라이언트 이미지
    ports:
     - '80:80'
     - '443:443'
    restart: 'unless-stopped'
    volumes:
      - ./www:/var/www/html
  certbot:
    depends_on:
      - client
    image: certbot/certbot
    container_name: certbot
    volumes:
      - ./certbot/etc:/etc/
      - ./certbot/var:/var/lib/
      - ./www:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email gomi.dev1755@gmail.com --agree-tos --no-eff-email --force-renewal -d 도메인

이상태에서 클라이언트 이미지를 두 가지 빌드한다.
하나는 위 처럼 nginx에 ssl설정이 되어있는 오리지널 클라이언트 이미지. 나머지는 ssl 설정을 제거한 http전용 이미지이다.


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    upstream docker-server {
        server server:4000;
    }
    
    server {
        listen 80;
        listen [::]:80;
        server_name rabbit-hole.kr;
        location /.well-known/acme-challenge/ {
            allow all;
            root /var/www/certbot;
        } 
    #     location / {
    #         return 301 https://$host$request_uri;
    #     }
    # }

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

    #     # ssl 설정

    #     ssl_protocols TLSv1.1 TLSv1.2;
    #     ssl_certificate /etc/letsencrypt/live/rabbit-hole.kr/fullchain.pem;
    #     ssl_certificate_key /etc/letsencrypt/live/rabbit-hole.kr/privkey.pem;
    #     ssl_prefer_server_ciphers on;
    #     ssl_session_timeout 1d;
    #     ssl_session_cache shared:SSL:50m;
    #     ssl_stapling on;
    #     ssl_stapling_verify on;
    #     add_header Strict-Transport-Security max-age=15768000;

    #     server_name localhost;
 
        location / {
            root /usr/share/nginx/html;
            index index.html index.htm;
            try_files $uri $uri/ /index.html =404;
        }

ssl설정을 주석처리한 이미지를 [이미지이름-cert]라는 이름의 이미지로 빌드 후 푸쉬한다.

version: '3'
services:
  server:
    build: ./
    env_file:
      - ./.env
    expose:
      - '4000'
    restart: "unless-stopped"
  client:
    image: 클라이언트 이미지-cert
    ports:
     - '80:80'
     - '443:443'
    restart: 'unless-stopped'
    volumes:
      - ./www:/var/www/html
  certbot:
    depends_on:
      - client
    image: certbot/certbot
    container_name: certbot
    volumes:
      - ./certbot/etc:/etc/
      - ./certbot/var:/var/lib/
      - ./www:/var/www/html
    command: certonly --webroot --webroot-path=/var/www/html --email gomi.dev1755@gmail.com --agree-tos --no-eff-email --force-renewal -d 도메인

클라이언트-cert 이미지를 certbot과 함께 실행하면

키가 정상 발급된다.
이제 클라이언트 이미지를 오리지널 ssl 이미지로 바꿔서 빌드해보자.

version: '3'
services:
  server:
    build: ./
    env_file:
      - ./.env
    expose:
      - '4000'
    restart: "unless-stopped"
  client:
    # image: 클라이언트 이미지-cert (인증용)
    image: 클라이언트 이미지
    ports:
     - '80:80'
     - '443:443'
    restart: always
    volumes:
    - ./certbot/etc:/etc/letsencrypt
    - ./certbot/var:/var/lib/letsencrypt
    - ./www:/var/www/certbot

  # certbot:(인증용)
  #   depends_on:
  #     - client
  #   image: certbot/certbot:latest
  #   container_name: certbot
  #   volumes:
  #     - ./certbot/etc:/etc/letsencrypt
  #     - ./certbot/var:/var/lib/letsencrypt
  #     - ./www:/var/www/certbot
  #   command: certonly --webroot --webroot-path=/var/www/certbot --email gomi.dev1755@gmail.com --a$




잘 동작하기에 앞으로 이런 세팅을 먼저 한 뒤 개발을 시작하는 플로우도 적용해보면 좋을 것 같다.
profile
터키어 배운 롤 덕후

0개의 댓글