홈 서버 만들기 07. SSL/TLS 인증서: Let’s Encrypt (Wildcard)

May 10, 2018

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

Let’s Encrypt SSL/TLS 인증서

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

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

와일드카드 인증서 발급

먼저, 와일드카드 인증서 발급은 DNS의 TXT 레코드 정보를 이용하므로 자신의 도메인이 연결된 DNS에서 TXT 레코드를 생성할 수 있어야 한다. 대부분의 도메인 등록 기관들은 “DNS 설정” 등의 이름으로 이를 지원한다.

그다음, Let’s Encrypt 인증서를 발급받기 위한 프로그램으로 Let’s Encrypt에서 권장하는 certbot를 우분투 서버에 설치한다.

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

패키지 저장소 정보를 업데이트하고, 최신 버전의 certbot를 설치하기 위해서 우분투 서버에 certbot 저장소 정보를 추가한다. 계속할 것인지 물어오면 엔터키를 입력해서 진행한다.

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

sudo apt-get update
sudo apt-get install certbot

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

sudo certbot certonly --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory -d example.com -d *.example.com

인증서를 발급받는 명령이다. certonly는 인증서를 발급받기만 하고 적용은 하지 않는 방식을 뜻하고, --manual은 인증서 발급과 적용을 도와주는 플러그인을 사용하지 않는 수동 모드, --preferred-challenges dns는 DNS 정보를 사용하는 방식을 뜻한다. --server 옵션에는 와일드카드 인증서를 발급받기 위한 Let’s Encrypt의 서버 정보가 들어간다. -d 뒤에는 인증서를 발급받을 도메인을 입력하는데, www. 등의 접두사가 없는 네이키드 도메인 example.com과 접두사에 와일드카드를 적용한 *.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을 입력한다.

(Y)es/(N)o:
인증서 발급을 위해 IP 주소가 기록된다는 메시지에 y를 입력한다.

-------------------------------------------------------------------------------
Please deploy a DNS TXT record under the name
_acme-challenge.example.com with the following value:

A-52Wm8V7xoUpGax-F8FrPO65cQRcbRj-XoblaY4uYM

Before continuing, verify the record is deployed.
-------------------------------------------------------------------------------
Press Enter to Continue

그다음, 도메인의 DNS에 TXT 레코드를 설정하라는 메시지가 나오는데, 빨간색 TXT 레코드 부분은 매번 모두 다르게 출력된다. 그리고 example.com과 *.example.com의 2가지 주소의 인증서를 발급하므로 TXT 레코드도 2가지를 설정해야 한다. 엔터키를 입력하면 두 번째 TXT 레코드가 출력된다.

-------------------------------------------------------------------------------
Please deploy a DNS TXT record under the name
_acme-challenge.example.com with the following value:

6KOgCI0p_LRhtrJMh9aTYAek6hZ64nT75-DkeeQccfA

Before continuing, verify the record is deployed.
-------------------------------------------------------------------------------
Press Enter to Continue

이렇게 두 번째 TXT 레코드까지 확인한 다음에, 이번에는 Press Enter to Continue 메시지에 엔터키를 입력하지 말고 그대로 놔둔 상태에서, 자신의 도메인의 DNS를 관리하는 곳에 접속해서 자신에게 출력된 내용대로 TXT 레코드 2가지를 생성한다.

예를 들어서, 위의 내용을 구글 도메인의 DNS 구성에서 설정하면 아래와 같다.

_acme-challenge 항목으로, TXT 레코드를 생성하고, TTL은 나중에 다시 입력해야 할 일이 생길 때를 대비해서 최대한 빠르게 갱신되도록 1분 정도로 짧게 입력하고, 출력된 TXT 레코드 A-52Wm8V7xoUpGax-F8FrPO65cQRcbRj-XoblaY4uYM6KOgCI0p_LRhtrJMh9aTYAek6hZ64nT75-DkeeQccfA 를 입력하고 저장한다. 이 문자열은 매번 달라지므로 자신의 메시지에 출력된 문자열을 정확하게 입력한다.

TXT 레코드를 정확하게 생성했으면 TXT 레코드가 반영되도록 어느 정도 시간을 기다린 뒤, 두 번째 Press Enter to Continue 메시지에 엔터키를 입력하면 인증서 발급이 진행된다. TXT 레코드가 반영되었는지 확인하는 방법은 PuTTY나 터미널 창을 하나 더 열고 dig -t txt _acme-challenge.example.com 명령을 실행하면 된다. 또는 윈도우 OS의 명령 프롬프트를 열고 nslookup -type=txt _acme-challenge.example.com 명령을 실행해도 된다.

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가 우분투 서버의 작업 스케줄러에 자동으로 갱신되도록 처리해두었기 때문에 신경 쓸 것이 없다.

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

우선, 인증서가 갱신되면 추가로 진행해야 하는 여러 가지 명령을 모아 놓을 스크립트 파일을 하나 생성한다.

sudo nano /usr/local/etc/certbot-renew-hook.sh

nano 편집기로 적당한 위치에 적당한 이름의 .sh 파일을 새로 생성한다.

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

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

sudo chmod u+x /usr/local/etc/certbot-renew-hook.sh

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

그다음, 작성한 .sh 파일을 Certbot가 생성한 작업 스케줄에 후크로 연결한다.

sudo nano /etc/cron.d/certbot

Certbot가 생성한 작업 스케줄 내용을 nano 편집기로 연다.

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew

이런 형태의 내용이 있을 것이다.

0 */12 * * * root test -x /usr/bin/certbot -a \! -d /run/systemd/system && perl -e 'sleep int(rand(43200))' && certbot -q renew --renew-hook /usr/local/etc/certbot-renew-hook.sh

이렇게 끝부분에 --renew-hook /usr/local/etc/certbot-renew-hook.sh 를 추가하고, Ctrl키와 x키를 동시에 눌러 nano 편집기를 빠져나오면서 저장한다. 이제 인증서가 갱신되면 /usr/local/etc/certbot-renew-hook.sh 파일에 담긴 명령이 자동으로 실행된다.

 

홈 서버 만들기 목차 
https://varins.com/category/server

01. 하드웨어 구성과 전기 요금
02. 우분투 서버 18.04 LTS 설치
03. 우분투 서버 18.04 LTS 기본 설정
04. 파일 복원: Btrfs 스냅샷
05. 네트워크 파일 공유: Samba (SMB)
06. Dynamic DNS: 구글 도메인 + ddclient
07. SSL/TLS 인증서: Let's Encrypt (Wildcard)
08. 웹 서버: Nginx + https 보안연결
09. 웹사이트: php + MariaDB + WordPress
10. 서버 모니터링: Monitorix + Nginx Proxy
11. FTPS: vsftpd
12. VPN: IKEv2 (strongSwan)
13. Torrent: Transmission
14. 클라우드 스토리지: Nextcloud (Nginx, MariaDB)
15. 온라인 오피스: ONLYOFFICE (Docker, Nginx)
16. 트랜스코딩: Plex

Leave a comment

Your email address will not be published. Required fields are marked *

Prev Post Next Post