Let's Encrypt 免費 SSL 憑證申請與自動續約

How to obtain free SSL certificates from Let's Encrypt using Certbot and configure automatic renewal

Let’s Encrypt 是一個免費、自動化且開放的憑證頒發機構(CA),讓任何人都能輕鬆為網站啟用 HTTPS。本文將介紹如何使用 Certbot 工具申請 SSL 憑證並設定自動續約。

Let’s Encrypt 簡介

什麼是 Let’s Encrypt?

Let’s Encrypt 是由網際網路安全研究小組(ISRG)運營的非營利憑證頒發機構,自 2016 年正式上線以來,已為數百萬個網站提供免費的 SSL/TLS 憑證。

主要特點

特點說明
免費完全免費,無任何隱藏費用
自動化支援自動申請與續約
安全使用業界標準的加密技術
透明所有憑證都會公開記錄
開放開放原始碼,任何人都能使用

憑證有效期限

Let’s Encrypt 憑證有效期為 90 天,官方建議每 60 天更新一次。這種短效期設計有助於:

  • 降低私鑰洩漏的風險
  • 促進自動化更新機制的採用
  • 加快憑證撤銷的反應速度

Certbot 安裝

Certbot 是 Let’s Encrypt 官方推薦的憑證管理工具,支援多種作業系統和網頁伺服器。

Ubuntu/Debian 系統

首先更新系統套件庫:

1
sudo apt update

安裝 Certbot 和網頁伺服器外掛:

1
2
3
4
5
# 如果使用 Nginx
sudo apt install certbot python3-certbot-nginx -y

# 如果使用 Apache
sudo apt install certbot python3-certbot-apache -y

CentOS/RHEL 系統

啟用 EPEL 儲存庫並安裝:

1
2
3
4
5
6
7
# CentOS 7
sudo yum install epel-release -y
sudo yum install certbot python3-certbot-nginx -y

# CentOS 8/RHEL 8
sudo dnf install epel-release -y
sudo dnf install certbot python3-certbot-nginx -y

使用 Snap 安裝(推薦)

Snap 提供最新版本的 Certbot:

1
2
3
4
5
6
7
8
# 安裝 Snap
sudo apt install snapd -y

# 安裝 Certbot
sudo snap install --classic certbot

# 建立符號連結
sudo ln -s /snap/bin/certbot /usr/bin/certbot

驗證安裝

確認 Certbot 已正確安裝:

1
certbot --version

申請憑證步驟

前置條件

在申請憑證之前,請確保:

  1. 擁有一個已註冊的網域名稱
  2. 網域的 DNS A 記錄已指向伺服器 IP
  3. 伺服器已開放 80 和 443 連接埠
  4. 已安裝網頁伺服器(Nginx 或 Apache)

方法一:使用網頁伺服器外掛(推薦)

Nginx 外掛

1
sudo certbot --nginx -d example.com -d www.example.com

Apache 外掛

1
sudo certbot --apache -d example.com -d www.example.com

執行後會出現互動式設定,按照提示操作:

  1. 輸入電子郵件地址(用於接收續約通知)
  2. 同意服務條款
  3. 選擇是否將 HTTP 流量重新導向至 HTTPS

方法二:Webroot 驗證

適用於不想讓 Certbot 自動修改網頁伺服器設定的情況:

1
sudo certbot certonly --webroot -w /var/www/html -d example.com -d www.example.com

參數說明:

  • certonly:僅取得憑證,不自動設定
  • --webroot:使用 Webroot 驗證方式
  • -w:指定網站根目錄
  • -d:指定網域名稱

方法三:獨立模式(Standalone)

適用於沒有執行網頁伺服器的情況:

1
2
3
4
5
6
7
8
# 需要先停止佔用 80 埠的服務
sudo systemctl stop nginx

# 申請憑證
sudo certbot certonly --standalone -d example.com -d www.example.com

# 重新啟動服務
sudo systemctl start nginx

方法四:DNS 驗證

適用於無法使用 HTTP 驗證或需要申請萬用字元憑證的情況:

1
sudo certbot certonly --manual --preferred-challenges dns -d example.com -d *.example.com

執行後需要在 DNS 設定中新增 TXT 記錄進行驗證。

憑證存放位置

申請成功後,憑證會存放在以下位置:

檔案路徑說明
憑證檔/etc/letsencrypt/live/example.com/fullchain.pem包含憑證鏈的完整憑證
私鑰檔/etc/letsencrypt/live/example.com/privkey.pem憑證私鑰
憑證/etc/letsencrypt/live/example.com/cert.pem網域憑證
憑證鏈/etc/letsencrypt/live/example.com/chain.pem中繼憑證

手動設定 Nginx SSL

如果使用 certonly 方式取得憑證,需要手動設定 Nginx:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    server_name example.com www.example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    # SSL 安全性設定
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
    ssl_prefer_server_ciphers off;

    # HSTS(HTTP Strict Transport Security)
    add_header Strict-Transport-Security "max-age=63072000" always;

    # 其他設定
    root /var/www/example.com/html;
    index index.html index.htm;

    location / {
        try_files $uri $uri/ =404;
    }
}

測試設定並重新載入:

1
2
sudo nginx -t
sudo systemctl reload nginx

自動續約設定

測試自動續約

Certbot 安裝時會自動設定 Cron 排程或 Systemd Timer。先測試續約是否正常:

1
sudo certbot renew --dry-run

如果測試成功,表示自動續約已正確設定。

檢查 Systemd Timer

在較新的系統上,Certbot 使用 Systemd Timer:

1
2
3
4
5
# 檢查 Timer 狀態
sudo systemctl status certbot.timer

# 查看排程時間
sudo systemctl list-timers | grep certbot

檢查 Cron 排程

在使用 Cron 的系統上:

1
2
# 檢查 Certbot Cron 設定
cat /etc/cron.d/certbot

手動設定 Cron

如果沒有自動設定,可以手動新增:

1
sudo crontab -e

新增以下內容(每天凌晨 3 點和下午 3 點各執行一次):

1
0 3,15 * * * certbot renew --quiet --post-hook "systemctl reload nginx"

設定續約後的動作

如果需要在續約後執行特定動作(如重新載入網頁伺服器):

1
2
# 建立 Hook 腳本
sudo nano /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh
1
2
#!/bin/bash
systemctl reload nginx
1
2
# 設定執行權限
sudo chmod +x /etc/letsencrypt/renewal-hooks/post/reload-nginx.sh

手動更新憑證

如果需要立即更新:

1
sudo certbot renew

強制更新(即使未到期):

1
sudo certbot renew --force-renewal

常見問題排解

問題一:無法驗證網域所有權

錯誤訊息:

1
Failed authorization procedure

解決方案:

  1. 確認 DNS 記錄已正確指向伺服器:

    1
    
    dig +short example.com
    
  2. 確認防火牆已開放 80 和 443 埠:

    1
    2
    3
    
    sudo ufw status
    sudo ufw allow 80
    sudo ufw allow 443
    
  3. 確認網頁伺服器正在執行:

    1
    
    sudo systemctl status nginx
    

問題二:達到申請頻率限制

錯誤訊息:

1
too many certificates already issued for exact set of domains

解決方案:

Let’s Encrypt 有以下頻率限制:

  • 每個註冊網域每週 50 個憑證
  • 每個憑證最多 100 個網域名稱
  • 每個 IP 每 3 小時 10 次失敗驗證

如果遇到限制,請等待一段時間後再試,或使用測試環境:

1
sudo certbot certonly --staging -d example.com

問題三:憑證過期未自動更新

解決方案:

  1. 檢查 Certbot Timer 或 Cron 是否正常運作
  2. 手動執行續約測試:
    1
    
    sudo certbot renew --dry-run
    
  3. 檢查日誌:
    1
    
    sudo cat /var/log/letsencrypt/letsencrypt.log
    

問題四:網頁伺服器設定錯誤

解決方案:

  1. 測試 Nginx 設定:

    1
    
    sudo nginx -t
    
  2. 檢查憑證檔案是否存在:

    1
    
    sudo ls -la /etc/letsencrypt/live/example.com/
    
  3. 確認憑證有效期:

    1
    
    sudo certbot certificates
    

問題五:混合內容警告

說明: 網頁使用 HTTPS 但載入 HTTP 資源。

解決方案:

  1. 將所有資源連結改為 HTTPS 或使用協議相對路徑 (//)
  2. 檢查網頁原始碼中的 HTTP 連結
  3. 使用 CSP(Content Security Policy)強制 HTTPS

常用 Certbot 指令

指令說明
certbot certificates列出所有憑證
certbot renew更新所有憑證
certbot renew --dry-run測試更新流程
certbot delete --cert-name example.com刪除憑證
certbot revoke --cert-path /path/to/cert.pem撤銷憑證

延伸閱讀

參考資料

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy