本指南帶你完成在 Nginx 上安裝 SSL 證書的全過程——從上傳檔案到最佳化 TLS 設定和排查常見錯誤。適用於來自 GetHTTPS、Certbot 或任何其他來源的證書。
如果你還沒有證書,5 分鐘內免費獲取一個。
前提條件
- Nginx 已安裝並在 HTTP(埠 80)上提供網站服務
- Root/sudo 訪問許可權
- 證書檔案 — 你需要兩個:
fullchain.pem— 你的證書 + 中間證書鏈(合併)privkey.pem— 你的私鑰
哪個檔案是哪個? GetHTTPS 給你四個檔案。Nginx 需要
fullchain.pem(不是cert.pem)和privkey.pem。單獨使用cert.pem會導致”證書鏈不完整”錯誤,因為瀏覽器無法驗證信任路徑。證書格式詳解 →
第一步:上傳證書檔案到伺服器
將檔案複製到安全目錄:
# Create directory
sudo mkdir -p /etc/ssl/gethttps
# Copy files (from your local machine to the server)
sudo cp fullchain.pem /etc/ssl/gethttps/
sudo cp privkey.pem /etc/ssl/gethttps/
# Restrict private key permissions — only root should read it
sudo chmod 600 /etc/ssl/gethttps/privkey.pem
sudo chmod 644 /etc/ssl/gethttps/fullchain.pem
sudo chown root:root /etc/ssl/gethttps/*
如果透過 SCP 傳輸:
scp fullchain.pem privkey.pem user@your-server:/tmp/
# Then on the server:
sudo mv /tmp/fullchain.pem /tmp/privkey.pem /etc/ssl/gethttps/
第二步:配置 HTTPS server 塊
編輯你網站的 Nginx 配置。檔案通常位於:
/etc/nginx/sites-available/yourdomain.conf(Debian/Ubuntu)/etc/nginx/conf.d/yourdomain.conf(CentOS/RHEL)
完整推薦配置:
# HTTPS server block
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name example.com www.example.com;
# ─── Certificate files ───────────────────────
ssl_certificate /etc/ssl/gethttps/fullchain.pem;
ssl_certificate_key /etc/ssl/gethttps/privkey.pem;
# ─── TLS protocol and ciphers ────────────────
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
# ─── Session caching (performance) ───────────
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
# ─── OCSP stapling (faster verification) ─────
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# ─── Security headers ────────────────────────
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
# ─── Your site ───────────────────────────────
root /var/www/html;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
# HTTP redirect block
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
各部分說明:
| 指令 | 用途 |
|---|---|
listen 443 ssl http2 | 埠 443 上的 HTTPS,啟用 HTTP/2 |
ssl_certificate | 證書 + 證書鏈的路徑 |
ssl_certificate_key | 私鑰的路徑 |
ssl_protocols | 僅 TLS 1.2 和 1.3(1.0/1.1 自 2020 年起已棄用) |
ssl_prefer_server_ciphers off | 讓用戶端選擇最佳加密套件(現代最佳實踐) |
ssl_session_cache | 快取 TLS 會話——回訪使用者無需重新握手 |
ssl_session_tickets off | Tickets 可能削弱前向保密 |
ssl_stapling | 伺服器預取 OCSP 響應——對用戶端更快 |
Strict-Transport-Security | HSTS — 瀏覽器記住始終使用 HTTPS |
return 301 | HTTP 到 HTTPS 的永久重新導向 |
第三步:測試配置
重新載入前務必測試:
sudo nginx -t
預期輸出:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
如果測試失敗,Nginx 會告訴你確切的行號和錯誤。常見錯誤:
- 檔案路徑中的拼寫錯誤(
ssl_certifcate而不是ssl_certificate) - 指定路徑的檔案不存在
- 缺少分號
第四步:重新載入 Nginx
sudo systemctl reload nginx
使用 reload,不是 restart。 Reload 將新配置應用到新連線而不斷開現有連線——零停機。
第五步:驗證證書
瀏覽器檢查
訪問 https://yourdomain.com。點選鎖頭圖示確認:
- 簽發者:“Let’s Encrypt”(或你的憑證授權機構)
- 有效期:起止日期
- 域名:與你的 URL 匹配
命令列檢查
# Full certificate details
echo | openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null \
| openssl x509 -noout -subject -issuer -dates -ext subjectAltName
# Check the full chain is present
echo | openssl s_client -connect yourdomain.com:443 -servername yourdomain.com 2>/dev/null \
| grep -E 'Verify return code|depth='
預期: Verify return code: 0 (ok) 和多個深度級別(你的證書 + 中間證書)。
線上檢查
使用 SSL Labs Server Test 獲取全面報告。它檢查:
- 證書鏈有效性
- 協議支援(應該只顯示 TLS 1.2 + 1.3)
- 加密套件強度
- 已知漏洞(BEAST、POODLE、Heartbleed)
- HSTS 配置
目標: 等級 A 或 A+。
如何續簽
當你的證書即將過期時(Let’s Encrypt 的第 60 天/共 90 天):
- 從 GetHTTPS(或你的續簽工具)獲取新證書
- 替換檔案:
sudo cp new-fullchain.pem /etc/ssl/gethttps/fullchain.pem sudo cp new-privkey.pem /etc/ssl/gethttps/privkey.pem - 重新載入 Nginx:
sudo systemctl reload nginx
無需重啟。Nginx 在 reload 時讀取新檔案。完整續簽指南 →
想要自動續簽? 安裝 Certbot 實現免管理續簽:
sudo certbot --nginx -d example.com。它處理一切包括 Nginx 配置。
故障排查
”SSL: error:0B080074:x509 certificate routines”
原因: 你使用了 cert.pem 而不是 fullchain.pem。
修復: 將 ssl_certificate 改為指向 fullchain.pem,它包含你的證書和中間證書鏈:
ssl_certificate /etc/ssl/gethttps/fullchain.pem; # NOT cert.pem
“cannot load certificate key”
原因: 私鑰檔案許可權錯誤、檔案損壞或金鑰與證書不匹配。
修復:
# Check permissions (should be 600)
ls -la /etc/ssl/gethttps/privkey.pem
# Verify the key is valid
sudo openssl ec -in /etc/ssl/gethttps/privkey.pem -check # For ECDSA
sudo openssl rsa -in /etc/ssl/gethttps/privkey.pem -check # For RSA
# Verify key matches certificate
sudo openssl x509 -noout -modulus -in /etc/ssl/gethttps/fullchain.pem | md5sum
sudo openssl rsa -noout -modulus -in /etc/ssl/gethttps/privkey.pem | md5sum
# Both hashes MUST match
“nginx: [emerg] bind() to 0.0.0.0:443 failed”
原因: 埠 443 已被另一個程序佔用。
修復:
# Find what's using port 443
sudo ss -tlnp | grep 443
# Usually: another Nginx instance or Apache
sudo systemctl stop apache2 # If Apache is running
sudo systemctl reload nginx
HTTPS 正常但瀏覽器顯示”不安全”
原因: 混合內容——你的頁面透過 http:// 載入圖片、指令碼或 CSS。
修復: 開啟 DevTools(F12)→ Console → 查詢”Mixed Content”警告。將所有資源 URL 更新為 https:// 或相對路徑。
“ERR_SSL_VERSION_OR_CIPHER_MISMATCH”
原因: 用戶端不支援你的伺服器提供的 TLS 版本或加密套件。
修復: 確保配置中包含 TLS 1.2(不只是 1.3):
ssl_protocols TLSv1.2 TLSv1.3; # NOT just TLSv1.3
證書顯示為”不受信任”但檔案正確
原因: 證書鏈不完整——fullchain.pem 缺少中間證書,或檔案順序錯誤。
修復: 透過連線你的證書 + 中間證書重建 fullchain.pem:
cat cert.pem chain.pem > fullchain.pem
順序很重要:你的證書在前,然後是中間證書。
常見問題
HTTP 和 HTTPS 需要單獨的配置檔案嗎?
不需要。將兩個 server 塊(埠 80 和 443)放在同一個檔案中。HTTP 塊僅用於重新導向到 HTTPS。
應該使用 ssl on; 嗎?
不應該。ssl on; 已棄用。使用 listen 443 ssl; 代替——listen 指令中的 ssl 引數是現代做法。
reload 和 restart 有什麼區別?
reload 優雅地將新配置應用到新連線而不斷開現有連線。restart 停止並啟動程序,短暫斷開所有連線。證書更改始終使用 reload。
可以用不同的證書服務多個域名嗎?
可以。使用不同的 server_name、ssl_certificate 和 ssl_certificate_key 指令建立單獨的 server 塊。Nginx 使用 SNI(Server Name Indication)根據請求的主機名提供正確的證書。
Nginx 支援 ECDSA/ECC 證書嗎?
支援。Nginx 處理 ECDSA 證書的方式與 RSA 完全相同——相同的指令,相同的檔案格式。GetHTTPS 預設生成 ECDSA P-256(更小的金鑰,更快的握手)。
如何啟用 HTTP/2?
在 listen 指令中新增 http2:listen 443 ssl http2;。這已經包含在上面的推薦配置中。HTTP/2 需要 HTTPS——無法在明文 HTTP 上使用。