讓 Certbot 可以每90天自動更新 Let’s Encrypt 憑證

三年前 使用 Certbot 來為網站申請 Let’s Encrtpt 憑證 (CentOS 7),解決了網站需要加解密傳輸的問題,但憑證僅有90天的有效期,所以每隔90天便得重新申請憑證。

如果我若能(1)更新憑證(非重新申請),且(2)每90天期限一到,便能自動更新憑證,那就太好了。

(1)更新網站憑證(非手動重新申請)

依據 certbot 的功能,只要輸入 sudo certbot renew ,便可以更新憑證。

但我一開始在輸入之後,出現以下錯誤訊息:

Failed to renew certificate yowlab.idv.tw with 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.’)

 

原來是我的網站(yowlab.idv.tw)使用了手動方式來獲取證書,而憑證更新時,Certbot 需要一個身份驗證腳本來證明我對我的網域名稱(yowlab.idv.tw)擁有控制權。

適合我的解決方法:
sudo certbot renew –manual-auth-hook /etc/letsencrypt/renewal/auth-hook.sh

但是,什麼是「auth-hook.sh」?系統裡面並沒有這個東西!

既然沒有這個檔案,我就自己來新增一個,因為我是使用「HTTP 驗證」方式來申請憑證,所以 auth-hook.sh 內容如下:

#!/bin/bash

# 確保傳入了所有必要的環境變數
if [ -z "$CERTBOT_TOKEN" ] || [ -z "$CERTBOT_VALIDATION" ] || [ -z "$CERTBOT_DOMAIN" ]; then
    echo "缺少必要的環境變數" >&2
    exit 1
fi

# 設定 Web 服務器根目錄,依據自己網站目錄來做設定
WEBROOT="/var/www/html"

# 創建驗證文件
mkdir -p "$WEBROOT/.well-known/acme-challenge"
echo "$CERTBOT_VALIDATION" > "$WEBROOT/.well-known/acme-challenge/$CERTBOT_TOKEN"

# 給予足夠的時間讓變更生效
sleep 10

echo "HTTP 驗證文件已創建"

 

在新增「auth-hook.sh」檔案與執行 sudo certbot renew –manual-auth-hook /etc/letsencrypt/renewal/auth-hook.sh 後,便可以達成更新憑證目的。

但若將 manual_auth_hook = /etc/letsencrypt/renewal/auth-hook.sh 這一行放入設定檔: /etc/letsencrypt/renewal/(域名).conf 裡面,便能簡化成只要輸入: sudo certbot renew ,便可以達成更新憑證目的。

 

(2)每90天,自動自動更新憑證

要達成每90天,自動自動更新憑證這一件事,簡單說,只要讓 cron 每 90 天執行一次 sudo certbot renew 動作就好。

問題是~ /etc/crontab 並無法做出每90天執行一次的設定。

而可以達成這個目標的方法有不少,我採用以下方法。

  1. 先建立一個判斷是否 90天期限已到的程式: run_every_90_days.sh
  2. #!/usr/bin/bash
    
    LAST_RUN_FILE="/etc/letsencrypt/renewal/last_run_file"
    CURRENT_TIME=$(date +%s)
    
    if [ ! -f "$LAST_RUN_FILE" ]; then
        # 如果文件不存在,創建它並執行命令
        echo $CURRENT_TIME > "$LAST_RUN_FILE"
        /usr/bin/certbot renew 
    else
        LAST_RUN_TIME=$(cat "$LAST_RUN_FILE")
        DAYS_SINCE_LAST_RUN=$(( ($CURRENT_TIME - $LAST_RUN_TIME) / 86400 ))
        
        if [ $DAYS_SINCE_LAST_RUN -ge 90 ]; then
            # 如果距離上次執行已經過了 90 天或更長時間,執行命令
            echo $CURRENT_TIME > "$LAST_RUN_FILE"
           /usr/bin/certbot renew 
        fi
    fi
    

     

  3. 再到 /etc/crontab 設定每天凌晨0時定時執行
  4. 0 0 * * * root /etc/letsencrypt/renewal/run_every_90_days.sh

     

  5. 最後記得重新啟動 cron 服務,好讓系統能夠記得執行。
  6. sudo service cron restart

     

補充事項

  1. 「certbot renew –dry-run」,模擬憑證更新動作
  2. 在做憑證更新時:「certbot renew」,可以先下:「certbot renew –dry-run」,模擬憑證更新是否正確,以免發生不容易挽回的錯誤。

  3. 「certbot certificates」,可以觀看目前憑證狀況。
  4. 憑證更新完成後,記得要將所有與憑證有相關的服務重新啟動。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

*