云计算百科
云计算领域专业知识百科平台

Nginx SSL/TLS 配置实战:从证书生成到 HTTPS 部署

一、前言

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;
}

迁移对比

对比项F5Nginx
证书存储 数据库(/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) 谨慎开启

八、生产建议

  • 生产环境使用正式 CA 签发的证书,不要用自签名证书
  • 通配符证书 *.example.com 只能覆盖一级子域名,不能覆盖 dev.www.example.com
  • 证书到期前 30 天开始预警,配置自动续期(Let’s Encrypt + certbot)
  • HSTS 必须配置,防止 SSL Strip 攻击
  • OCSP Stapling 必须开启,提升 TLS 握手速度
  • TLS 1.0/1.1 必须禁用,存在已知安全漏洞

  • 下一篇: Nginx 主动健康检查实现:Python 脚本守护进程实战

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » Nginx SSL/TLS 配置实战:从证书生成到 HTTPS 部署
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!