본문 바로가기

Certificates, ssl, tls

Auto Renewal for let's encrypt certificate with wildcard domain

wildcard로 된 domain(*.domain.com)같은 경우 dns challenge를 통해 발급을 받는다.

let's encrypt는 보통 3개월 단위로 갱신을 해줘야하기 때문에 매번 하기 귀찮을 수 밖에 없다. 따라서 crontab같은 job scheduler를 이용하면 편하다.

let's encrypt 인증서는 certbot을 이용하는데 갱신하려면 다음과 같은 명령어를 입력하면 된다.

 

sudo certbot renew

 

하지만 다음과 같은 에러를 얻는다.

 

the error occurs:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Processing /etc/letsencrypt/renewal/<your-domain>.conf
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Cert is due for renewal, auto-renewing...
Could not choose appropriate plugin: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',)
Attempting to renew cert (<your-domain>) from /etc/letsencrypt/renewal/<your-domain>.conf produced an unexpected error: The manual plugin is not working; there may be problems with your existing configuration.
The error was: PluginError('An authentication script must be provided with --manual-auth-hook when using the manual plugin non-interactively.',). Skipping.

 

이는 wildcard로 된 domain은 plugin을 위한 script가 필요하다는 의미이며, 즉 txt record를 자동적으로 실행하기 위한 script를 --manual-auth-hook으로 넘겨주어야 한다는 것이다.

 

따라서 우리는 다음과 같은 명령어를 통해 자동으로 인증서를 갱신하도록 한다.

 

#auto_renewal.sh
sudo certbot -d $SERVER_DOMAIN --agree-tos --register-unsafely-without-email --manual \
--preferred-challenges dns --manual-auth-hook $HOOK_RENEWAL \
--manual-cleanup-hook $HOOK_CLEANUP --manual-public-ip-logging-ok \
--force-renewal certonly

 

crontab을 이용하면

 

crontab -e 0 03 01 */2 * [auto_renewal.sh] [sh_parameter]

 

다음과 같이 매년 2개월 12시마다 auto_renewal.sh를 실행시킨다는 것이다.

 

그렇다면 $HOOK_RENEWAL과 $HOOK_CLEANUP은 어떤 파일이 들어가야 할까?

여러가지 형식이 있지만, 우리는 godaddy라는 domain provider를 사용하고 있으며,

 

https://chariotsolutions.com/blog/post/automating-lets-encrypt-certificate-renewal-using-dns-challenge-type/

 

Automating Let's Encrypt Certificate Renewal using DNS Challenge Type

In the following examples, I'll show how to renew certs with domains hosted on AWS/Route53 and GoDaddy. I run certbot with scripts within a docker container (to simplify automation), however you can use CLI.

chariotsolutions.com

 

에서 찾을 수 있었다.

 

1. renewal.sh

 

#!/bin/bash
GODADDY_API_KEY=[GODADDY_API_KEY]
GODADDY_API_SECRET=[GODADDY_API_SECRET]
GODADDY_URL="https://api.godaddy.com/"
############################################################

# Replace all of a Domain's type of DNS Records

DNS_REC_TYPE=TXT
DNS_REC_NAME="_acme-challenge"
DNS_REC_DATA="$CERTBOT_VALIDATION"
DNS_REC_TTL="600"

IFS='.' read -ra ADDR <<< $CERTBOT_DOMAIN
if [[ ${#ADDR[@]} > 2 ]]; then
        DNS_REC_NAME=`echo $CERTBOT_DOMAIN | cut --delimiter="." -f 1`;
        DNS_REC_NAME=`echo _acme-challenge.$DNS_REC_NAME`;
fi

curl -X PUT \
"${GODADDY_URL}/v1/domains/${CERTBOT_DOMAIN}/records/${DNS_REC_TYPE}/${DNS_REC_NAME}" \
-H  "accept: application/json" -H  "Content-Type: application/json" \
-H  "Authorization: sso-key ${GODADDY_API_KEY}:${GODADDY_API_SECRET}" \
-d "[{ \"data\": \"${DNS_REC_DATA}\", \"name\": \"${DNS_REC_NAME}\", \"ttl\": ${DNS_REC_TTL} }]"

# Sleep to make sure DNS propagates before lets encrypt validates.
sleep 30

 

2. cleanup.sh

 

#!/bin/bash
GODADDY_API_KEY=[GODADDY_API_KEY]
GODADDY_API_SECRET=[GODADDY_API_SECRET]
GODADDY_URL="https://api.godaddy.com/"
############################################################

# Replace all of a Domain's type of DNS Records

DNS_REC_TYPE=TXT
DNS_REC_NAME="_acme-challenge"
DNS_REC_TTL="600"

IFS='.' read -ra ADDR <<< $CERTBOT_DOMAIN
if [[ ${#ADDR[@]} > 2 ]]; then
        DNS_REC_NAME=`echo $CERTBOT_DOMAIN | cut --delimiter="." -f 1`;
        DNS_REC_NAME=`echo _acme-challenge.$DNS_REC_NAME`;
fi

curl -X PUT \
"${GODADDY_URL}/v1/domains/${CERTBOT_DOMAIN}/records/${DNS_REC_TYPE}/${DNS_REC_NAME}" \
-H  "accept: application/json" -H  "Content-Type: application/json" \
-H  "Authorization: sso-key ${GODADDY_API_KEY}:${GODADDY_API_SECRET}" \
-d "[{ \"data\": \"clean\", \"name\": \"${DNS_REC_NAME}\", \"ttl\": ${DNS_REC_TTL} }]"

 

위의 script는 단순하다.

godaddy에서 제공하는 api_key와 api_secret을 가져와서 curl로 data항목에 $CERTBOT_VALIDATIION이라는 VALIDATION TXT RECORD를 넘겨받아 넣어주고, validation후에 clean으로 바꿔주는 것이다.

'Certificates, ssl, tls' 카테고리의 다른 글

(에러)Certbot fails to run hook scripts  (0) 2021.11.15
Certificates and Let's encrypt  (0) 2021.11.15