본문 바로가기
Linux

certbot - LetsEncrypt으로 Nginx에 무료 SSL 적용

by 올엠 2022. 12. 13.
반응형

SSL 인증서는 구매하여 사용하기에는 큰 대형 사이트가 아니라면, 일반적인 작은 사이트 혹은 프리랜서용 사이트라면 부담이 클 수 있다. 이를 해결해 주는 것이 바로 Let's Encrypt 에서 제공하는 무료 SSL 인증서라고 할 수 있다. 

Let's Encrypt (letsencrypt.org)에 방문하여 기부하는 것도 가능하니 만약 도움을 받았다고 생각이 든다면, 기부를 해보는 것도 추찬한다.

여기에서는 이 Let's Encrypt 를 Nginx에 적용하는 방법에 대해서 정리해 보고자 한다.

 

여기에서 기본적으로 사용하는 추가 라이브러리는 Certbot이다.

 

Certbot

Tagline

certbot.eff.org

1. Nginx 및 Certbot 설치

가장 먼저 Nginx를 설치한다. 이미 설치가 되었다면, 이 부분은 스킵해도 된다.

sudo apt install nginx

콘솔내용

azureuser@geip:~/geoip/base$ sudo apt install nginx
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  fontconfig-config fonts-dejavu-core libfontconfig1 libgd3 libjbig0 libjpeg-turbo8 libjpeg8 libnginx-mod-http-image-filter libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-stream
  libtiff5 libwebp6 libxpm4 nginx-common nginx-core
Suggested packages:
  libgd-tools fcgiwrap nginx-doc ssl-cert
The following NEW packages will be installed:
  fontconfig-config fonts-dejavu-core libfontconfig1 libgd3 libjbig0 libjpeg-turbo8 libjpeg8 libnginx-mod-http-image-filter libnginx-mod-http-xslt-filter libnginx-mod-mail libnginx-mod-stream
  libtiff5 libwebp6 libxpm4 nginx nginx-common nginx-core
0 upgraded, 17 newly installed, 0 to remove and 17 not upgraded.
Need to get 2435 kB of archives.
After this operation, 7909 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://azure.archive.ubuntu.com/ubuntu focal/main amd64 fonts-dejavu-core all 2.37-1 [1041 kB]
Get:2 http://azure.archive.ubuntu.com/ubuntu focal/main amd64 fontconfig-config all 2.13.1-2ubuntu3 [28.8 kB]
Get:3 http://azure.archive.ubuntu.com/ubuntu focal/main amd64 libfontconfig1 amd64 2.13.1-2ubuntu3 [114 kB]
Get:4 http://azure.archive.ubuntu.com/ubuntu focal-updates/main amd64 libjpeg-turbo8 amd64 2.0.3-0ubuntu1.20.04.3 [118 kB]
Get:5 http://azure.archive.ubuntu.com/ubuntu focal/main amd64 libjpeg8 amd64 8c-2ubuntu8 [2194 B]
...(중략)
Processing triggers for man-db (2.9.1-1) ...
Processing triggers for libc-bin (2.31-0ubuntu9.9) ...

이후 Certbot도 설치하도록 하자. Nginx용은 별도의 이름을 가지고 있기 때문에, 아래 명령을으로 Nginx용을 설치할 수 있다.

sudo add-apt-repository ppa:certbot/certbot
sudo apt install python3-certbot-nginx

콘솔내용

azureuser@geip:~/geoip/base$ sudo add-apt-repository ppa:certbot/certbot
 The PPA has been DEPRECATED.

To get up to date instructions on how to get certbot for your systems, please see https://certbot.eff.org/docs/install.html.
 More info: https://launchpad.net/~certbot/+archive/ubuntu/certbot
Press [ENTER] to continue or Ctrl-c to cancel adding it.

Hit:1 http://azure.archive.ubuntu.com/ubuntu focal InRelease
Get:2 http://azure.archive.ubuntu.com/ubuntu focal-updates InRelease [114 kB]
Get:3 http://azure.archive.ubuntu.com/ubuntu focal-backports InRelease [108 kB]
Get:4 http://azure.archive.ubuntu.com/ubuntu focal-security InRelease [114 kB]
Hit:5 https://packages.microsoft.com/ubuntu/20.04/prod focal InRelease                     
Ign:6 http://ppa.launchpad.net/certbot/certbot/ubuntu focal InRelease                      
Get:7 http://azure.archive.ubuntu.com/ubuntu focal-updates/main amd64 Packages [2269 kB]
Get:8 http://azure.archive.ubuntu.com/ubuntu focal-updates/main amd64 c-n-f Metadata [16.1 kB]
Err:9 http://ppa.launchpad.net/certbot/certbot/ubuntu focal Release
  404  Not Found [IP: 185.125.190.52 80]
Get:10 http://azure.archive.ubuntu.com/ubuntu focal-security/main amd64 c-n-f Metadata [11.5 kB]
Reading package lists... Done     
E: The repository 'http://ppa.launchpad.net/certbot/certbot/ubuntu focal Release' does not have a Release file.
N: Updating from such a repository can't be done securely, and is therefore disabled by default.
N: See apt-secure(8) manpage for repository creation and user configuration details.

azureuser@geip:~/geoip/base$ sudo apt install python3-certbot-nginx
Reading package lists... Done
Building dependency tree       
Reading state information... Done
The following additional packages will be installed:
  python3-pyparsing
Suggested packages:
  python-certbot-nginx-doc python-pyparsing-doc
The following NEW packages will be installed:
  python3-certbot-nginx python3-pyparsing
0 upgraded, 2 newly installed, 0 to remove and 17 not upgraded.
Need to get 112 kB of archives.
After this operation, 591 kB of additional disk space will be used.
Do you want to continue? [Y/n] y
Get:1 http://azure.archive.ubuntu.com/ubuntu focal/main amd64 python3-pyparsing all 2.4.6-1 [61.3 kB]
Get:2 http://azure.archive.ubuntu.com/ubuntu focal-updates/universe amd64 python3-certbot-nginx all 0.40.0-0ubuntu0.1 [50.8 kB]
Fetched 112 kB in 0s (2022 kB/s)               
Selecting previously unselected package python3-pyparsing.
(Reading database ... 71758 files and directories currently installed.)
Preparing to unpack .../python3-pyparsing_2.4.6-1_all.deb ...
Unpacking python3-pyparsing (2.4.6-1) ...
Selecting previously unselected package python3-certbot-nginx.
Preparing to unpack .../python3-certbot-nginx_0.40.0-0ubuntu0.1_all.deb ...
Unpacking python3-certbot-nginx (0.40.0-0ubuntu0.1) ...
Setting up python3-pyparsing (2.4.6-1) ...
Setting up python3-certbot-nginx (0.40.0-0ubuntu0.1) ...

 

Nginx 는 사이트 설정을 각 사이트 이름으로 진행할 수 있다. 만약 기본 설정을 변경하고자 한다면, /etc/nginx/sites-available/default 파일을 수정해 주면 되며, 다중 사이트를 설정한다면, {domain} 이름을 지정하도록 하자.

sudo nano /etc/nginx/sites-available/example.com
sudo systemctl reload nginx

내용은 server_name으로 추가하면 되며, 도메인 이름의 접근 주소를 공백으로 모두 설정하면 된다. 모두 입력하였다면 세미콜론으로 마무리 한다. 이후 설정 적용을 위해서 서비스 환경 설정을 다시 읽어드리도록 하자.

server_name 도메인이름(DNS) 도메인이름(DNS) 도메인이름(DNS);

콘솔내용

azureuser@geip:~/geoip/base$ sudo nano /etc/nginx/sites-available/example.com


Use "fg" to return to nano.

[2]+  Stopped                 sudo nano /etc/nginx/sites-available/geoip.one

azureuser@geip:~/geoip/base$ sudo systemctl reload nginx

2. Certbot SSL 인증서 설정

앞서 Nginx용으로 설치한 Certbot을 통해 인증서를 생성할 차례이다.

sudo certbot --nginx -d 도메인이름(DNS)

위 명령을 실행하면, 아래와 같이 관리자 이메일부터 기본 환경 설정을 물어보는데 본인에게 알맞은 값을 선택하도록 하자.

가장 망설여지는 SSL Redirect은 요즘 대부분 SSL 접근만 허용하는 추세이므로, 필자는 2번을 선택했다.

콘솔화면

azureuser@geip:~/geoip/base$ sudo certbot --nginx -d geoip.one
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): allmnet@naver.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.3-September-21-2022.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: a

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing 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: y
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for geoip.one
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/sites-enabled/default

Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Redirecting all traffic on port 80 to ssl in /etc/nginx/sites-enabled/default

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://geoip.one

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=geoip.one
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/geoip.one/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/geoip.one/privkey.pem
   Your cert will expire on 2023-03-13. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - 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

azureuser@geip:~/geoip/base$ sudo certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/geoip.one.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not due for renewal, but simulating renewal for dry run
Plugins selected: Authenticator nginx, Installer nginx
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for geoip.one
Waiting for verification...
Cleaning up challenges

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed with reload of nginx server; fullchain is
/etc/letsencrypt/live/geoip.one/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

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

IMPORTANT NOTES:
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.

작업이 마무리되면, 아래와 같이 공개키와 비밀키 위치를 알려주며 이를 본인의 웹서버에 설정하면 된다.

3. Certbot SSL 인증서 자동 갱신 설정

이제 마지막으로 자동 갱신 설정을 진행하도록 하자.

무료로 발급받은 SSL 인증서는 90일간 유효안 인증서이다. 이를 갱신시점이 도달하기 전에 자동으로 갱신을 하기 위해서는 Cron Job에 등록하여 사용할 필요가 있다. 먼저 갱신시 문제가 있는지 확인을 위해서 renew --dry-run을 실행하도록 하자. --dry-run 옵션을 붙이면 실제 인증서를 갱신하지 않고, 테스트만 진행하게 된다.

sudo certbot renew --dry-run

필자와 같이 오류가 없다면 renew 명령을 Cron Job으로 등록해도 무방하다고 할 수 있다.

콘솔화면

azureuser@geip:~/geoip/base$ sudo certbot renew --dry-run
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/geoip.one.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not due for renewal, but simulating renewal for dry run
Plugins selected: Authenticator nginx, Installer nginx
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for geoip.one
Waiting for verification...
Cleaning up challenges

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed with reload of nginx server; fullchain is
/etc/letsencrypt/live/geoip.one/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
** DRY RUN: simulating 'certbot renew' close to cert expiry
**          (The test certificates below have not been saved.)

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

IMPORTANT NOTES:
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal

Crontab은 -e 옵션을 이용해서 편집이 가능하다.

(sudo를 통해 crontab을 실행하면 root의 작업 리스트를 여는 것이며, 별도의 계정에서 작업하는 것도 가능하지만, Certbot을 기본적으로 설치했다면 root 권한이 필요하다.) 

sudo crontab -e

Crontab은 기본적으로 6개의 시간 값이후에 자신이 실행하고자 하는 명령을 입력하는 방식이며, 6개의 시간 값은 아래와 같은 의미가 있다.

Cron Jobs - How to Setup, Edit and Save them (webservertalk.com)
시간값 예시

세부적인 시간 설정은 다른 곳에서 다루고, 여기에서는 매월 1일 01시에 인증서를 갱신하고자 한다면 다음과 같은 명령을 이용할 수 있다.

0 1 1 * * /usr/bin/certbot renew --renew-hook="sudo systemctl restart nginx"

--renew-hook은 certbot에서 제공하는 옵션으로 만약 인정서 갱신이 성공적으로 완료되었다면 다음에 실행할 명령을 전달할 수 있다. 위에서는 nginx를 재시작하도록 구성하였다.

정상적으로 설정하였다면, Crontab 서비스를 재시작하고, 작업이 정상적으로 잘 등록 되었는지 -l 옵션을 이용해서 확인이 가능하다.

sudo service cron restart
sudo crontab -l

추후 실행상 문제가 발생하면 /var/log/cron.log 에서 확인이 가능하다.

 

반응형