SSL/TLS 現代化設定指南
在建置現代網站與 API 伺服器時,HTTPS(SSL/TLS 加密傳輸)早已不是選配,而是現代網路通訊的絕對標配。未啟用 HTTPS 的網站不僅會被主流瀏覽器標記為「不安全」,還會嚴重影響搜尋引擎排名(SEO)並將使用者機敏資料暴露於中間人攻擊(MITM)的風險中。
無論你是要申請企業級商業憑證(OV/EV)、搭建內網服務、測試環境自簽憑證,還是使用自動化憑證,掌握 OpenSSL 的底層原理 以及 Nginx、Apache 的現代化設定,都是每位系統工程師不可或缺的基礎功。
一、SSL/TLS 憑證核心三要素
在開始操作前,必須先搞清楚三個核心檔案的職責與關係:
- 私鑰(Private Key,
.key):伺服器的最高機密。用於解密客戶端傳送的對稱金鑰與數位簽章,絕對不能外流。 - 憑證簽署請求(CSR, Certificate Signing Request,
.csr):包含你的公鑰以及組織資訊(網域名稱、公司、國家)。這是送交給憑證授權單位(CA, Certificate Authority)用來申請憑證的申請表。 - 數位憑證(Certificate,
.crt或.pem):由 CA 驗證你的 CSR 後,用 CA 自身的私鑰簽署發給你的身分證明文件,包含你的公鑰與有效期限。
二、使用 OpenSSL 產生金鑰、CSR 與自簽憑證
1. 產生 RSA 私鑰
在終端機執行以下指令產生 2048 位元的 RSA 私鑰:
openssl genrsa -out example.com.key 2048
注意:為什麼不要對私鑰設密碼(Passphrase)? 如果在產生時加上
-des3設定了密碼,未來每次伺服器重新啟動或 reload Nginx/Apache 時,終端機都會卡住要求輸入密碼,導致無人值守的伺服器重啟失敗。 若私鑰原本有加密,可用以下指令解除密碼保護:openssl rsa -in example.com_secure.key -out example.com.key
2. 設定嚴格的私鑰存取權限
私鑰必須只允許伺服器擁有者(通常是 root)讀取,避免伺服器上其他受限程式存取:
sudo chown root:root example.com.key
sudo chmod 600 example.com.key
3. 產生憑證簽署請求(CSR)
拿著私鑰生成 CSR,準備提交給商業 CA 審核:
openssl req -new -key example.com.key -out example.com.csr
系統會詢問國家(Country)、省份、城市、組織名稱,其中最關鍵的是 Common Name (e.g. server FQDN),必須填入你的完整網域名稱(例如 example.com 或 *.example.com)。
4. (本地開發/測試用)產生自簽憑證(Self-Signed Certificate)
如果是開發測試環境或內部私有網路,不需要花錢購買 CA 憑證,可直接用一行指令同時產生私鑰與自簽憑證(有效期限 365 天):
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout example.com.key \
-out example.com.crt \
-subj "/CN=example.com"
三、Nginx 現代化 HTTPS 設定
在早期的 Nginx 教學中,常看到 ssl on; 這種寫法。請注意:ssl on; 在現代 Nginx 中已被廢棄並移除!
1. 現代 Nginx 標準設定檔
在 /etc/nginx/sites-available/example.com 中加入以下設定:
# 1. 將所有 HTTP (Port 80) 流量強制轉址至 HTTPS
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com;
return 301 https://$host$request_uri;
}
# 2. HTTPS (Port 443) 伺服器區塊
server {
listen 443 ssl;
listen [::]:443 ssl;
# 若支援 HTTP/2,Nginx 1.25.1+ 可使用: http2 on;
# 舊版則在 listen 後加上 http2: listen 443 ssl http2;
server_name example.com www.example.com;
root /var/www/example.com;
index index.html index.php;
# 憑證與私鑰路徑
ssl_certificate /etc/ssl/certs/example.com_bundle.crt;
ssl_certificate_key /etc/ssl/private/example.com.key;
# 現代化 SSL/TLS 安全通訊協定設定
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# 憑證快取加速
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off;
location / {
try_files $uri $uri/ =404;
}
}
關鍵防坑點:中繼憑證鏈(Certificate Chain / Bundle)
當你向商業 CA 購買憑證時,CA 通常會提供兩個檔案:你的網域憑證(domain.crt)與中繼憑證(intermediate.crt)。
Nginx 的 ssl_certificate 必須包含完整的憑證鏈! 若只放網域憑證,Android、手機瀏覽器或 curl 會報錯 unable to get local issuer certificate。
- 正確做法:將網域憑證與中繼憑證合併為一個 bundle 檔(順序:自己的憑證在最上方,中繼憑證在下方):
cat example.com.crt intermediate.crt > example.com_bundle.crt
四、Apache 現代化 HTTPS 設定
在 Apache 伺服器上,需先確認已啟用 SSL 模組:
sudo a2enmod ssl
sudo a2enmod headers
1. Apache VirtualHost 設定
編輯 /etc/apache2/sites-available/example.com-ssl.conf:
# 1. HTTP 自動 301 轉址到 HTTPS
<VirtualHost *:80>
ServerName example.com
ServerAlias www.example.com
Redirect permanent / https://example.com/
</VirtualHost>
# 2. HTTPS 主機設定
<VirtualHost *:443>
ServerName example.com
ServerAlias www.example.com
DocumentRoot /var/www/example.com
SSLEngine on
# 憑證與私鑰路徑(Apache 2.4.8+ 中,SSLCertificateFile 已支援包含中繼鏈的 fullchain 檔案)
SSLCertificateFile /etc/ssl/certs/example.com_bundle.crt
SSLCertificateKeyFile /etc/ssl/private/example.com.key
# 舊版 Apache (2.4.7 以前) 若分開提供中繼憑證,才需要以下設定:
# SSLCertificateChainFile /etc/ssl/certs/intermediate.crt
# 停用老舊不安全的協定(僅允許 TLS 1.2 與 1.3)
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite HIGH:!aNULL:!MD5
SSLHonorCipherOrder on
<Directory /var/www/example.com>
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
五、現代公開網站的首選:Let’s Encrypt 自動化
如果你架設的是公開對外的正式網站,且不需要特定組織驗證(OV/EV)的企業認證,目前全球業界最普遍的標準是使用 Let’s Encrypt 搭配 Certbot。
它能將上述產生金鑰、申請憑證、設定 Nginx/Apache 以及自動續約(每 90 天)全部一鍵自動化:
# Ubuntu / Debian 安裝 Certbot
sudo apt update && sudo apt install -y certbot python3-certbot-nginx
# 一鍵為 Nginx 申請並自動配置憑證
sudo certbot --nginx -d example.com -d www.example.com
# 測試自動續約排程(systemd timer 會自動處理)
sudo certbot renew --dry-run
六、檢驗與除錯指令
完成配置後,記得先驗證設定檔語法,再重啟 Web 服務:
- Nginx 語法檢查與重啟:
sudo nginx -t sudo systemctl reload nginx - Apache 語法檢查與重啟:
sudo apache2ctl configtest sudo systemctl reload apache2 - 本機驗證 TLS 握手與證書鏈:
openssl s_client -connect example.com:443 -servername example.com - 線上專業安全性測試: 可透過著名的 Qualys SSL Labs SSL Test 輸入網址檢測,確認伺服器評分達到最高等級的 A+。