1. 設定 SSL 憑證(Let's Encrypt)
1.1. SSL/TLS 概述
SSL(Secure Sockets Layer)/ TLS(Transport Layer Security)是加密用戶端與伺服器之間通訊的協定。
為什麼需要 HTTPS:
- 資料安全性(加密)
- 伺服器驗證
- 資料完整性
- SEO 優勢(Google 排名)
- 瀏覽器信任(無警告)
- HTTP/2 的必要條件
- PWA(漸進式網頁應用程式)的必要條件
憑證授權機構(CA):
- Let's Encrypt — 免費、自動化
- DigiCert、Comodo、GlobalSign — 商業服務
- 自我簽署 — 僅用於開發環境
1.2. 安裝 Certbot(Let's Encrypt 用戶端)
Ubuntu/Debian:
# 更新套件清單 sudo apt update安裝 Certbot
sudo apt install certbot python3-certbot-nginx -y
確認安裝
certbot --version
CentOS/RHEL:
# 安裝 EPEL 儲存庫 sudo yum install epel-release -y安裝 Certbot
sudo yum install certbot python3-certbot-nginx -y
CentOS 8+
sudo dnf install certbot python3-certbot-nginx -y
1.3. 取得 SSL 憑證 — 自動方式
方法一:Certbot 自動設定
# Certbot 自動設定 Nginx sudo certbot --nginx -d example.com -d www.example.com依提示操作:
- 輸入電子郵件地址
- 同意服務條款
- 選擇:將 HTTP 重新導向至 HTTPS(建議)
Certbot 的處理流程:
- 驗證網域所有權
- 取得憑證
- 自動設定 Nginx
- 設定自動更新
確認憑證:
# 列出憑證 sudo certbot certificates輸出範例:
Certificate Name: example.com
Domains: example.com www.example.com
Expiry Date: 2024-03-01 10:30:00+00:00 (VALID: 89 days)
Certificate Path: /etc/letsencrypt/live/example.com/fullchain.pem
Private Key Path: /etc/letsencrypt/live/example.com/privkey.pem
1.4. 取得 SSL 憑證 — 手動方式
方法二:Certbot certonly(手動設定)
# 取得憑證但不自動設定 sudo certbot certonly --nginx -d example.com -d www.example.com或使用 webroot
sudo certbot certonly --webroot -w /var/www/html -d example.com -d www.example.com
或使用 standalone(暫時停止 Nginx)
sudo systemctl stop nginx sudo certbot certonly --standalone -d example.com -d www.example.com sudo systemctl start nginx
手動 Nginx 設定:
server { listen 80; server_name example.com www.example.com;# ACME challenge 位置 location /.well-known/acme-challenge/ { root /var/www/html; } # 重新導向至 HTTPS location / { return 301 https://$server_name$request_uri; }}
server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.com www.example.com;
# SSL 憑證檔案 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_prefer_server_ciphers off; root /var/www/html; index index.html; location / { try_files $uri $uri/ =404; }
}
1.5. 憑證更新
Let's Encrypt 憑證 90 天後到期。Certbot 會設定自動更新。
測試更新:
# 乾跑(不實際更新)
sudo certbot renew --dry-run
手動更新:
# 更新所有憑證 sudo certbot renew更新特定憑證
sudo certbot renew --cert-name example.com
更新後重新載入 Nginx
sudo certbot renew --deploy-hook "systemctl reload nginx"
自動更新(systemd 計時器):
# 確認計時器已啟用 sudo systemctl status certbot.timer啟用計時器
sudo systemctl enable certbot.timer sudo systemctl start certbot.timer
1.6. 萬用字元憑證
sudo certbot certonly --manual --preferred-challenges dns
-d example.com -d *.example.com依指示新增 DNS TXT 記錄
_acme-challenge.example.com TXT "generated-token"
確認 DNS 傳播
dig _acme-challenge.example.com TXT
1.7. 多個網域
# 一張憑證包含多個網域
sudo certbot --nginx
-d example.com -d www.example.com
-d blog.example.com -d shop.example.com
2. HTTP 轉 HTTPS 重新導向
2.1. 簡單重新導向
server { listen 80; listen [::]:80; server_name example.com www.example.com;# 將所有 HTTP 重新導向至 HTTPS return 301 https://$server_name$request_uri;}
server { listen 443 ssl http2; 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; root /var/www/html; index index.html;
}
2.2. 含 ACME Challenge 的重新導向
server { listen 80; listen [::]:80; server_name example.com www.example.com;# 允許 ACME challenge location /.well-known/acme-challenge/ { root /var/www/html; allow all; } # 其餘全部重新導向至 HTTPS location / { return 301 https://$server_name$request_uri; }
}
2.3. www 轉非 www 重新導向(HTTPS)
# 將 www 重新導向至非 www server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name www.example.com;ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; return 301 https://example.com$request_uri;}
主要網站
server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # 網站設定...
}
2.4. 完整重新導向設定
# HTTP — 重新導向至 HTTPS server { listen 80; listen [::]:80; server_name example.com www.example.com;location /.well-known/acme-challenge/ { root /var/www/html; } location / { return 301 https://example.com$request_uri; }}
HTTPS www — 重新導向至非 www
server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; return 301 https://example.com$request_uri;}
主要 HTTPS 伺服器
server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers off; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; root /var/www/html; index index.html; location / { try_files $uri $uri/ =404; }
}
3. SSL 協定與加密套件
3.1. SSL/TLS 協定
可用協定:
- SSLv2 — 已棄用,不安全 ❌
- SSLv3 — 已棄用,不安全 ❌
- TLSv1.0 — 已棄用,應避免 ⚠️
- TLSv1.1 — 已棄用,應避免 ⚠️
- TLSv1.2 — 安全,廣泛支援 ✅
- TLSv1.3 — 最安全,現代標準 ✅
建議設定:
server { listen 443 ssl http2; server_name example.com;ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # 僅使用 TLS 1.2 與 1.3 ssl_protocols TLSv1.2 TLSv1.3; # 優先使用伺服器加密套件(TLS 1.2) ssl_prefer_server_ciphers off; # TLS 1.3 自動處理
}
3.2. SSL 加密套件
加密套件決定使用的加密演算法。
Mozilla 中間設定(平衡):
server { listen 443 ssl http2; server_name example.com;ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # 協定 ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers off; # TLS 1.2 加密套件 ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
}
完整 SSL 設定:
server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.com;# 憑證檔案 ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # 協定 ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers off; # 加密套件 ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; # 工作階段快取 ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_session_tickets off; # DH 參數 ssl_dhparam /etc/nginx/dhparam.pem; # OCSP Stapling ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s;
}
3.3. 產生 DH 參數
Diffie-Hellman 參數可強化安全性。
# 產生 2048 位元 DH 參數(需要數分鐘) sudo openssl dhparam -out /etc/nginx/dhparam.pem 2048或 4096 位元(耗時較長,更安全)
sudo openssl dhparam -out /etc/nginx/dhparam.pem 4096
設定權限
sudo chmod 644 /etc/nginx/dhparam.pem
3.4. SSL 工作階段設定
http { # SSL 工作階段快取(跨工作程序共享) ssl_session_cache shared:SSL:10m; # 10MB = 約 40,000 個工作階段# 工作階段逾時 ssl_session_timeout 10m; # 10 分鐘 # 停用工作階段票證(完美前向保密) ssl_session_tickets off;
}
4. HSTS(HTTP 嚴格傳輸安全)
HSTS 指示瀏覽器一律使用 HTTPS。
4.1. 基本 HSTS
server { listen 443 ssl http2; server_name example.com;# HSTS 標頭 add_header Strict-Transport-Security "max-age=31536000" always;
}
max-age 值:
# 測試 — 1 小時 add_header Strict-Transport-Security "max-age=3600" always;短期 — 1 週
add_header Strict-Transport-Security "max-age=604800" always;
建議 — 1 年
add_header Strict-Transport-Security "max-age=31536000" always;
最長 — 2 年
add_header Strict-Transport-Security "max-age=63072000" always;
4.2. 含 includeSubDomains 的 HSTS
server { listen 443 ssl http2; server_name example.com;# 將 HSTS 套用至所有子網域 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
}
警告: includeSubDomains 會影響所有子網域。請確認所有子網域都支援 HTTPS。
4.3. HSTS Preload
server { listen 443 ssl http2; server_name example.com;# 含 preload 指令的 HSTS add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
}
提交至 HSTS Preload 清單:
- 前往 https://hstspreload.org/
- 輸入您的網域
- 確認要求:
- 提供有效憑證
- 將 HTTP 重新導向至 HTTPS
- 在根網域提供 HSTS 標頭
- max-age ≥ 31536000(1 年)
- includeSubDomains 指令
- preload 指令
4.4. 完整 HSTS 設定
# HTTP — 重新導向至 HTTPS server { listen 80; listen [::]:80; server_name example.com www.example.com;location /.well-known/acme-challenge/ { root /var/www/html; } location / { return 301 https://example.com$request_uri; }}
HTTPS 伺服器
server { listen 443 ssl http2; 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_protocols TLSv1.2 TLSv1.3; # HSTS 標頭 add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; # 安全標頭 add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; root /var/www/html; index index.html;
}
5. OCSP Stapling
OCSP Stapling 可提升 SSL/TLS 握手效能與隱私保護。
5.1. 什麼是 OCSP Stapling?
無 OCSP Stapling:
用戶端 → 伺服器:SSL 握手
用戶端 → CA:憑證是否有效?
CA → 用戶端:是的,有效
用戶端 → 伺服器:繼續
有 OCSP Stapling:
伺服器 → CA:我的憑證是否有效?(已快取)
用戶端 → 伺服器:SSL 握手
伺服器 → 用戶端:憑證 + OCSP 回應
用戶端:憑證有效!(無需額外請求 CA)
5.2. 啟用 OCSP Stapling
server { listen 443 ssl http2; server_name example.com;ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # 啟用 OCSP Stapling ssl_stapling on; ssl_stapling_verify on; # 用於驗證的信任憑證 ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem; # OCSP 的 DNS 解析器 resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s;
}
5.3. 確認 OCSP Stapling
# 測試 OCSP Stapling echo QUIT | openssl s_client -connect example.com:443 -status 2> /dev/null | grep -A 17 'OCSP response:'預期輸出:
OCSP response:
======================================
OCSP Response Status: successful (0x0)
Response Type: Basic OCSP Response
...
Cert Status: good
5.4. 完整 OCSP 設定
http { resolver 8.8.8.8 8.8.4.4 1.1.1.1 valid=300s; resolver_timeout 5s;server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.com; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers off; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_session_tickets off; ssl_stapling on; ssl_stapling_verify on; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; root /var/www/html; index index.html; }
}
6. HTTP/2 設定
HTTP/2 透過多工處理、伺服器推送和標頭壓縮大幅提升效能。
6.1. 啟用 HTTP/2
server { # 使用 http2 參數啟用 HTTP/2 listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.com;ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # HTTP/2 需要 TLS 1.2 以上 ssl_protocols TLSv1.2 TLSv1.3; root /var/www/html;
}
確認 HTTP/2 是否已啟用:
# 使用 curl 測試 curl -I --http2 https://example.com確認出現:
HTTP/2 200
或在瀏覽器開發者工具中確認
網路分頁 → 通訊協定欄位應顯示「h2」
6.2. HTTP/2 推送
伺服器推送允許伺服器在用戶端請求前主動發送資源。
server { listen 443 ssl http2; server_name example.com;ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; root /var/www/html; location / { # 請求 HTML 時推送 CSS 和 JS http2_push /css/style.css; http2_push /js/app.js; try_files $uri $uri/ =404; }
}
警告: HTTP/2 推送若使用不當會降低效能。請僅推送關鍵資源。
6.3. HTTP/2 參數
http {
# HTTP/2 設定
http2_max_field_size 16k; # 標頭欄位最大大小
http2_max_header_size 32k; # 標頭最大大小
http2_max_requests 1000; # 每個連線最大請求數
http2_recv_timeout 30s; # 用戶端逾時
}
7. 正式環境完整 SSL 設定
7.1. 最佳 SSL/TLS 設定
# /etc/nginx/nginx.confuser nginx; worker_processes auto; error_log /var/log/nginx/error.log warn; pid /var/run/nginx.pid;
events { worker_connections 1024; }
http { include /etc/nginx/mime.types; default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; client_max_body_size 20M; # 隱藏 Nginx 版本 server_tokens off; # SSL 工作階段快取 ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; ssl_session_tickets off; # OCSP 設定 resolver 8.8.8.8 8.8.4.4 1.1.1.1 valid=300s; resolver_timeout 5s; # Gzip 壓縮 gzip on; gzip_vary on; gzip_comp_level 6; gzip_types text/plain text/css text/xml text/javascript application/json application/javascript application/xml+rss; # HTTP/2 設定 http2_max_field_size 16k; http2_max_header_size 32k; include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*;
}
7.2. 網站設定
# /etc/nginx/sites-available/example.comHTTP — 重新導向至 HTTPS
server { listen 80; listen [::]:80; server_name example.com www.example.com;
location /.well-known/acme-challenge/ { root /var/www/html; allow all; } location / { return 301 https://example.com$request_uri; }}
HTTPS www — 重新導向至非 www
server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name www.example.com;
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem; return 301 https://example.com$request_uri;}
主要 HTTPS 伺服器
server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name example.com;
root /var/www/example.com/public; index index.html index.htm; access_log /var/log/nginx/example.com.access.log; error_log /var/log/nginx/example.com.error.log; ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem; ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers off; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_dhparam /etc/nginx/dhparam.pem; ssl_stapling on; ssl_stapling_verify on; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; add_header X-Frame-Options "SAMEORIGIN" always; add_header X-Content-Type-Options "nosniff" always; add_header X-XSS-Protection "1; mode=block" always; add_header Referrer-Policy "no-referrer-when-downgrade" always; add_header Content-Security-Policy "default-src 'self' https:; script-src 'self' 'unsafe-inline' 'unsafe-eval' https:; style-src 'self' 'unsafe-inline' https:;" always; location / { try_files $uri $uri/ =404; http2_push /css/style.css; http2_push /js/app.js; } location ~* \.(jpg|jpeg|png|gif|ico|svg|webp)$ { expires 1y; add_header Cache-Control "public, immutable"; access_log off; } location ~* \.(css|js)$ { expires 1M; add_header Cache-Control "public"; access_log off; } location ~ /\. { deny all; access_log off; log_not_found off; } error_page 404 /404.html; error_page 500 502 503 504 /50x.html;
}
8. 測試與最佳化
8.1. SSL Labs 測試
# 前往 SSL Labshttps://www.ssllabs.com/ssltest/analyze.html?d=example.com
目標:A+ 評分
A+ 評分清單:
- ✅ TLS 1.2 與 1.3 已啟用
- ✅ 強力加密套件
- ✅ 憑證有效且受信任
- ✅ HSTS 已啟用(含 preload)
- ✅ OCSP Stapling 正常運作
- ✅ 無 SSL/TLS 漏洞
8.2. 測試指令
# 測試 SSL 連線 openssl s_client -connect example.com:443 -tls1_2測試 TLS 1.3
openssl s_client -connect example.com:443 -tls1_3
檢查憑證
echo | openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -dates
測試 OCSP Stapling
echo QUIT | openssl s_client -connect example.com:443 -status 2> /dev/null | grep -A 17 'OCSP response:'
測試 HTTP/2
curl -I --http2 https://example.com
8.3. 效能測試
# 測試 SSL 握手時間 time openssl s_client -connect example.com:443 </dev/null使用 ab 進行基準測試
ab -n 1000 -c 10 https://example.com/
使用 h2load(HTTP/2)測試
h2load -n 1000 -c 10 https://example.com/
8.4. 安全標頭確認
# 確認所有安全標頭 curl -I https://example.com應包含:
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Frame-Options: SAMEORIGIN
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Referrer-Policy: no-referrer-when-downgrade
9. 疑難排解
9.1. 憑證錯誤
問題:憑證不受信任
# 檢查憑證鏈 openssl s_client -connect example.com:443 -showcerts確認憑證檔案
sudo ls -la /etc/letsencrypt/live/example.com/
應包含:
cert.pem(憑證)
chain.pem(中繼憑證)
fullchain.pem(憑證 + 鏈)
privkey.pem(私鑰)
修正:
# 使用 fullchain.pem,而非 cert.pem
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
9.2. 混合內容警告
問題: 網站載入但顯示「不安全」
原因: 以 HTTPS 提供的頁面載入了 HTTP 資源
修正:
<!-- 錯誤寫法 --> <script src="http://example.com/js/app.js"></script>
<!-- 正確寫法 — HTTPS --> <script src="https://example.com/js/app.js"></script>
9.3. OCSP Stapling 無法運作
修正:
server { ssl_stapling on; ssl_stapling_verify on; ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s;
}
9.4. HTTP/2 無法運作
修正:
# 確認 http2 參數存在 listen 443 ssl http2; # 不能只寫 listen 443 ssl;重新啟動 Nginx
sudo systemctl restart nginx
9.5. 憑證更新失敗
修正一:連接埠 80 無法存取
sudo ufw allow 80
修正二:手動更新
# 停止 Nginx sudo systemctl stop nginx使用 standalone
sudo certbot certonly --standalone -d example.com
啟動 Nginx
sudo systemctl start nginx
10. 練習題
練習1:使用 Let's Encrypt 設定 HTTPS
- 安裝 Certbot
- 取得網域憑證
- 在 Nginx 設定 HTTPS
- 測試憑證
練習2:實作 HTTP 轉 HTTPS 重新導向
- 設定 HTTP 伺服器(連接埠 80)
- 設定 HTTPS 伺服器(連接埠 443)
- 設定 HTTP → HTTPS 重新導向
- 測試重新導向
練習3:啟用 HSTS
- 新增 HSTS 標頭
- 在瀏覽器中測試
- 確認 HSTS preload 要求
- (選擇性)提交至 HSTS preload 清單
練習4:設定 OCSP Stapling
- 啟用 OCSP Stapling
- 設定解析器
- 測試 OCSP 回應
- 使用 SSL Labs 驗證
練習5:啟用 HTTP/2
- 在 listen 指令中新增 http2 參數
- 測試 HTTP/2 連線
- 實作 HTTP/2 推送
- 對比 HTTP/1.1 與 HTTP/2 的效能基準
練習6:取得 A+ 評分
- 設定最佳 SSL/TLS 配置
- 啟用所有安全功能
- 使用 SSL Labs 測試
- 修正任何問題以取得 A+ 評分
11. 最佳實踐
11.1. 安全性
# 使用強力協定 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_session_tickets off;
啟用 OCSP Stapling
ssl_stapling on; ssl_stapling_verify on;
HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
11.2. 效能
# 工作階段快取 ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m;HTTP/2
listen 443 ssl http2;
壓縮
gzip on; gzip_types text/plain text/css application/json application/javascript;
靜態資源快取
location ~* .(jpg|png|css|js)$ { expires 1y; add_header Cache-Control "public, immutable"; }
11.3. 維護
# 定期更新憑證 sudo certbot renew檢查憑證到期日
sudo certbot certificates
監控日誌
sudo tail -f /var/log/letsencrypt/letsencrypt.log
備份憑證
sudo tar -czf letsencrypt-backup.tar.gz /etc/letsencrypt/
總結
本課程學到的內容:
- ✅ 使用 Let's Encrypt 設定 SSL 憑證
- ✅ HTTP 轉 HTTPS 重新導向
- ✅ SSL 協定與加密套件最佳化
- ✅ HSTS 設定與 preload
- ✅ OCSP Stapling 提升效能
- ✅ HTTP/2 設定與最佳化
- ✅ 安全標頭與最佳實踐
- ✅ 測試與疑難排解
下一課: 效能調校——透過工作程序、連線、緩衝區、逾時、壓縮與快取最佳化,將 Nginx 效能發揮到極致。