Certbot có thể dễ dàng tạo SSL cho domain và tất cả subdomain của nó, nhưng khi renew lại bị báo lỗi.
Chúng ta có thể khắc phục việc này bằng cách tạo script manual_auth_hook và manual_cleanup_hook.
- manual_auth_hook (dấu _ thay vì dấu – như trên command line) giúp tạo record _acme-challenge.$CERTBOT_DOMAIN với giá trị $CERTBOT_VALIDATION để certbot chứng thực chủ domain
- manual_cleanup_hook giúp xóa record _acme-challenge.$CERTBOT_DOMAIN khi đã tạo xong SSL
Khi certbot renew bao nhiêu domain thì các script trên được gọi bấy nhiêu lần, vì vậy việc tối ưu thời gian chờ record _acme-challenge có hiệu lực trên internet rất có ý nghĩa.
Chú ý các script này sử dụng API của cloudflare nên chỉ có giá trị với domain đặt ở cloudflare.com
Chúng ta cần dùng dig, cài đặt nếu chưa có
apt-get install -y dnsutils
#!/bin/bash
# certbot_auth.cf
# Create challenge record on cloudflare
# © 2020 LNT <lnt@ly-le.info>
# version 20221010
#
# Get your API key from https://www.cloudflare.com/a/account/my-account
#
AUTH_EMAIL='you@mail'
AUTH_KEY='abc...'
DOMAIN=$(expr match "$CERTBOT_DOMAIN" '.*\.\(.*\..*\)')
[ -z "$DOMAIN" ] && DOMAIN=$CERTBOT_DOMAIN
H1="X-Auth-Email:$AUTH_EMAIL"
H2="X-Auth-Key:$AUTH_KEY"
H3="Content-Type:application/json"
URL="https://api.cloudflare.com/client/v4/zones"
CLG="_acme-challenge.$CERTBOT_DOMAIN"
VL="$CERTBOT_VALIDATION"
# Lấy zone id
ZID=$(curl -s -G -H "$H1" -H "$H2" -H "$H3" "$URL?name=$DOMAIN" \
| python -c "import sys,json;print(json.load(sys.stdin)['result'][0]['id'])")
# Tạo challenge record và lấy record id
RID=$(curl -s -X POST -H "$H1" -H "$H2" -H "$H3" "$URL/$ZID/dns_records" \
--data '{"type":"TXT","name":"'"$CLG"'","content":"'"$VL"'","ttl":120}' \
| python -c "import sys,json;print(json.load(sys.stdin)['result']['id'])")
# Cất data cho cleanup
TMP="/tmp/CERTBOT_${CERTBOT_DOMAIN}"
[ -d "$TMP" ]||mkdir "$TMP"
echo -n "$H1">$TMP/H1
echo -n "$H2">$TMP/H2
echo -n "$URL/$ZID/dns_records/$RID">$TMP/URL
# Chờ challenge record có hiệu lực trên internet
for t in {1..90}; do
[ -z "$(dig @8.8.8.8 $CLG TXT | grep -Po '"'$VL'"')" ] && sleep 1 || exit 0
done
exit 1
#!/bin/bash
# certbot_cleanup.cf
# Remove challenge record on cloudflare
# © 2020 LNT <lnt@ly-le.info>
# version 20221010
#
TMP="/tmp/CERTBOT_${CERTBOT_DOMAIN}"
[ -e "$TMP/H1" ] && H1="$(<"$TMP/H1")"
[ -e "$TMP/H2" ] && H2="$(<"$TMP/H2")"
[ -e "$TMP/URL" ] && URL="$(<"$TMP/URL")"
[[ -z $H1 || -z $H2 || -z $URL ]] && exit
H3="Content-Type: application/json"
# Xóa challenge record
ret=$(curl -s -X DELETE -H "$H1" -H "$H2" -H "$H3" "$URL" \
| python -c "import sys,json;print(json.load(sys.stdin)['success'])")
[ "$ret" == 'True' ] && rm -rf "$TMP"
Để sử dụng các script trên cho renew, sửa các file /etc/letsencrypt/renewal/example.com như sau
# renew_before_expiry = 30 days
version = a.x.y
...
# Options used in the renewal process
[renewalparams]
account = aaa...
authenticator = manual
manual_auth_hook = /path/to/certbot_auth.cf
manual_cleanup_hook = /path/to/certbot_cleanup.cf
pref_challs = dns-01,
server = https://acme-v02.api.letsencrypt.org/directory
key_type = rsa
Test các script có hoạt động không
certbot renew --dry-run
Chú thích
- Có thể dùng các script trên để renew bất kỳ tổ hợp domain, subdomain nào với khai báo như trên.
- Để dùng các script trên để tạo mới chứng chỉ SSL với certbot certonly, cần khai báo rõ trên dòng lệnh tương tự như sau:
certbot certonly \
-d example.com -d '*.example.com' \
--manual \
--manual-auth-hook=/path/to/certbot_auth.cf \
--manual-cleanup-hook=/path/to/certbot_cleanup.cf \
--preferred-challenges=dns-01 \
--server https://acme-v02.api.letsencrypt.org/directory
3. namecheap cũng có API, tuy nhiên có điều kiện sử dụng:
In order to have API enabled, your account should meet one of the following requirements:
- have at least 20 domains under your account;
- have at least $50 on your account balance;
- have at least $50 spent within the last 2 years.
Ngoài ra, API của namecheap cập nhật một lần tất cả DNS record, không thể cập nhật riêng lẻ các record cần thiết mà thôi. Xem tại đây