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를 사용하고 있으며,
에서 찾을 수 있었다.
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 |