在现代网站部署中,HTTPS 是保障通信安全的关键技术。无论是为前端服务启用 HTTPS,还是反向代理 HTTPS 的后端接口,正确理解和配置证书在 Nginx 中尤为重要。
本文将阐述各种常见证书格式(.crt
、.pem
、.key
、.pfx
等)的区别与转换方法,详解 Nginx 如何配置 HTTPS,并介绍如何使用 proxy_ssl_trusted_certificate
实现安全的上游 HTTPS 验证。
一、常见证书格式与区别
格式 | 类型 | 说明 |
---|---|---|
.crt / .pem |
公钥证书 | 包含网站的公钥信息,PEM 编码(文本) |
.key |
私钥文件 | 与公钥配对的私钥,PEM 编码 |
.pfx / .p12 |
证书包 | 包含证书 + 私钥,二进制格式,常用于 Windows |
.cer |
公钥证书 | 通常为 DER 或 PEM 编码,需确认实际格式 |
✅ Nginx 支持哪种格式?
Nginx 仅支持 PEM 格式(即以 -----BEGIN CERTIFICATE-----
开头的文本文件)。因此,若为 .pfx
/.p12
文件,必须转换为 .crt
+ .key
格式。
二、从 .pfx
转换为 .crt
和 .key
# 提取证书(公钥)
openssl pkcs12 -in your-cert.pfx -clcerts -nokeys -out your-cert.crt
# 提取私钥
openssl pkcs12 -in your-cert.pfx -nocerts -nodes -out your-cert.key
# 提取中间证书(可选)
openssl pkcs12 -in your-cert.pfx -cacerts -nokeys -out chain.pem
# 合并证书链(用于 fullchain.pem)
cat your-cert.crt chain.pem > fullchain.pem
三、Nginx 配置 HTTPS(标准服务端)
📁 目录结构建议
/etc/nginx/ssl/
├── fullchain.pem # 包含证书 + 中间证书
├── privkey.pem # 私钥
✅ Nginx 配置示例
server {
listen 443 ssl http2;
server_name www.example.com;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
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 10m;
ssl_session_tickets off;
add_header Strict-Transport-Security "max-age=31536000" always;
location / {
proxy_pass http://localhost:8080;
}
}
四、Nginx 强制 HTTP 跳转 HTTPS
server {
listen 80;
server_name www.example.com;
return 301 https://$host$request_uri;
}
五、配置 Nginx 反向代理 HTTPS 上游服务
如果你要代理的是一个 HTTPS 的后端服务(比如 API 接口),建议启用后端证书验证,避免中间人攻击。
示例:代理到 https://api.backend.com
location /api/ {
proxy_pass https://api.backend.com;
proxy_ssl_verify on; # 启用后端 HTTPS 验证
proxy_ssl_verify_depth 2;
proxy_ssl_trusted_certificate /etc/nginx/ssl/ca-chain.pem;
proxy_ssl_name api.backend.com;
}
配置说明
指令 | 作用 |
---|---|
proxy_ssl_verify on |
启用 HTTPS 上游服务器证书校验 |
proxy_ssl_trusted_certificate |
指定受信任的 CA 根证书,用于验证上游证书 |
proxy_ssl_verify_depth |
验证证书链的最大层级(建议设为 2~3) |
proxy_ssl_name |
显式指定用于 SNI 的主机名,确保与证书匹配 |
💡
ca-chain.pem
可包含多个中间证书和根证书,使用cat root.crt intermediate.crt > ca-chain.pem
合成。
六、检查证书是否有效
# 查看证书有效期
openssl x509 -in your-cert.crt -noout -enddate
# 验证证书链
openssl verify -CAfile ca-chain.pem your-cert.crt
七、常见问题排查
问题 | 原因 | 解决办法 |
---|---|---|
Nginx 启动报 PEM lib 错误 |
证书格式错误 | 确保证书和私钥为 PEM 格式 |
浏览器提示“不受信任的证书” | 缺少中间证书 | 合并证书链为 fullchain.pem |
代理后端 HTTPS 时连接失败 | 没启用 proxy_ssl_verify 或证书未配置 |
检查上游证书与 ca-chain.pem 是否匹配 |
八、总结
场景 | 推荐做法 |
---|---|
部署 HTTPS 服务 | 使用 ssl_certificate + ssl_certificate_key ,建议使用 fullchain.pem |
代理 HTTPS 后端 | 使用 proxy_ssl_verify + proxy_ssl_trusted_certificate |
拥有 .pfx 文件 |
使用 openssl 转换为 .crt 和 .key |
多证书验证 | 合并多个证书为 ca-chain.pem |
示例完整配置:HTTPS + 上游代理
server {
listen 443 ssl http2;
server_name www.example.com;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
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 10m;
ssl_session_tickets off;
add_header Strict-Transport-Security "max-age=31536000" always;
location /api/ {
proxy_pass https://api.backend.com;
proxy_ssl_verify on;
proxy_ssl_verify_depth 2;
proxy_ssl_trusted_certificate /etc/nginx/ssl/ca-chain.pem;
proxy_ssl_name api.backend.com;
}
}