HTTPS 지원 서비스 만들기

SummerToday·2024년 5월 9일

도커, 서버 기술

목록 보기
31/34
post-thumbnail

HTTPS

HTTPS를 지원하기 위해서는 인증서 발급이 필요하며, 보통 연단위 비용이 청구된다. 하지만 Let's Encrypt와 cerbot 서비스 이용 시 연단위 비용 없이 인증서를 발급 받을 수 있다. 대신 일정 기간(90일)마다 갱신이 필요하다.


Let's Encrypt와 cerbot

  • Let's Encrypt
    Let's Encrypt는 인터넷 보안 연구 그룹인 ISRG(Internet Security Research Group)에서 운영하는 인증 기관(CA)이다. 해당 서비스는 웹사이트 소유자에게 무료 SSL/TLS 인증서를 제공하여 HTTPS 통신을 사용할 수 있도록 해준다.

  • Certbot
    Electronic Frontier Foundation(EFF)에서 개발한 오픈 소스 소프트웨어이다. Certbot을 사용하면 Let's Encrypt의 인증서 발급 및 갱신을 자동화할 수 있다.


Let's Encrypt SSL 인증서 발급

cerbot 프로그램을 제공해주며, 해당 프로그램에 다음 옵션을 넣어 인증서를 발급 받을 수 있다.

cerbot certonly --cert-name cert --standalone -d
domain.com,www.domain.com


HTTPS 테스트를 위한 사전 준비

  1. 도메인 구입 및 DNS 레코드 설정

    • 가비아에서 도메인 구입 후, 가비아에서 DNS 레코드 설정을 하여 자신의 EC2 고정 IP를 도메인에 연결시켜 준다.


  2. AWS EC2 서버 구축 및 고정 IP(탄력적 IP) 연결

  1. 도메인 DNS 설정

certbot과 nginx 기본 설정

certonly 옵션

certbot certonly --dry-run --webroot --webroot-path=/usr/share/nginx/html
--email [이메일] --agree-tos --no-eff-email --keep-untill-expiring -d [도메인 주소1 ex. inkyung.site] -d [도메인 주소2 ex. www.inkyung.site]

  • certbot certonly
    certonly는 certbot 프로그램의 플러그인으로 인증서를 받는 서브 명령이다.

  • --dry-run
    테스트 시 해당 옵션을 사용하여 테스트 해준다. 해당 옵션 없이 반복적으로 테스트를 진행하면, 에러가 발생한다.

    cf. Let's Encrypt도 양산용 서버와 테스트 서버가 있다고 생각하면 된다. 따라서 테스트를 할 때에는 위 명령어를 사용해 테스트 서버에 인증서 발급 요청을 하는 것이 좋다. 위 명령어 없이 테스트 시 실제 양산 서버에 인증서를 수 없이 요청하게 되어 나중에는 요청 수가 초과되었다는 오류가 발생하게 된다.

  • --webroot
    자신이 발급받은 도메인과 연결된 웹 서버에 접속하여 정상적으로 동작하는지 확인 후, 인증서를 발급 받도록 하는 옵션이다.
    다른 유사 옵션들과 달리 --webroot 옵션을 사용하면 인증서를 발급받을 동안에도 서버가 중단되지 않아 해당 옵션을 사용한다.

  • --webroot-path
    해당 옵션을 사용하여 웹 서버의 루트 디렉토리를 지정하면, 인증서 발급 과정 중 해당 디렉토리에 임시 파일을 생성하여 Let's Encrypt가 도메인 소유 여부를 확인할 수 있다. (보통은 각 웹 서버에서 지정해놓은 루트 폴더로 설정한다.)

  • --email
    인증서 복구 등을 위한 이메일을 등록하는 옵션이다.

  • --agree-tos
    Let's Encrypt 인증서를 요청할 때 이용 약관에 동의하는 것을 자동화하는 옵션이다. Let's Encrypt는 SSL/TLS 인증서를 무료로 제공하며, 이용 약관에 동의해야 인증서를 발급받을 수 있다. 보통은 수동으로 약관에 동의를 해야하지만, 해당 옵션 사용시 약관 동의를 자동화 할 수 있다.

  • --no-eff-email
    일반적으로 Let's Encrypt의 이용 약관에 따라 SSL/TLS 인증서를 발급받을 때, 이메일 주소를 제공해야 한다. 하지만 해당 옵션을 사용하면 이메일 주소를 제공하지 않고 인증서를 요청할 수 있다.
    그러나 주의해야 할 점은 이메일 통보를 받지 못하면 인증서의 만료나 기타 중요한 사항을 알지 못할 수 있으므로, 주기적으로 SSL/TLS 인증서를 관리하고 갱신해야 한다.

  • --keep-until-expiring
    아직 인증서의 재발급이 필요하지 않으면, 갱신하지 않고 기존 인증서를 보존하는 옵션이다. 인증서의 기본 유효기간은 90일이다.

  • -d
    인증서를 발급받을 도메인 이름을 지정하는 옵션이다. 해당 옵션을 사용하여 하나 이상의 도메인 이름을 지정하면, 해당 도메인에 대한 SSL/TLS 인증서를 발급받을 수 있다. 위와 같이 2개의 도메인 주소를 사용하는 것이 일반적이다.


docker-compose.yml 설정

version: "3"

services:
  webserver:
    image: nginx:latest
    container_name: proxy
    restart: always
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./myweb:/usr/share/nginx/html
      - ./nginx/nginx.conf:/etc/nginx/nginx.conf
      - ./certbot-etc:/etc/letsencrypt

  nginx:
    image: nginx:latest
    container_name: myweb
    restart: always
    volumes:
      - ./myweb:/usr/share/nginx/html

  certbot:
    depends_on:
       - webserver
    image: certbot/certbot
    container_name: certbot
    volumes:
       - ./certbot-etc:/etc/letsencrypt
       - ./myweb:/usr/share/nginx/html
    command: certonly --dry-run --webroot --webroot-path=/usr/share/nginx/html --email kom347@naver.com --agree-tos --no-eff-email --keep-until-expiring -d inkyung.site -d www.inkyung.site
  • --webroot 옵션을 사용했기 때문에 webserver 컨테이너가 선행되어야지만 정상적으로 실행되기 때문에 depends on 옵션을 사용해준다.

  • HTTPS 통신을 위해서는 443번 포트를 열어주어야 한다.

    EC2 서버에서도 443번 포트를 열어주는 인바운드 규칙을 추가해줘야 한다.

  • ./myweb:/usr/share/nginx/html
    --webroot --webroot-path=/usr/share/nginx/html 옵션으로 인해 인증서 발급 과정 중 해당 디렉토리에 Let's Encrypt가 도메인 소유 여부를 확인할 수 있는 임시 파일을 생성하게 된다.

    그리고 -webroot 옵션으로 인해, 도메인과 연결된 서버(webserver 컨테이너)에 접속하여 이 임시파일을 확인하고 정상적으로 Let's Encrypt가 도메인 소유 여부를 확인하면 인증서를 ./certbot-etc:/etc/letsencrypt 경로로 발급하게 된다.

    따라서 webserver 컨테이너의 볼륨 옵션으로 ./myweb:/usr/share/nginx/html를 설정해주는 것이다.

  • ./certbot-etc:/etc/letsencrypt
    webserver 컨테이너(프록시 서버)가 HTTPS를 지원하게 되고, 인증서를 체크하게 되는데 해당 인증서는 ./certbot-etc:/etc/letsencrypt 경로에 저장이 되어있다. 따라서 해당 프록시 서버에서 인증서를 확인할 수 있도록 볼륨 옵션으로 ./certbot-etc:/etc/letsencrypt를 설정해주는 것이다.

    cf. 외부에서 프록시 서버로 진입할 때만 HTTPS 통신을 하고 내부 서버들 간의 통신은 HTTP 통신을 할 것이기에 nginx 컨테이너의 볼륨 옵션에는 ./certbot-etc:/etc/letsencrypt 설정을 할 필요가 없다.


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;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" "$request_uri" "$uri"'
                      '"$http_user_agent" "$http_x_forwarded_for"';
    access_log  /var/log/nginx/access.log  main;
    sendfile on;
    keepalive_timeout 65;

    upstream docker-web {
        server nginx:80;
    }

    server {
        location ~ /.well-known/acme-challenge {
                allow all;
                root /usr/share/nginx/html;
                try_files $uri =404;
        }

        location / {
                allow all;
                root /usr/share/nginx/html;
                try_files $uri =404;
        }
    }
}
  • /.well-known/acme-challenge 파일을 요청시 /usr/share/nginx/html 폴더에서 찾아 응답한다.

테스트 하기

docker-compose up -d

위 명령어를 사용해 컨테이너들을 생성해주고 아래 명령어를 통해 인증서가 성공적으로 발급되었는지를 확인한다.

docker logs certbot

  • certbot 컨테이너의 로그를 확인하는 명령어이다.

  • 해당 명령어를 입력후 아래 내용이 뜨면 성공적으로 인증서가 발급되었다는 것이다.




해당 글은 다음 강의의 내용을 참고한 글임을 밝힙니다. 자세한 내용은 다음 강의에서 확인해볼 수 있습니다.
인프런, 잔재미 코딩, ⌜풀스택을 위한 도커와 최신 서버 기술(리눅스, nginx, AWS, HTTPS, flask 배포) [풀스택 Part3]⌟
profile
블로그 이관했습니다.

0개의 댓글