letsencrypt 와일드카드(Wildcard) 인증서 생성하기

우선 와일드카드(Wildcard) 인증서가 뭔지 보자.

구글에서 "와일드카드 인증서"라고 검색해보면 아래와 같은 내용이 나온다.

와일드카드(Wildcard) 인증서란, 도메인(FQDN) 의 하위 서브 도메인 호스트에 대해서 무제한 적용할수 있는 SSL 인증서 타입 입니다. 최근에 SSL 인증서 발급 약 40% 선이 Wildcard SSL 인증서로 발급이 되고 있으며, 이는 그만큼 효용성이 높다는 것을 증명합니다.

 

이 와일드카드 인증서를 생성하기 위해서는 SSL인증서 발급기관에 의뢰하게 되면 대충 10만원 이상의 비용이 발생한다.

하지만, letsencrypt를 이용하면 무료로 발급할 수 있다.

다만, 3개월에 한번씩 갱신해줘야 하는 단점이 있지만.. 이도 자동으로 갱신 설정을 해놓으면 된다.

 

이제 letsencrypt 로 와일드카드 인증서 생성을 하는 과정을 보자.

 

생성하고자 하는 도메인을 "abcd.com" 이라고 하자.

여기에 *.abcd.com 을 운영을 위해 와일드카드(wildcard) SSL 인증서를 만들어 보자.

[root@svr ~]# certbot certonly --manual --preferred-challenges dns -d "*.abcd.com" -d "abcd.com"

Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
You have an existing certificate that contains a portion of the domains you
requested (ref: /etc/letsencrypt/renewal/abcd.com.conf)

It contains these names: abcd.com

You requested these names for the new certificate: *.abcd.com,
abcd.com.

Do you want to expand and replace this existing certificate with the new
certificate?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(E)xpand/(C)ancel: E
Renewing an existing certificate for *.abcd.com and abcd.com
Performing the following challenges:
dns-01 challenge for abcd.com
dns-01 challenge for abcd.com

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

0l5sfzMfdL7gpoQaEbssassdfaIMqWNdf0o4drAZmmQasdfR9Smd

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

위에서 확인된 DNS TXT값을 도메인관리 기관에서 해당 도메인의 TXT값으로 추가해준다.

호스트값 : _acme-challenge 

값 : 0l5sfzMfdL7gpoQaEbssassdfaIMqWNdf0o4drAZmmQasdfR9Smd

 

위 두개 값으로 dns관리에 추가해준다. 추가 dns에 적용이 된 후 이후 작업을 해야 하니,

아래 url에서 dns txt가 적용이 되었는지 확인을 해본다.
https://toolbox.googleapps.com/apps/dig/#TXT/_acme-challenge.domain.com
위 페이지에 접속해 조회할 도메인 정보를 입력하고 TXT 결과값을 확인해본다.
txt 결과값이 나오면 인증서 신청 화면에서 엔터를 치고,

두번째 TXT값을 확인한다.

 

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

8aOhySsbHUSKTsdfnDa9qwOstslSjlewLRjNx10cpsRqqaW

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.)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue


첫번째 TXT값과 동일한 등록 작업을 하고, dns txt값이 잘 나오는지 확인한 후 에 엔터를 친다.



IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/abcd.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/abcd.com/privkey.pem
   Your certificate will expire on 2024-03-11. 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

letsencrypt wildcard 인증서가 모두 생성이 되면 위와 같은 마지막 메세지가 나온다.

여기에서 위에 붉은색 부분을 이제 웹서버의 ssl vhost 설정에 추가해 주면 된다.


SSLCertificateFile /etc/letsencrypt/live/abcd.com/cert.pem
SSLCertificateKeyFile /etc/letsencrypt/live/abcd.com/privkey.pem
SSLCertificateChainFile /etc/letsencrypt/live/abcd.com/fullchain.pem

 

ssl vhost의 해당 도메인 부분에 위 인증서 정보를 추가해주고, 웹서버를 재시작 해주면 된다.

 

 

Support EFF's Work on Let's Encrypt

Protect digital privacy and free expression. The Electronic Frontier Foundation's public interest legal work, activism, and software development preserve fundamental rights.  EFF is a U.S. 501(c)(3) nonprofit,...

supporters.eff.org

 

 

 

certbot 갱신 실패 - apache plugin 오류

인증서 갱신일이 얼마 안남았다고 인증서 생성시 지정한 메일로 알림 메일을 받았다.
자동으로 갱신하도록 크론탭에 작성을 해놨었는데....
수동으로 확인을 해보니.. 아래와 같은 내용이 출력되며 갱신 실패.

[root@kidd ~]# /usr/bin/certbot renew
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/AAAA.co.kr.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not yet due for renewal

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/BBBB.co.kr.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert is due for renewal, auto-renewing...
Could not choose appropriate plugin: The requested apache plugin does not appear to be installed
Failed to renew certificate kidd.co.kr with error: The requested apache plugin does not appear to be installed

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/CCCC.co.kr.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not yet due for renewal

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/www.AAAA.co.kr.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert not yet due for renewal

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
The following certificates are not due for renewal yet:
  /etc/letsencrypt/live/AAAA.co.kr/fullchain.pem expires on 2023-01-27 (skipped)
  /etc/letsencrypt/live/BBBB.co.kr/fullchain.pem expires on 2023-02-17 (skipped)
  /etc/letsencrypt/live/www.AAAA.co.kr/fullchain.pem expires on 2023-02-03 (skipped)
All renewals failed. The following certificates could not be renewed:
  /etc/letsencrypt/live/BBBB.co.kr/fullchain.pem (failure)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1 renew failure(s), 0 parse failure(s)


내용인 즉, apache plugin이 설치가 안되었다는 거 같은데...
letsencrypt 설치할때.. 그런거를 못봤던거 같고. 
인증서 생성시 생성 옵션이 뭔가 이전보다 적었다는거... 그정도 생각이 떠오른다..

구글신에게 물어보니...
"The requested apache plugin does not appear to be installed" 이 질문에 대한 여러 답변중에
python 관련 apache plugin을 설치하라는거가 있었다.
"python2-certbot-apache" - CentOS 7"python3-certbot-apache" - CentOS 8

현재 설치된 letsencrypt 의 plugin을 확인해보니, 아래와 같다.

[root@~]# certbot plugins
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* standalone
Description: Spin up a temporary webserver
Interfaces: IAuthenticator, IPlugin
Entry point: standalone = certbot._internal.plugins.standalone:Authenticator

* webroot
Description: Place files in webroot directory
Interfaces: IAuthenticator, IPlugin
Entry point: webroot = certbot._internal.plugins.webroot:Authenticator
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

역시, apache 어쩌고는 없다.


현재 서버 버젼이 CentOS7 버젼이니, "python2-certbot-apache"를 설치하면 되겠다.
[root@~]# yum install certbot python2-certbot-apache

설치하고 나서 갱신을 해보니, 잘 되고, plugin도 확인해보니, apache plugin이 나온다.

[root@~]# certbot plugins
Saving debug log to /var/log/letsencrypt/letsencrypt.log

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* apache
Description: Apache Web Server plugin
Interfaces: IAuthenticator, IInstaller, IPlugin
Entry point: apache = certbot_apache._internal.entrypoint:ENTRYPOINT

* standalone
Description: Spin up a temporary webserver
Interfaces: IAuthenticator, IPlugin
Entry point: standalone = certbot._internal.plugins.standalone:Authenticator

* webroot
Description: Place files in webroot directory
Interfaces: IAuthenticator, IPlugin
Entry point: webroot = certbot._internal.plugins.webroot:Authenticator
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


결론, 
letsencrypt 를 설치하고 인증서 생성시 apache 옵션이 안보이거나,
인증서 갱신시 apache plugin 어쩌고 하는 빨간색 오류줄이 보이면,
주저없이 OS버젼에 맞게 python2-certbot-apache를 설치해주면 된다.

 

letsencrypt 설치시 처음부터 apache plugin까지 설치하면 더 좋겠다.

[root@~] yum install certbot python2-certbot-apache 

letsencrypt ssl인증서 갱신, 생성 오류 사례

신규 인증서 생성시 아래와 같은 오류 발생 대처
에러1 -------------------------
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
An unexpected error occurred:
TypeError: __str__ returned non-string (type Error)
Please see the logfiles in /var/log/letsencrypt for more details.
해결 -------------------------
pip install urllib3==1.26.7
pip install requests==2.11.1



에러2 --------------------------
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
An unexpected error occurred:
SSLError: ("bad handshake: Error([('SSL routines', 'ssl3_get_server_certificate', 'certificate verify failed')],)",)

해결 ---------------------------
# --no-verify-ssl 옵션을 추가해서 생성한다. 
certbot certonly --no-verify-ssl

letsencrypt 인증서 다른서버로 복사하기

letsencrypt 인증서 생성 후 서버를 이전 또는 이중화 하는 경우가 있을것이다.

이때 기존 생성한 인증서를 복사한 방법은 아래와 같다.

 

우선 인증서가 설치된 위치로 이동한다.

cd /etc/letsencrypt

이동 후 하위의 디렉토리들을 확인하고, 하위 디렉토리중 

인증서 정보, 설정 정보, 갱신정보가 있는

"archarchive", "live", "renewal", "renewal-hooks" 를 복사한다.

이때, 특정 도메인만 하겠다고 하면 해당 도메인 인증서만 복사한다.

 

두번째로 기존 인증서에 사용하는 계정정보(account)를 확인해 둔다.

이 부분이 중요한데, 다른서버에서 계정정보가 다르기 때문에 타겟 서버에 이동후 인증서 파일정보에 있는 계정을 타켓서버에 맞게 변경을 해줘야 한다.

 

타겟서버에서도 letsencrypt의 인증서 계정정보를 확인한다.

ls /etc/letsencrypt/accounts/acme-v02.api.letsencrypt.org/directory/

위와 같이 하거나, 타겟서버에서 생성된 인증서가 있다면 해당 인증서의 설정 파일을 열어 확인해도 된다.

 

복사한 원본 letsencrypt 인증서를 타겟서버에 복사한다.

 

마지막으로 복사한 인증서 정보에서 account 를 변경해 준다.

sed -i 's/old계정/new계정/' /etc/letsencrypt/renewal/*

 

참고 url : community.letsencrypt.org/t/copy-etc-letsencrypt-or-regenerate-to-move/141684/3

 

letsencrypt ssl인증서 만료 갱신 오류 해결 - webroot 관련

ssl인증서는 최근 웹서비스에서는 필요불가결한 서비스이다.

여러 웹서비스를 운영할 경우 상당히 많은 부분에 ssl 인증서가 필요하다 보니 비용 문제에 직면하게 된다.

 

그래서, 무료로 사용이 가능한 letsencrypt 인증서를 많이들 사용하는데....

잘만 관리해주면 상당히 괞찮은 ssl 적용 방법이라고 생각된다.

 

다만, 가끔씩 갱신이 잘 안된다거나, 갱신 오류가 발생하기도 하는데...

오늘은 아래와 같은 오류에 대해서 해결하는 방법을 공유해 본다.

 

 

letsencrypt ssl 인증서 갱신하기

 

우선, 인증서를 적용하는 도메인을 aaaa.bbbb.kr 이라고 가정하고..

 

리눅스 크론탭(crontab)에 통해 매달 2일정도 갱신을 시도하도록 스케줄링을 적용해 놓았다.

# letsencrypt renew
00 5 10,16 * * root /root/letsencrypt/certbot-auto renew >> /var/log/letsencrypt/renew.log

 

그런데, 확인을 해보니, 인증서 만료일이 갱신되지 못하고 실패가 나고 있었다.

그래서, 직접 갱신 시도를 해보았다.

 

#cd /root/letsencrypt

#./certbot-auto renew

 

갱신을 실행해 보니, 아래와 같은 메세지가 출력되었다.

 

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

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/aaaa.bbbb.kr.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert is due for renewal, auto-renewing...
Plugins selected: Authenticator webroot, Installer None
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for aaaa.bbbb.kr
Cleaning up challenges
Attempting to renew cert (aaaa.bbbb.kr) from /etc/letsencrypt/renewal/aaaa.bbbb.kr.conf produced an unexpected error: Missing command line flag or config entry for this setting:
Input the webroot for aaaa.bbbb.kr:. Skipping.
All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/aaaa.bbbb.kr/fullchain.pem (failure)

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

All renewal attempts failed. The following certs could not be renewed:
  /etc/letsencrypt/live/aaaa.bbbb.kr/fullchain.pem (failure)
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1 renew failure(s), 0 parse failure(s)

 

내용을 보니, 뭔가 수정을 하라는거 같은데....

오류 내용에 뭔가 빠져 있다고 하는거 같고... 그게 webroot 와 관련되는거 같고...

그래서 구글링을 통해 확인을 해보니...

configuration 파일(/etc/letsencrypt//renewal/aaaa.bbbb.kr.conf)에 webroot 정보가 빠져서 그렇다고 한다.

 

설정파일을 열어 확인해보니, 해당 부분이 없서 추가 해주었다.

 

#vi /etc/letsencrypt/renewal/aaaa.bbbb.kr.conf

# renew_before_expiry = 30 days
version = 0.38.0
archive_dir = /etc/letsencrypt/archive/aaaa.bbbb.kr
cert = /etc/letsencrypt/live/aaaa.bbbb.kr/cert.pem
privkey = /etc/letsencrypt/live/aaaa.bbbb.kr/privkey.pem
chain = /etc/letsencrypt/live/aaaa.bbbb.kr/chain.pem
fullchain = /etc/letsencrypt/live/aaaa.bbbb.kr/fullchain.pem

# Options used in the renewal process
[renewalparams]
server = https://acme-v02.api.letsencrypt.org/directory
authenticator = webroot
account = asdfasfasfasfdasfdasfdasfdasdfa

 

설정 파일 내용을 보면, webroot에 대한 정보가 없다.

그래서, aaaa.bbbb.kr 에 대한 웹루트(/webroot/aaaa.bbbb.kr) 정보를 설정 파일 하단에 추가 주었다.

 

[[webroot_map]]
aaaa.bbbb.kr = /webroot/aaaa.bbbb.kr

 

 

이렇게 수정을 마치고, 다시 갱신 시도를 해보니 오류 없이 잘 되었다.

 

#./certbot-auto renew

 

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

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/aaaa.bbbb.kr.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert is due for renewal, auto-renewing...
Plugins selected: Authenticator webroot, Installer None
Renewing an existing certificate
Performing the following challenges:
http-01 challenge for aaaa.bbbb.kr
Waiting for verification...
Cleaning up challenges

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
new certificate deployed without reload, fullchain is
/etc/letsencrypt/live/aaaa.bbbb.kr/fullchain.pem
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

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

Congratulations, all renewals succeeded. The following certs have been renewed:
  /etc/letsencrypt/live/aaaa.bbbb.kr/fullchain.pem (success)