Let's Encrypt 인증서 발급 (certonly)

Written by TELK on 2023.02.01

Let's Encrypt 인증서는 무료로 사용할 수 있는 인증서로, 무료가 장점이지만 3개월마다 재발급해주어야 하는 것이 단점이다. 재발급은 crontab과 같은 스케쥴러를 이용하면 되므로 결국 우리는 무료+기한없이 SSL 인증서를 웹 서버에 사용할 수 있다.

여기에서는 Let's Encrypt 인증서를 인증서만 발급(certonly)받아 Apache 웹 서버에 반영하는 방법을 알아본다.
아래의 설명은 Ubuntu 20.04/22.04 를 기준으로 한다. (사실 혼자 보려고 적어둔 글이라 매우 설명이 부족하니 Google에 검색해서 더 자세히 설명한 글을 보는 게 좋다.)

설치

sudo apt install letsencrypt -y


인증서 발급 (certonly)

인증서만 발급받아 아파치 설정에 추가하여 사용할 것이다.

sudo letsencrypt certonly --webroot --webroot-path={사이트가 있는 폴더의 경로} -d {도메인}

{사이트가 있는 폴더의 경로}는 정확하게는 .well-known 폴더가 있는 위치를 지정하면 되는데 보통은 사이트 루트 경로를 지정하면 된다.
{도메인}이 여러 개라면 아래와 같이 콤마(,)나 공백으로 연결하면 된다:
sudo letsencrypt certonly --webroot --webroot-path=/var/html/www -d mydomain.com,www.mydomain.com

아래의 모든 설명에서 도메인은 mydomain.com으로 설명하므로 본인의 상황에 맞는 도메인으로 수정해서 사용하면 된다.

최초로 letsencrypt 명령어를 실행할 경우 몇 가지 단계를 거쳐야 한다.
먼저 인증서의 만료(expire) 안내를 받을 전자 우편 주소를 입력한다:

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator standalone, Installer None
Enter email address (used for urgent renewal and security notices)
(Enter 'c' to cancel):


그 다음으로는 약관 동의 여부를 물어본다. 반드시 Y 또는 Yes를 입력한다:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server. Do you agree?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y


다음으로 전자우편으로 Let's Encrypt의 프로젝트 정보를 받아올지를 선택하는데 굳이 받을 필요 없으므로 No를 입력한다:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing, once your first certificate is successfully issued, to
share your email address with the Electronic Frontier Foundation, a founding
partner of the Let's Encrypt project and the non-profit organization that
develops Certbot? We'd like to send you email about our work encrypting the web,
EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o:


인증서가 발급된 경우 아래와 같이 Congratulations! 라는 문구와 함께 체인 키 파일과 개인 키 파일 경로가 두 개 나타나는데 이를 복사해둔다.

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/mydomain.com/fullchain.pem               #<= 발급된 체인 키 파일
   Your key file has been saved at:
   /etc/letsencrypt/live/mydomain.com/privkey.pem                 #<= 발급된 개인 키 파일
   Your certificate will expire on 2021-05-16. To obtain a new or
   tweaked version of this certificate in the future, simply run
   certbot again. To non-interactively renew *all* of your
   certificates, run "certbot renew"
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le         



Apache의 VirtualHost 설정 파일 수정

/etc/apache2/sites-available/ 폴더 안에 있는 VirtualHost 설정 파일을 보면 아래와 같은 내용이 있다.

<VirtualHost *:80>
    # (중략...)
</VirtualHost>

<VirtualHost *:80> ~ </VirtualHost> 부분을 복사하고 80443으로 변경한 다음, ssl 모듈이 있을 때에만 https를 활성화하기 위해 <IfModule mod_ssl.c> ~ </IfModule>로 한 번 더 감싼 다음,
</VirtualHost> 윗줄에 아래 내용을 추가한다.

    # SSL
    SSLEngine on

    # Intermediate configuration, tweak to your needs
    SSLProtocol             all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite          ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
    SSLHonorCipherOrder     on
    SSLCompression          off

    SSLOptions +StrictRequire

    # Add vhost name to log entries:
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" vhost_combined
    LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common

    SSLCertificateFile /etc/letsencrypt/live/mydomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/mydomain.com/privkey.pem

최종적으로 아래와 같은 내용이 되면 된다.

<VirtualHost *:80>
    # (중략...)
</VirtualHost>

<IfModule mod_ssl.c>
<VirtualHost *:443>
    # (중략...)

    # SSL
    SSLEngine on

    # Intermediate configuration, tweak to your needs
    SSLProtocol             all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1
    SSLCipherSuite          ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS
    SSLHonorCipherOrder     on
    SSLCompression          off

    SSLOptions +StrictRequire

    # Add vhost name to log entries:
    LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-agent}i\"" vhost_combined
    LogFormat "%v %h %l %u %t \"%r\" %>s %b" vhost_common

    SSLCertificateFile /etc/letsencrypt/live/mydomain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/mydomain.com/privkey.pem
</VirtualHost>
</IfModule>

mod_ssl 활성화

다음 명령어를 입력하여 mod_ssl을 활성화하고 apache를 재시작한다.

sudo a2enmod ssl
sudo systemcl reload apache2

자동 갱신

crontab을 열고(sudo crontab -e) 다음 내용을 추가한다:

10 6 * * * /usr/bin/letsencrypt renew 1>>/var/log/letsencrypt-renew.log 2>&1

매일 610분에 갱신을 시도한다는 뜻으로 원하는 시각으로 변경한다.
실행 결과는 /var/log/letsencrypt-renew.log 파일에 기록한다는 뜻으로, 경로는 원하는 위치로 변경해도 된다.

자동 갱신이 잘 되는지 확인해보려면 dry-run 을 해본다:

letsencrypt renew --dry-run