建立自動化 SSL 憑證監控系統 文章首圖

建立自動化 SSL 憑證監控系統

建立自動化 SSL 憑證監控系統

在現代網路架構中,SSL/TLS 憑證的過期往往被視為「小事」,直到網站出現 ERR_CERT_DATE_INVALID 的警告,導致用戶無法存取,甚至影響企業信譽。對於系統管理員而言,依賴人為記憶來檢查憑證有效期是極高風險的做法。本文将介紹如何在一台 Ubuntu 22.04 或 Debian 12 伺服器上,建立一個輕量級、自動化的 SSL 憑證監控腳本,並透過 cron 定時檢查,確保憑證始終有效。

環境準備與依賴安裝

首先,我們需要一個能夠查詢憑證資訊的工具。雖然許多 Linux 發行版預設已安裝 openssl,但為了確保指令的一致性与可用性,建議先確認其存在。此外,為了讓監控結果更易於閱讀與整合,我們將使用 jq 來處理 JSON 格式的輸出。

sudo apt update
sudo apt install -y openssl jq

安裝完成後,我們可以手動測試一下憑證查詢功能。以下指令將查詢 google.com 的憑證資訊,並透過 jq 過濾出到期日:

echo | openssl s_client -servername google.com -connect google.com:443 2>/dev/null | openssl x509 -noout -enddate

若輸出類似 notAfter=Dec 31 23:59:59 2025 GMT 的結果,表示環境已準備就緒。

編寫監控腳本

接下來,我們建立一個名為 ssl_monitor.sh 的腳本。這個腳本的核心邏輯是:接收主機名與端口作為參數,查詢憑證到期日,計算剩餘天數,若低於閾值則發送警告。

請建立檔案 /usr/local/bin/ssl_monitor.sh

sudo nano /usr/local/bin/ssl_monitor.sh

填入以下內容:

#!/bin/bash

# 設定參數
HOSTNAME=$1
PORT=${2:-443}
WARNING_DAYS=30 # 剩餘天數低於此值時發出警告

# 檢查參數是否提供
if [ -z "$HOSTNAME" ]; then
    echo "用法: $0 <hostname> [port]"
    exit 1
fi

# 獲取憑證到期時間戳記
EXPIRY_DATE=$(echo | openssl s_client -servername "$HOSTNAME" -connect "$HOSTNAME:$PORT" 2>/dev/null | openssl x509 -noout -enddate | cut -d= -f2)

if [ -z "$EXPIRY_DATE" ]; then
    echo "ERROR: 無法獲取 $HOSTNAME 的憑證資訊"
    exit 1
fi

# 將到期時間轉換為 Unix 時間戳記
EXPIRY_EPOCH=$(date -d "$EXPIRY_DATE" +%s)
CURRENT_EPOCH=$(date +%s)

# 計算剩餘天數
REMAINING_DAYS=$(( (EXPIRY_EPOCH - CURRENT_EPOCH) / 86400 ))

# 輸出結果
echo "$HOSTNAME:$PORT - 剩餘天數: $REMAINING_DAYS 天"

# 若剩餘天數小於閾值,則返回錯誤碼以便 cron 記錄或觸發後續動作
if [ $REMAINING_DAYS -lt $WARNING_DAYS ]; then
    echo "WARNING: 憑證即將過期!"
    exit 2
else
    exit 0
fi

賦予腳本執行權限:

sudo chmod +x /usr/local/bin/ssl_monitor.sh

自動化執行與整合

為了讓監控持續運行,我們使用 cron 來定時執行腳本。這裡我們設定每天凌晨 3 點檢查一次。

編輯 cron 表:

crontab -e

在檔案末尾加入以下行:

0 3 * * * /usr/local/bin/ssl_monitor.sh yourdomain.com 443 >> /var/log/ssl_monitor.log 2>&1

注意:將 yourdomain.com 替換為您實際要監控的域名。

為了讓監控更具實用性,我們可以進一步整合郵件通知或 webhook(如 Slack、Telegram)。以 Telegram Bot 為例,您可以在腳本中加入以下邏輯,當 exit 2 時發送訊息:

if [ $REMAINING_DAYS -lt $WARNING_DAYS ]; then
    CHAT_ID="your_chat_id"
    BOT_TOKEN="your_bot_token"
    MESSAGE="警告: $HOSTNAME 的 SSL 憑證僅剩 $REMAINING_DAYS 天!"
    curl -s -X POST "https://api.telegram.org/bot$BOT_TOKEN/sendMessage" \
         -d chat_id="$CHAT_ID" \
         -d text="$MESSAGE"
fi

常見問題與解決方案

1. 腳本執行時出現 "hostname verification failed" 錯誤 這通常發生在憑證的主機名與查詢的主機名不匹配,或是伺服器未正確配置 SNI (Server Name Indication)。確保在 openssl s_client 指令中正確使用了 -servername 參數,並且查詢的域名確實指向該伺服器。

2. 如何監控多個域名? 您可以建立一個包含所有監控目標的檔案 targets.txt,每行一個 hostname:port,然後修改腳本或使用循環來遍歷該檔案。例如:

while IFS=: read -r host port; do
    /usr/local/bin/ssl_monitor.sh "$host" "$port"
done < /etc/ssl_monitor/targets.txt

小結

透過上述步驟,我們建立了一個簡單但強大的 SSL 憑證監控系統。這個方案不需要昂貴的外部服務,僅依賴 Linux 原生工具即可實現自動化檢查。對於中階 Linux 使用者而言,掌握這類基礎監控技能,能有效避免因憑證過期導致的服務中斷,提升系統的穩定性與專業度。建議定期檢視監控日誌,並根據實際需求調整警告閾值與通知方式。