본문 바로가기
서버/리눅스 서버

Let's Encrypt SSL 인증서 발급하기 (certbot / renew)

by 도정진 ㅋㅋ잠자 2020. 4. 5.

안녕하세요.


최근에 FTPS 서버 설정을 하면서, 확인되지 않은 CA 에서 발급한 인증서로 에러가 발생하는 부분이 있어서 이번에 Let's Encrypt 를 통해 모두 신뢰할 수 있는 CA 에서 발급한 인증서로 처리하기 위해 아래의 가이드를 백업합니다.


정확히 인증 과정에 대해서 모르며, 설정방법에 대해서만 기술합니다.


이전에는 와일드 카드가 되지 않았는데 이제 된다고 해서 시도해봄직 한 부분이 있습니다.


https://letsencrypt.org/ko/






1. certbot 설치하기


간단하게 apt 툴로 설치합니다.


root@AOL-Debian:~# apt install certbot

Reading package lists... Done

Building dependency tree       

Reading state information... Done

The following additional packages will be installed:

  python3-acme python3-certbot python3-configargparse python3-configobj python3-josepy python3-mock python3-openssl python3-parsedatetime python3-pbr python3-requests-toolbelt python3-rfc3339 python3-tz

  python3-zope.component python3-zope.event python3-zope.hookable python3-zope.interface

Suggested packages:

  python3-certbot-apache python3-certbot-nginx python-certbot-doc python-acme-doc python-configobj-doc python-mock-doc python-openssl-doc python3-openssl-dbg

Recommended packages:

  python3-pyicu

The following NEW packages will be installed:

  certbot python3-acme python3-certbot python3-configargparse python3-configobj python3-josepy python3-mock python3-openssl python3-parsedatetime python3-pbr python3-requests-toolbelt python3-rfc3339

  python3-tz python3-zope.component python3-zope.event python3-zope.hookable python3-zope.interface

0 upgraded, 17 newly installed, 0 to remove and 92 not upgraded.

Need to get 809 kB of archives.

After this operation, 4,358 kB of additional disk space will be used.

Do you want to continue? [Y/n]


일단 실행이 되는지 한번 체크합니다.


root@AOL-Debian:~# certbot

Saving debug log to /var/log/letsencrypt/letsencrypt.log

Certbot doesn't know how to automatically configure the web server on this system. However, it can still get a certificate for you. Please run "certb web server to use the resulting certificate.





2. 인증서 발급받기


# 저는 DNS 로 인증하고 -d 로 설정할 도메인을 입력합니다.

root@AOL-Debian:~# certbot certonly --manual --preferred-challenges dns \

> -d "djjproject.com" -d "www.djjproject.com" -d "*.djjproject.com"

Saving debug log to /var/log/letsencrypt/letsencrypt.log

Plugins selected: Authenticator manual, Installer None


Enter email address (used for urgent renewal and security notices) (Enter 'c' to

cancel): djj9405@naver.com


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

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 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: N

Obtaining a new certificate


# www 의 경우에도 * 에 들어가기 때문에 ... 에러가 나는 부분입니다.

An unexpected error occurred:

The request message was malformed :: Error creating new order :: Domain name "www.djjproject.com" is redundant with a wildcard domain in the same request. Remove one or the other from the certificate request.

Please see the logfiles in /var/log/letsencrypt for more details.


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.


# 다시 해봅니다.

root@AOL-Debian:~# certbot certonly --manual --preferred-challenges dns -d "djjproject.com"  -d "*.djjproject.com"

Saving debug log to /var/log/letsencrypt/letsencrypt.log

Plugins selected: Authenticator manual, Installer None

Obtaining a new certificate

Performing the following challenges:

dns-01 challenge for djjproject.com

dns-01 challenge for djjproject.com


# 아래는 Y를 입력해야 넘어갈 수 있습니다.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

NOTE: The IP of this machine will be publicly logged as having requested this

certificate. If you're running certbot in manual mode on a machine that is not

your server, please ensure you're okay with that.


Are you OK with your IP being logged?

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

(Y)es/(N)o: Y


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Please deploy a DNS TXT record under the name

_acme-challenge.djjproject.com with the following value:


YI2oDOIOg_SVOg


Before continuing, verify the record is deployed.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Press Enter to Continue


일단 엔터를 누르기 전에 도메인 설정하러 dnszi 로 한번 가보겠습니다.


아래와 같이 TXT 를 설정합니다.



실제로 반영되는데에 시간이 조금 걸림으로 아래의 명령으로 반영이 되었는지 확인해 봅니다.


root@AOL-Debian:~# nslookup -q=TXT _acme-challenge.djjproject.com

Server: 8.8.8.8

Address: 8.8.8.8#53


Non-authoritative answer:

_acme-challenge.djjproject.com text = "YI2oDOIOg_SVOg1ser4yTXKucXfEjyocaH7hSbqlBhw"


Authoritative answers can be found from:


그리고 엔터를 눌러 진행합니다.


엔터를 누르면 또 추가하라고 하는데 추가하고 상기 명령으로 반영되는 데 까지 대기를 합니다.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Please deploy a DNS TXT record under the name

_acme-challenge.djjproject.com with the following value:


YI2oDOIOg_SVOg1ser4yTXKucXfEjyocaH7hSbqlBhw


Before continuing, verify the record is deployed.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Press Enter to Continue


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Please deploy a DNS TXT record under the name

_acme-challenge.djjproject.com with the following value:


ACiYqZWFbcG3SHxrz1pkTMrIIKy4Ndu6KGtyU7jFw0k


Before continuing, verify the record is deployed.

(This must be set up in addition to the previous challenges; do not remove,

replace, or undo the previous challenge tasks yet. Note that you might be

asked to create multiple distinct TXT records with the same name. This is

permitted by DNS standards.)

# 동일한 이름으로 레코드 생성이 가능하고 2개를 등록하라고 합니다.


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Press Enter to Continue



반영되기까지 얼마나 걸릴 지 몰라서 watch 명령을 돌려놓고 기다립니다.



중간에 못참고 엔터 눌렀다가 2번째 키가 바뀌어서 또 기다리게 되었네요.


커피한잔 하고 오시면 될 것 같습니다. ㅎㅎㅎ


한편, 오랫동안 반영이 되지 않아서 TTL 설정까지 하게 되었습니다.



반영되면 기본설정으로 돌려놓으면 될 것 같습니다.


Every 5.0s: nslookup -q=TXT _acme-challenge.djjproject.com     AOL-Debian: Sun Apr  5 22:59:55 2020


Server:         8.8.8.8

Address:        8.8.8.8#53


Non-authoritative answer:

_acme-challenge.djjproject.com  text = "CAXAjzmV5qDO5o1GaWuQQc1ndbQRSXelbIJ5vYpfMG4"

_acme-challenge.djjproject.com  text = "YI2oDOIOg_SVOg1ser4yTXKucXfEjyocaH7hSbqlBhw"


Authoritative answers can be found from:


설정이 올라와서 이제 진행하면 될 것 같네요.


Waiting for verification...

Cleaning up challenges


IMPORTANT NOTES:

 - Congratulations! Your certificate and chain have been saved at:

   /etc/letsencrypt/live/djjproject.com/fullchain.pem

   Your key file has been saved at:

   /etc/letsencrypt/live/djjproject.com/privkey.pem

   Your cert will expire on 2020-07-04. 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


완료 되었습니다.





3. 웹서버에 적용하기


저는 아파치 웹서버를 쓰고 있습니다.


guacamole 의 경우 아래와 같이 설정이 가능합니다.



  1 <Virtualhost *:80>

  2 ServerName remote.mycloud.djjproject.com

  3 ServerAlias remote.djjproject.com

  4 RewriteEngine On

  5 RewriteCond %{HTTPS} off

  6 RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}

  7 </VirtualHost>

  8 

  9 <VirtualHost *:443>

 10 ServerName remote.mycloud.djjproject.com

 11 ServerAlias remote.djjproject.com

 12 SSLEngine On

 13 SSLCertificateFile /etc/letsencrypt/live/djjproject.com/cert.pem

 14 SSLCertificateKeyFile /etc/letsencrypt/live/djjproject.com/privkey.pem

 15 SSLCertificateChainFile /etc/letsencrypt/live/djjproject.com/chain.pem

 16 SSLProtocol +TLSv1.2

 17 

 18 ProxyPreserveHost On

 19 SSLProxyEngine On

 20 ProxyRequests Off

 21 RequestHeader set Front-End-Https "On"

 22 

 23 <Location />

 24 Order allow,deny

 25 Allow from all

 26 ProxyPass http://127.0.0.1:8080/guacamole/ max=20 flushpackets=on

 27 ProxyPassReverse http://127.0.0.1:8080/guacamole/

 28 ProxyPassReverseCookiePath /guacamole/ /

 29 </Location>

 30 <Location /websocket-tunnel>

 31 Order allow,deny

 32     Allow from all

 33 ProxyPass ws://127.0.0.1:8080/guacamole/websocket-tunnel

 34 ProxyPassReverse ws://127.0.0.1:8080/guacamole/websocket-tunnel

 35 </Location>

 36 </Virtualhost>


그럼 아래와 같이 매번 뜨는 에러가 아닌 정상적으로 SSL 연결을 사용하고 있다는 메시지가 뜹니다.







4. ftps 에 letsencrypt 사용하기


일단 fullchain.pem 파일에 private 키가 포함되어 제공되지 않음으로 cat 으로 합쳐서 파일을 아래와 같이 생성합니다.


root@AOL-Debian:/etc/ssl/private# cat ../../letsencrypt/live/djjproject.com/privkey.pem ../../letsencrypt/live/djjproject.com/fullchain.pem > pure-ftpd.pem



정상적으로 인식을 하고 있는데 아직 KODI 에서는 연결이 되지 않습니다.


차후에 알아보도록 하겠습니다.





5. 인증서 자동 갱신 설정하기


급하게 대충 작성하고 crontab 에 등록합니다.


  1 #!/bin/bash

  2 

  3 # ssl renew

  4 date

  5 echo "renew cert.."

  6 /usr/bin/certbot renew

  7 

  8 # pure-ftpd ssl renew

  9 echo "re-generate pure-ftpd.pem ..."

 10 SSLDIR=/etc/letsencrypt/live/djjproject.com

 11 cat $SSLDIR/privkey.pem $SSLDIR/fullchain.pem > /etc/ssl/private/pure-ftpd.pem

 12 /etc/init.d/pure-ftpd restart


실행 테스트


root@AOL-Debian:/home# ./renew_ssl.sh 

renew cert..

Saving debug log to /var/log/letsencrypt/letsencrypt.log


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Processing /etc/letsencrypt/renewal/djjproject.com.conf

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Cert not yet due for renewal


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


The following certs are not due for renewal yet:

  /etc/letsencrypt/live/djjproject.com/fullchain.pem expires on 2020-07-04 (skipped)

No renewals were attempted.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

re-generate pure-ftpd.pem ...

Restarting ftp server: Running: /usr/sbin/pure-ftpd-virtualchroot -l puredb:/etc/pure-ftpd/pureftpd.pdb -l pam -9 utf8 -H -Y 1 -b -O clf:/var/log/pure-ftpd/transfer.log -U 000:000 -E -u 0 -A -8 utf8 -J HIGH -p 49152:65534 -B

root@AOL-Debian:/home# vim renew_ssl.sh 

root@AOL-Debian:/home# ./renew_ssl.sh 

Sun Apr  5 23:27:14 KST 2020

renew cert..

Saving debug log to /var/log/letsencrypt/letsencrypt.log


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Processing /etc/letsencrypt/renewal/djjproject.com.conf

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Cert not yet due for renewal


- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


The following certs are not due for renewal yet:

  /etc/letsencrypt/live/djjproject.com/fullchain.pem expires on 2020-07-04 (skipped)

No renewals were attempted.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

re-generate pure-ftpd.pem ...

Restarting ftp server: Running: /usr/sbin/pure-ftpd-virtualchroot -l puredb:/etc/pure-ftpd/pureftpd.pdb -l pam -9 utf8 -H -Y 1 -b -O clf:/var/log/pure-ftpd/transfer.log -U 000:000 -E -u 0 -A -8 utf8 -J HIGH -p 49152:65534 -B


crontab 에 등록합니다.


# letsencrypt

0 6 1 * * su root -c "/home/renew_ssl.sh > /var/log/ssl_generate.log 2>&1


매월 1일 6시에 renew 를 하는 것으로 설정하였습니다.




한편, 추가적으로 다른 앱과 호환성에 대해서는 차후에 알아보겠습니다.


감사합니다.




댓글0