Linux 伺服器

無需面板申請免費 SSL 證書:Certbot/acme.sh 配置 Nginx、Cloudflare 泛域名證書與自動續期

7 個步驟 11 分鐘閱讀 24 次閱讀 0
本文目錄

部署 HTTPS 並不一定需要控製麵板。使用 Certbot 或 acme.sh,就能為 Nginx 上的任何網站申請 Let's Encrypt 免費證書,通過 Cloudflare DNS API 簽發 *.example.com 這樣的泛域名證書,並實現自動續期。本文介紹在 Debian/Ubuntu 和 Rocky Linux/AlmaLinux 上使用這兩個工具的方法、Nginx 的 HTTPS 配置、開啟了 Cloudflare 代理的網站如何處理,以及如何確認自動續期真正生效。

Let's Encrypt 證書的有效期為 90 天,並且 Let's Encrypt 已於 2025 年停止傳送到期提醒郵件。配置完成後,務必用 dry run(模擬續期)確認自動續期正常,否則證書一旦過期,網站就會在毫無提醒的情況下無法正常訪問。

準備工作

  • 域名的 A 記錄(如使用 IPv6,還包括 AAAA 記錄)已指向伺服器 IP,可用 dig +short example.com 檢查。
  • 伺服器防火牆已放行 80 和 443 埠(參見使用 firewalld 和 ufw 開放埠)。
  • 已安裝 Nginx,並且網站已能通過 HTTP 正常訪問。

方式 A:Certbot + Nginx 外掛(最簡單)

Certbot 可以自動申請證書並修改 Nginx 的 server 配置塊,包括設定 HTTP 跳轉 HTTPS。

# Debian / Ubuntu
apt update
apt install -y certbot python3-certbot-nginx

# Rocky Linux / AlmaLinux (EPEL)
dnf install -y epel-release
dnf install -y certbot python3-certbot-nginx

# Request and install a certificate for the domain and www
certbot --nginx -d example.com -d www.example.com \
  --agree-tos -m [email protected] --redirect

# Renewal is scheduled automatically; confirm the timer and run a test renewal
systemctl list-timers | grep -i certbot
certbot renew --dry-run

證書儲存在 /etc/letsencrypt/live/example.com/ 目錄下。如果不希望 Certbot 改動你的 Nginx 配置檔案,可以使用 certbot certonly --nginx -d example.com,然後按照下文“Nginx HTTPS 配置”自行新增證書路徑。

方式 B:acme.sh(輕量,無需 Python)

acme.sh 是一個以 cron 任務方式執行的 Shell 指令碼。注意它預設的證書頒發機構(CA)是 ZeroSSL,如有需要可以切換為 Let's Encrypt。

# Install (creates ~/.acme.sh and a daily cron job)
curl https://get.acme.sh | sh -s [email protected]
source ~/.bashrc

# Use Let's Encrypt as the default CA
acme.sh --set-default-ca --server letsencrypt

# Issue using your site's web root (HTTP-01 validation)
acme.sh --issue -d example.com -d www.example.com -w /var/www/example

# Install the certificate where Nginx expects it and reload Nginx on every renewal
mkdir -p /etc/nginx/ssl
acme.sh --install-cert -d example.com \
  --key-file       /etc/nginx/ssl/example.com.key \
  --fullchain-file /etc/nginx/ssl/example.com.crt \
  --reloadcmd      "systemctl reload nginx"

不要讓 Nginx 直接引用 ~/.acme.sh 目錄中的檔案;請始終使用 --install-cert,它會複製證書檔案,並在每次續期後執行過載命令。

通過 Cloudflare DNS API 簽發泛域名證書

泛域名證書(*.example.com)必須使用 DNS 驗證。如果域名使用 Cloudflare DNS,請在 Cloudflare 控制臺的 My Profile → API Tokens 中,使用“Edit zone DNS”模板建立 API 令牌,並將許可權限定在需要的域名(zone)上。

# acme.sh: dns_cf reads the token from the environment and saves it for renewals
export CF_Token="your-cloudflare-api-token"
export CF_Zone_ID="your-zone-id"        # shown on the domain's Overview page in Cloudflare
acme.sh --issue --dns dns_cf -d example.com -d '*.example.com'

# Certbot alternative
apt install -y python3-certbot-dns-cloudflare
mkdir -p ~/.secrets && chmod 700 ~/.secrets
echo 'dns_cloudflare_api_token = your-cloudflare-api-token' > ~/.secrets/cloudflare.ini
chmod 600 ~/.secrets/cloudflare.ini
certbot certonly --dns-cloudflare \
  --dns-cloudflare-credentials ~/.secrets/cloudflare.ini \
  -d example.com -d '*.example.com'

即使 80 埠未開放或網站暫時無法訪問,DNS 驗證同樣可以完成,因此也適用於內部服務和新開通的伺服器。

Nginx HTTPS 配置

如果使用 certonly 或 acme.sh 簽發證書,需要自行新增 HTTPS 的 server 配置塊。請根據所用工具調整證書路徑。

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    http2 on;                      # Nginx 1.25.1+; older versions: "listen 443 ssl http2;"
    server_name example.com www.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;   # acme.sh: /etc/nginx/ssl/example.com.crt
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;     # acme.sh: /etc/nginx/ssl/example.com.key
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_session_cache shared:SSL:10m;

    root /var/www/example;
    index index.html index.php;
}
nginx -t && systemctl reload nginx

開啟 Cloudflare 代理的網站

開啟橙色雲朵(代理)後,HTTP 驗證通常仍然可用,因為 Cloudflare 會把 /.well-known/acme-challenge/ 請求轉發到你的伺服器。源站擁有有效證書後,請將 Cloudflare 的 SSL/TLS 加密模式設定為 Full (strict)(完全/嚴格);“Flexible”(靈活)模式下 Cloudflare 到源站的流量不加密,而且經常導致重定向迴圈。也可以改用 DNS 驗證;如果網站只通過 Cloudflare 訪問,還可以使用免費的 Cloudflare Origin Certificate(源伺服器證書)。如需防止訪客繞過 Cloudflare 直接訪問源站,請參見隱藏源站 IP。

檢查證書到期時間與續期

# Expiry date of the certificate your site actually serves
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates

# Certbot: all certificates and their expiry
certbot certificates

# acme.sh: list certificates and force a test renewal
acme.sh --list
acme.sh --renew -d example.com --force

常見問題

驗證失敗,提示“Timeout during connect”或 404 錯誤?

原因通常是 80 埠被攔截、DNS 記錄指向了其他地址,或者有其他 server 配置塊響應了該域名。請檢查防火牆,執行 dig +short example.com,並確認 Nginx 配置中沒有對 /.well-known/acme-challenge/ 做重定向或拒絕訪問。如果仍然不行,請改用 DNS 驗證。

測試時觸發了頻率限制?

Let's Encrypt 限制了同一組域名每週可簽發的證書數量。除錯期間請使用 --dry-run(Certbot)或 --staging(acme.sh),確認配置無誤後再申請正式證書。

一張證書能用於多個域名嗎?

可以。每個域名單獨加一個 -d 引數即可。泛域名只匹配一級子域名,因此 *.example.com 能匹配 shop.example.com,但不能匹配 a.shop.example.com 或 example.com 本身;主域名需要單獨新增。

如果按以上步驟操作後問題仍未解決,請提交工單聯絡 IMIDC 7×24 技術支援,並附上伺服器 IP、系統版本、域名、執行過的命令和完整報錯資訊,方便工程師快速定位。

這篇文章有幫助嗎?

相關教程