TLS 인증서: Let’s Encrypt

July 1, 2019
    본문 업데이트
    2019년 7월 1일: 인증서 갱신 후 추가 작업 자동화 방법 수정
    

    TLS 인증서

    도메인을 확보했으면 그 도메인에 대한 보안 상태를 인증해주는 TLS 인증서를 발급받을 수 있는데, 이 인증서는 웹사이트의 https 접속뿐만 아니라 보안이 필요한 FTPS, VPN 등의 여러 가지 연결에도 사용할 수 있다.

    Let’s Encrypt

    TLS 인증서를 발급하는 여러 기관 중에서 Let’s Encrypt는 무료로 DV (Domain Validation) 인증서를 발급해준다. Let’s Encrypt는 검증된 인증기관(CA)으로서, Let’s Encrypt의 인증서는 모든 웹 브라우저와 VPN 클라이언트 등에서 신뢰 된다.

    Let’s Encrypt가 인증서를 발급하는 방식에는 도메인만 이용하는 방식, 운영 중인 웹사이트를 이용하는 방식, DNS의 TXT 레코드를 이용하는 방식의 세 가지가 있다. 이 중에서 DNS의 TXT 레코드를 이용하는 방식을 사용하면 *.example.com 형태의 와일드카드 서브도메인에 대한 인증서를 발급받을 수 있어서 하나의 인증서로 모든 서브도메인에 사용할 수 있게 되어 편리하다.

    인증서 자동갱신

    Let’s Encrypt 인증서의 유효기간은 90일이고, 유효기간이 30일 남았을 때부터 갱신할 수 있다. 와일드카드 인증서는 갱신할 때마다 DNS의 TXT 레코드를 새로 생성해야 하는데, 보통의 경우에는 매번 자신의 도메인이 연결된 DNS 서비스에 접속해서 수동으로 TXT 레코드를 생성해야 하므로 인증서 갱신 과정을 자동화할 수 없다. 이때 DNS 레코드를 외부에서 입력할 수 있도록 API를 제공하는 DNS 서비스를 이용하면 우분투 서버에서 모든 갱신 과정을 자동으로 처리할 수 있다.

    Let’s Encrypt에서 추천하는 인증서 발급 프로그램인 Certbot은 와일드카드 인증서 자동 갱신을 위해 여러 가지 DNS 서비스를 플러그인 형태로 지원하는데, 여기서는 CloudFlare의 DNS 서비스를 선택했다. CloudFlare는 DNS 뿐만 아니라 CDN, SSL, DDoS 방어 등도 제공하는데, 무료 상품을 이용하더라도 DNS 기능을 사용하기에 충분하다.

    CloudFlare 설정

    DNS 레코드 입력

    CloudFlare에 가입하고 자신의 도메인을 추가한 다음, DNS 레코드 입력 단계에서 자신이 기존에 사용하던 DNS 레코드를 빠짐없이 입력한다.

    설정 항목 중에 아래와 같은 구름 모양의 버튼이 있는데, CloudFlare의 CDN등의 다른 기능은 이용하지 않고 DNS만 이용하려면 이것을 클릭해서 회색으로 설정한다.

    CloudFlare에서 DNS 레코드 입력을 마쳤으면 자신의 도메인을 등록한 사업자에 접속해서 네임 서버를 CloudFlare의 네임 서버로 변경한다. 이후 네임 서버 정보가 업데이트되도록 기다린 다음에 CloudFlare의 Overview 페이지에서 Re-check now 버튼을 눌러 자신의 도메인이 정상적으로 연결되었는지 확인한다.

    Global API Key 확인

    CloudFlare 웹사이트 우측 상단의 개인정보 항목을 클릭하면 My Profile 항목이 보이는데 이곳에서 Global API Key 값을 확인하고 별도로 기록해둔다.

    우분투 서버 설정

    API 정보 파일 생성

    와일드카드 인증서 발급에 CloudFlare의 Global API Key를 사용하기 위해서 Global API Key 정보가 담긴 파일을 우분투 서버에 생성한다.

    sudo mkdir /root/.secrets

    파일이 위치할 임의의 디렉토리를 생성한다.

    sudo nano /root/.secrets/certbot-cloudflare.ini

    생성한 디렉토리 아래에 certbot-cloudflare.ini 라는 이름으로 Global API Key 정보가 담길 파일을 nano 편집기로 생성한다. 파일 이름은 원하는 대로 작성하면 된다.

    dns_cloudflare_email = mail@example.com
    dns_cloudflare_api_key = kq70flsb6lcqd8g262c2b673vb73290vkxj2a
    

    nano 편집기가 열리면 위의 형식으로 자신의 값을 기록한다. mail@example.com은 CloudFlare의 로그인 ID로 사용하는 이메일 주소이고, kq70flsb6lcqd8g262c2b673vb73290vkxj2a은 앞서 확인한 Global API Key 값이다.

    편집을 마쳤으면 Ctrl키와 x키를 동시에 눌러서 nano 편집기를 빠져나오면서 저장한다.

    sudo chmod 0700 /root/.secrets
    sudo chmod 0400 /root/.secrets/certbot-cloudflare.ini
    

    파일이 위치한 디렉토리와 파일에 root 슈퍼유저만 접근할 수 있도록 권한을 조정한다.

    Certbot 설치

    Let’s Encrypt가 추천하는 인증서 발급 프로그램인 Certbot과 와일드카드 인증서 자동 갱신을 위한 CloudFlare 플러그인을 설치한다.

    sudo apt update
    sudo add-apt-repository ppa:certbot/certbot
    

    패키지 저장소 정보를 업데이트하고, 최신 버전의 Certbot을 설치하기 위해서 우분투 서버에 Certbot의 PPA (Personal Package Archive) 저장소 정보를 추가한다. 계속할 것인지 물어오면 엔터키를 입력해서 진행한다. 만일 add-apt-repository 명령이 작동하지 않는다면 우분투 서버에 software-properties-common이 설치되어 있지 않은 경우이므로 sudo apt install software-properties-common 명령으로 먼저 설치한 다음에 진행한다.

    그다음 Certbot을 설치하는데, Certbot은 인증서 발급 기능만 있는 certbot과 발급된 인증서를 웹 서버에 적용까지 해주는 python-certbot-nginx, python-certbot-apache 등의 몇 가지 종류가 있다. 그런데 웹 서버에 자동으로 적용해주는 내용이 일률적이라서 어차피 다시 편집해야 하므로 인증서만 발급받아서 직접 적용하는 편이 오히려 간편하다.

    sudo apt update
    sudo apt install certbot
    

    다시 한번 패키지 저장소 정보를 업데이트하고, 인증서 발급 기능만 있는 certbot을 설치한다.

    sudo apt update
    sudo apt install python3-certbot-dns-cloudflare
    

    그다음, Certbot의 CloudFlare 플러그인 python3-certbot-dns-cloudflare를 설치한다.

    인증서 발급

    sudo certbot certonly --dns-cloudflare --preferred-challenges dns-01 --dns-cloudflare-propagation-seconds 20 --dns-cloudflare-credentials /root/.secrets/certbot-cloudflare.ini -d example.com -d *.example.com

    위 형식의 명령을 실행하면 와일드카드 인증서가 발급된다. certonly는 인증서를 발급받기만 하고 적용은 하지 않는 방식을 뜻하고, --dns-cloudflare은 CloudFlare 플러그인을 사용하는 모드, --preferred-challenges dns-01은 DNS 레코드를 사용해서 인증서를 발급받는 방식을 뜻한다. --dns-cloudflare-propagation-seconds 20은 CloudFlare의 DNS에 TXT 레코드가 생성된 후 Let’s Encrypt가 이를 확인할 때까지 (DNS 레코드가 반영될 때까지) 20초 기다린다는 뜻이다. --dns-cloudflare-credentials 옵션에는 앞서 생성한 Global API Key 정보 파일의 위치 /root/.secrets/certbot-cloudflare.ini를 입력한다. -d 뒤에는 인증서를 발급받을 도메인을 입력하는데, www. 등의 접두사가 없는 루트 도메인 (네이키드 도메인) example.com과 접두사에 와일드카드를 적용한 *.example.com을 각각 입력한다.

    위 명령을 실행하면 아래처럼 몇 가지 정보를 입력하라는 메시지가 출력된다.

    Enter email address (used for urgent renewal and security notices) (Enter 'c' to cancel):
    이메일 주소를 입력한다.

    (A)gree/(C)ancel:
    약관에 동의하기 위해 a를 입력한다.

    (Y)es/(N)o:
    정보 이메일 수신을 원하면 y, 원하지 않으면 n을 입력한다.

    IMPORTANT NOTES:
    - Congratulations! Your certificate and chain have been saved at:
    /etc/letsencrypt/live/example.com/fullchain.pem
    Your key file has been saved at:
    /etc/letsencrypt/live/example.com/privkey.pem
    

    인증서 발급에 성공하면 위와 같이 /etc/letsencrypt/live/example.com/ 경로에 인증서가 저장되었다는 메시지가 출력된다. 보다 자세하게는 총 4종류의 인증서 파일이 생성되는데 각각 다음의 이름으로 저장된다:
    /etc/letsencrypt/live/example.com/cert.pem
    /etc/letsencrypt/live/example.com/chain.pem
    /etc/letsencrypt/live/example.com/fullchain.pem
    /etc/letsencrypt/live/example.com/privkey.pem

    인증서 자동갱신 설정

    Let’s Encrypt 인증서는 유효기간이 90일이고 유효기간이 30일 남았을 때부터 인증서를 갱신할 수 있는데, 본 글처럼 Certbot 저장소 정보를 추가하는 방식으로 Certbot을 설치하면 우분투 서버의 작업 스케줄러에 인증서 자동 갱신 명령이 추가되기 때문에 신경 쓸 것이 없다.

    만일 갱신 작업이 제대로 작동하는지 확인하고 싶다면 sudo certbot renew --dry-run 명령을 실행하면 갱신 시뮬레이션이 진행되고, 성공하면 아래와 같은 메시지가 출력된다.

    Congratulations, all renewals succeeded. The following certs have been renewed:
    /etc/letsencrypt/live/example.com/fullchain.pem (success)
    ** DRY RUN: simulating 'certbot renew' close to cert expiry
    ** (The test certificates above have not been saved.)
    

    추가 작업 자동화

    인증서가 갱신되면 갱신된 인증서를 다른 서비스에 적용하는 일 – 예를 들어 웹사이트를 운영 중이라면 웹 서버를 리로드 하는 일, VPN을 구성했다면 VPN을 재실행하는 일 등을 추가로 처리해야 하는데, Certbot의 후크 기능을 사용하면 이런 추가 작업도 모두 같이 자동화할 수 있다.

    sudo nano /etc/letsencrypt/renewal-hooks/deploy/certbot-deploy-hook.sh

    우선, Certbot이 인증서 갱신 이후의 후크 작업을 관리하는 디렉토리인 /etc/letsencrypt/renewal-hooks/deploy/ 경로에 인증서가 갱신되면 추가로 진행해야 하는 여러 가지 명령을 모아 놓을 스크립트 파일을 하나 생성한다. 파일 이름은 원하는 대로 생성하면 된다.

    #!/bin/bash
    /bin/systemctl reload nginx
    /usr/sbin/ipsec restart
    

    이 파일에 인증서가 갱신되면 추가로 진행할 여러 가지 명령을 기록한다. 위의 예시는 Nginx 웹 서버를 리로드하고, strongSwan VPN을 재실행하는 내용이다. 자신에게 필요한 내용을 작성하고, Ctrl키와 x키를 동시에 눌러 nano 편집기를 빠져나오면서 저장한다. 아직 추가할 작업이 없다면 첫 번째 줄 #!/bin/bash 만 작성하고 나머지 내용은 비워둔 채로 저장해두었다가 나중에 추가해도 된다.

    sudo chmod u+x /etc/letsencrypt/renewal-hooks/deploy/certbot-deploy-hook.sh

    생성한 파일에 실행 권한을 부여한다.

    이제 인증서가 갱신되면 certbot-deploy-hook.sh 파일의 내용이 자동으로 실행된다.

     

    본 글의 저작권은 작성자 Varins에게 있습니다.
    Varins의 사전 서면 동의 없이는 본 글의 전부 또는 일부를 무단으로 전재, 게시, 배포하는 것을 금지합니다.
    

Leave a comment

댓글은 관리자의 승인 이후에 게시됩니다.