一、前言
SSL/TLS 配置是 Nginx 生产部署中必不可少的一环。本文将从自建 CA 开始,一步步完成证书签发、Nginx HTTPS 配置、HTTP→HTTPS 跳转,以及 TLS 性能优化,最后补充 F5 到 Nginx 的证书迁移要点。
二、证书体系基础
证书链结构
根证书(CA)
└── 中间证书(Intermediate CA)
└── 服务器证书(Server Certificate) ← 配在 Nginx 上
三种证书类型
| 单域名证书 | 一个域名 | 单一服务 |
| 通配符证书 | *.example.com | 多个子域名共用 |
| SAN 证书 | 多个指定域名 | 多域名需要同一张证书 |
三、自建 CA 与证书签发
第 1 步:生成 CA 根证书
# 生成 CA 私钥
openssl genrsa -out ca.key 2048
# 生成 CA 根证书(有效期 10 年)
openssl req -x509 -new -nodes -key ca.key -days 3650 \\
-subj "/C=CN/ST=Shanghai/L=Shanghai/O=Demo/CN=Demo CA" \\
-out ca.crt
第 2 步:生成服务器证书
# 生成服务器私钥
openssl genrsa -out server.key 2048
# 生成证书签名请求(CSR)
openssl req -new -key server.key \\
-subj "/C=CN/ST=Shanghai/L=Shanghai/O=Demo/CN=nginx.demo" \\
-out server.csr
# 用 CA 签发服务器证书(有效期 1 年)
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \\
-CAcreateserial -days 365 -out server.crt
第 3 步:生成完整证书链
# 合并服务器证书和 CA 证书
cat server.crt ca.crt > fullchain.pem
# 生成 DH 参数(增强 PFS 安全性)
openssl dhparam -out dhparam.pem 2048
文件结构
/etc/nginx/ssl/
├── ca.key # CA 私钥(妥善保管)
├── ca.crt # CA 根证书(客户端需要导入)
├── server.key # 服务器私钥(权限 600)
├── server.crt # 服务器证书
├── server.csr # 证书签名请求(可删除)
├── fullchain.pem # 服务器证书 + CA 证书(Nginx 配置用)
└── dhparam.pem # DH 参数
四、Nginx HTTPS 配置
完整配置
# HTTP → HTTPS 强制跳转
server {
listen 8082;
server_name localhost;
location / {
return 301 https://$host:8443$request_uri;
}
}
# HTTPS 主 server 块
server {
listen 8443 ssl http2;
server_name localhost;
# ========== 证书配置 ==========
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/server.key;
# ========== 协议和加密套件 ==========
ssl_protocols TLSv1.2 TLSv1.3; # 禁用 TLS 1.0/1.1
ssl_ciphers HIGH:!aNULL:!MD5; # 高强度加密套件
ssl_prefer_server_ciphers on;
# ========== DH 参数(增强 PFS 安全性) ==========
ssl_dhparam /etc/nginx/ssl/dhparam.pem;
# ========== 会话缓存(提升性能) ==========
ssl_session_cache shared:SSL:10m; # 共享缓存 10MB
ssl_session_timeout 10m; # 会话超时 10 分钟
# ========== HSTS(强制浏览器用 HTTPS) ==========
add_header Strict-Transport-Security "max-age=63072000" always;
# ========== 响应内容 ==========
root /var/www/nginx-review;
index index.html;
location / {
default_type text/plain;
return 200 "HTTPS 连接成功!证书由 Nginx 终止\\n";
}
}
五、验证 HTTPS
测试命令
# 测试 HTTPS 连接
curl -k https://localhost:8443/
# 输出:HTTPS 连接成功!证书由 Nginx 终止
# 查看 TLS 版本和加密套件
curl -kv https://localhost:8443/ 2>&1 | grep -E "SSL|TLS|cipher"
# 测试 HTTP→HTTPS 跳转
curl -I http://localhost:8082/
# 输出:HTTP/1.1 301 Moved Permanently
# Location: https://localhost:8443/
验证结果
| HTTPS 访问 | curl -k https://localhost:8443/ | 200 OK |
| TLS 版本 | curl -kv | TLSv1.3 |
| 加密套件 | curl -kv | AES_256_GCM_SH384 |
| HTTP 跳转 | curl -I http://localhost:8082/ | 301 → HTTPS |
| HSTS 头 | curl -I -k https://localhost:8443/ | Strict-Transport-Security 存在 |
六、F5 到 Nginx 的证书迁移
第 1 步:从 F5 导出证书
# 登录 F5
tmsh list sys crypto cert example.com.crt > /tmp/example.com.crt
tmsh list sys crypto key example.com.key > /tmp/example.com.key
第 2 步:验证证书
# 检查有效期
openssl x509 -in example.com.crt -dates -noout
# 检查证书链
openssl verify -untrusted ca-chain.crt example.com.crt
# 验证私钥和证书是否匹配
openssl x509 -in example.com.crt -pubkey | openssl md5
openssl pkey -in example.com.key -pubkey | openssl md5
# 两个 MD5 值必须一致
第 3 步:在 Nginx 上配置
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /etc/nginx/certs/example.com.crt;
ssl_certificate_key /etc/nginx/certs/example.com.key;
ssl_trusted_certificate /etc/nginx/certs/ca-chain.crt; # 很多人漏这个!
# 或者合并到一个文件
ssl_certificate /etc/nginx/certs/fullchain.pem;
ssl_certificate_key /etc/nginx/certs/fullchain.pem;
}
迁移对比
| 证书存储 | 数据库(/config/filestore/) | 文件系统 |
| 证书格式 | PEM/DER/PKCS12 | PEM |
| 私钥安全 | 加密存储(secure_path) | 文件权限 600 |
| 证书链 | Profile 中自动配置 | 需要手动配或合并 |
| 更新方式 | 重新导入 + 更新 Profile | 替换文件 + reload |
| 证书匹配验证 | 自动校验 | 语法检查时校验 |
常见坑
坑 1:证书链缺失
错误:curl: (6) SSL certificate problem: unable to get local issuer certificate
原因:没有配置 ssl_trusted_certificate 或 chain 未合并
解决:cat server.crt ca-chain.crt > fullchain.pem
坑 2:私钥密码保护
如果 F5 导入时设了密码,Nginx 不支持 reload 时输入密码
解决:openssl rsa -in encrypted.key -out decrypted.key
七、TLS 配置优化
安全配置
# 最高安全级别
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_ecdh_curve prime256v1:secp384r1;
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_session_tickets off;
性能配置
| ssl_session_cache | 复用 TLS 会话,减少完整握手 | shared:SSL:10m(约 8 万个会话) |
| ssl_session_timeout | 会话缓存有效期 | 10m |
| ssl_buffer_size | 数据块大小 | 4k(默认) |
| ssl_early_data | 0-RTT(TLS 1.3) | 谨慎开启 |
八、生产建议
下一篇: Nginx 主动健康检查实现:Python 脚本守护进程实战
网硕互联帮助中心



评论前必须登录!
注册