UFSの備忘録 % Home / Categories

FreeBSD下Let's Encrypt證書安裝

Created 2018-05-29 / Updated 2022-11-23

安裝Certbot:

# pkg install py38-certbot

安裝curl:

# pkg install curl

通過驗證DNS來安裝,好處是即使服務器沒有運行也可以通過驗證,而且支持泛域名(wildcard)。以Cloudflare為例(manual,嫌麻煩的可以裝個certbot-dns-cloudflare):

# mkdir -p $HOME/.secrets/certbot
# vi $HOME/.secrets/certbot/.authinfo
API_KEY="你cf的Global API Key"
EMAIL="你cf的郵箱"
ZONE_ID="你cf的Zone ID"

(「Global API Key」在Cloudflare的「My Profile」頁面獲取,「Zone ID」在你域名的管理頁面獲取)

验证脚本:

# vi $HOME/.secrets/certbot/authenticator.sh
### 內容開始 ###
#!/bin/sh

. $HOME/.secrets/certbot/.authinfo

# Create TXT record
CREATE_DOMAIN="_acme-challenge.$CERTBOT_DOMAIN"
RECORD_ID=$(curl -s -X POST "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
  -H     "X-Auth-Email: $EMAIL" \
  -H     "X-Auth-Key: $API_KEY" \
  -H     "Content-Type: application/json" \
  --data '{"type":"TXT","name":"'"$CREATE_DOMAIN"'","content":"'"$CERTBOT_VALIDATION"'","ttl":120}' \
          | python3.8 -c "import sys,json;print(json.load(sys.stdin)['result']['id'])")

# Save info for cleanup
if [ ! -d /tmp/CERTBOT_$CERTBOT_DOMAIN ];then
    mkdir -m 0700 /tmp/CERTBOT_$CERTBOT_DOMAIN
fi

echo $RECORD_ID >> /tmp/CERTBOT_$CERTBOT_DOMAIN/RECORD_ID

# Sleep to make sure the change has time to propagate over to DNS
sleep 60
### 內容結束 ###

(记得把python3.8替换成你自己的版本)

清理脚本:

# vi $HOME/.secrets/certbot/cleanup.sh
### 內容開始 ###
#!/bin/sh

. $HOME/.secrets/certbot/.authinfo

if [ -f /tmp/CERTBOT_$CERTBOT_DOMAIN/RECORD_ID ]; then
    RECORD_ID=$(cat /tmp/CERTBOT_$CERTBOT_DOMAIN/RECORD_ID)
    rm -f /tmp/CERTBOT_$CERTBOT_DOMAIN/RECORD_ID
fi

# Remove the challenge TXT record from the zone
for i in ${RECORD_ID}
do
    if [ -n "${i}" ]; then
        curl -s -X DELETE "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/${i}" \
                -H "X-Auth-Email: $EMAIL" \
                -H "X-Auth-Key: $API_KEY" \
                -H "Content-Type: application/json"
    fi
done
### 內容結束 ###

更改權限:

# chmod -R 700 $HOME/.secrets
# chmod 600 $HOME/.secrets/certbot/.authinfo

安裝:

# certbot certonly --manual \
  --preferred-challenges=dns \
  --manual-auth-hook $HOME/.secrets/certbot/authenticator.sh \
  --manual-cleanup-hook $HOME/.secrets/certbot/cleanup.sh \
  --server https://acme-v02.api.letsencrypt.org/directory \
  --agree-tos \
  -m 你的郵箱 \
  --no-eff-email \
  -d "example.com" -d "*.example.com"

證書會生成在「/usr/local/etc/letsencrypt/live/你的域名」下。

Let’s Encrypt的證書有效期是3個月,可以設置讓它自動更新:

# vi $HOME/.secrets/certbot/deploy-hook.sh
### 內容開始 ###
#!/bin/sh

chmod 640 /usr/local/etc/letsencrypt/live/example.com/privkey.pem
service nginx restart
### 內容結束 ###

然後:

# crontab -e
0 3 1 */2 * certbot renew --deploy-hook $HOME/.secrets/certbot/deploy-hook.sh

這樣,每隔兩個月的1號3點,就會自動更新證書(deploy-hook.sh這個腳本只有當證書成功更新的時候才會運行)。

附加:Debian下默认会通过systemd自动更新证书,若想禁用,运行:

# systemctl stop certbot.timer
# systemctl disable certbot.timer

想查看該證書的信息,可以用:

# certbot certificates

如果要讓該證書失效,使用:

# certbot revoke \
  --cert-path=/usr/local/etc/letsencrypt/live/example.com/cert.pem

如果提示:

An unexpected error occurred:
The client lacks sufficient authorization :: Revocation request must be signed by private key of cert to be revoked, by the account key of the account that issued it, or by the account key of an account that holds valid authorizations for all names in the certificate.

加上--key-path指定你私鑰的位置即可解決:

# certbot revoke \
  --cert-path=/usr/local/etc/letsencrypt/live/example.com/cert.pem \
  --key-path=/usr/local/etc/letsencrypt/live/example.com/privkey.pem

參考:

Categories: [FreeBSD] [security]