Nginx에 무료 인증서 등록 및 자동갱신

인한별
인한별
조회 수554

기존에는 Cloudflare 프록시 서버를 통해 보안과 SSL 인증서 기능을 편리하게 관리해 왔습니다.

하지만 국내 망 사용료 이슈로 인해, 한국 서버임에도 불구하고 트래픽이 해외 데이터 센터를 경유하게 되면서 속도가 현저히 느려지는 문제가 발생했습니다.

이를 해결하고 국내 사용자에게 최적의 속도를 제공하기 위해, Cloudflare 프록시를 거치지 않고 Nginx에 직접 무료 SSL 인증서를 등록하여 사용하는 방식을 설명합니다.


이 본문은 Let's Encrypt, Certbot을 사용하여 무료 인증서를 적용합니다.


Let's Encrypt란?

무료로 SSL/TLS 인증서를 발급해 주는 비영리 CA(인증 기관)입니다.


과거에는 웹사이트에 HTTPS를 적용하려면 연간 수십만 원의 비용을 지불하고 복잡한 서류 절차를 거쳐 인증서를 구매해야 했습니다.

Let's Encrypt는 이를 해결하기 위해 등장했습니다.


  1. 비용 0원: 모든 인증서 발급이 무료입니다.
  2. 자동화: 사람이 개입하지 않고 프로그래밍 방식으로 인증서를 발급/갱신할 수 있습니다.
  3. 투명성: 모든 인증서 발급 기록이 공개됩니다.
  4. 유효 기간: 보안 강화를 위해 인증서 유효 기간이 90일로 짧습니다. (따라서 자동 갱신 설정이 필수입니다.)



Certbot이란?

Let's Encrypt 인증서를 자동으로 발급받고 관리해 주는 오픈소스 소프트웨어 도구입니다.


Let's Encrypt는 API 형태로 운영되기 때문에, 사용자가 서버에서 직접 명령어를 입력해 인증서를 가져와야 합니다.

이때 가장 널리 쓰이는 표준 클라이언트가 바로 Certbot입니다.


  1. 자동 발급: 서버 소유권을 확인(Validation)하고 인증서를 내려받습니다.
  2. 자동 설정: Nginx나 Apache 같은 웹 서버의 설정 파일(nginx.conf 등)을 분석하여 HTTPS 설정을 자동으로 추가해 줍니다.
  3. 자동 갱신: 유효 기간이 끝나기 전에 스스로 인증서를 갱신하도록 스케줄링(Cron 등)할 수 있습니다.



작동 원리

Certbot과 Let's Encrypt는 ACME라는 프로토콜을 통해 통신합니다. 대략적인 과정은 다음과 같습니다.


  1. 요청: Certbot이 "나 example.com 주인인데 인증서 좀 줘"라고 요청합니다.
  2. 챌린지(검증): Let's Encrypt가 "진짜 주인인지 확인하게 특정 경로에 파일을 만들거나 DNS 레코드를 추가해 봐"라고 숙제를 줍니다.
  3. 확인: Certbot이 숙제를 수행하면, Let's Encrypt가 확인 후 인증서를 발급합니다.
  4. 적용: Certbot이 받은 인증서를 Nginx 설정에 넣고 서버를 재시작합니다.


인증서 발급 및 적용 방법

  1. 인증서 발급이 필요한 도메인 주소 레코드를 추가합니다.

Cloudflare 사용자는 반드시 프록시 상태를 'DNS 전용'으로 변경(체크 해제)해 주세요.


  1. 80포트 기준 챌린지용 conf 파일을 생성 후 Nginx를 재시작 또는 재실행합니다.
server {
    listen 80;
    server_name foopery.com;

    # Certbot이 챌린지 파일을 생성하고 읽을 경로
    location /.well-known/acme-challenge/ {
        root /var/www/certbot;
    }

    # 그 외의 HTTP 요청은 HTTPS로 강제 리다이렉트
    location / {
        return 301 https://$host$request_uri;
    }
}
# 재실행
nginx -s reload


  1. 인증서 발급 명령어를 입력합니다.
sudo certbot certonly --webroot -w /var/www/certbot -d foopery.com


  1. 발급 성공 시 터미널에 출력되는 pem 경로를 https용 conf 파일에 추가 후 Nginx 재시작 또는 재실행 하면 https가 적용됩니다.
server {
    listen	 443 ssl;
    server_name  foopery.com;

    ssl_certificate /etc/letsencrypt/live/foopery.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/foopery.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    
    client_max_body_size 100M;

    location / {
        proxy_pass http://foopery:80;
        proxy_set_header Host $http_host;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
         root   /usr/share/nginx/html;
    }
}



인증서 자동 갱신 방법

특정 주기에 맞춰서 갱신되도록 스케줄러 이벤트를 구성합니다.


  1. 크론잡 설정
    sudo crontab -e

    처음 접근하는 경우 편집기를 선택하라고 출력되는데 이때 본인이 편한 편집기를 선택하시면됩니다.


  1. 맨 아래줄에 크론 명령어를 설정합니다.
    # 매일 새벽 3시에 인증서 만료체크를하여 만료임박(30일)시 자동갱신됩니다.
    0 3 * * * /usr/bin/certbot renew --quiet --deploy-hook "/usr/sbin/nginx -s reload"
    
    # 도커 컨테이너로 nginx를 구성한 경우
    0 3 * * * /usr/bin/certbot renew --quiet --deploy-hook "/usr/bin/docker exec nginx nginx -s reload"

    크론잡(Cronjob) 환경은 우리가 터미널에서 사용하는 환경 변수($PATH)를 모두 가지고 있지 않기 때문에, 실행 오류를 방지하기 위해 명령어들의 전체 경로(Absolute Path)를 적어주는 것이 가장 안전합니다. 명령어들의 전체 경로를 확인하려면 which nginx명령어로 확인해보세요.


  1. 크론잡의 시간대는 서버의 로컬 타임존 기준으로 실행됩니다 그렇기에 한국시간으로 설정되어있는지 확인이 필요합니다.
    timedatectl

    Local time이 UTC로 구성되어있는 경우가 대부분일건데, KST라면 아래의 설정을 더이상 할 필요 없습니다.


  1. 서버의 로컬 타임존을 한국 시간대로 변경
    sudo timedatectl set-timezone Asia/Seoul


  1. 로컬 타임존이 한국으로 변경되었는지 확인
    timedatectl


  1. 크론잡을 재시작하여 변경된 타임존 기준으로 실행되도록합니다.
    sudo systemctl restart cron


  1. 마지막으로, 크론잡이 정상 실행중인지 상태를 체크 후 종료합니다.
    sudo systemctl status cron

댓글 0

댓글은 회원만 작성할 수 있습니다.

로그인하고 댓글 달기
댓글을 불러오는 중입니다...