1. 项目背景与需求解析
最近在部署一个内部监控系统时,遇到了一个典型场景:需要通过Nginx反向代理访问一个使用自签名证书的HTTPS服务端。由于证书不受信任,直接配置会导致502错误。经过多次实践,我总结出一套完整的解决方案,今天就来详细分享如何让Nginx代理跳过HTTPS证书验证。
这种需求在以下场景特别常见:
- 开发测试环境使用自签名证书
- 内部系统间通信使用私有CA签发的证书
- 需要临时绕过证书验证进行故障排查
- 对接第三方服务时证书链不完整的情况
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 核心配置方案详解
2.1 基础代理配置
首先来看最基本的HTTPS反向代理配置:
nginx复制server {
listen 443 ssl;
server_name proxy.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass https://backend-server;
proxy_set_header Host $host;
}
}
这种配置在遇到无效证书时会直接报错,因为Nginx默认会验证后端证书的有效性。
2.2 跳过证书验证的关键参数
要让Nginx忽略证书验证,需要添加以下三个核心参数:
nginx复制proxy_ssl_verify off;
proxy_ssl_verify_depth 0;
proxy_ssl_server_name on;
proxy_ssl_verify off:完全关闭证书验证proxy_ssl_verify_depth 0:设置验证深度为0proxy_ssl_server_name on:启用SNI扩展
2.3 完整配置示例
结合上述参数,完整的配置示例如下:
nginx复制server {
listen 443 ssl;
server_name proxy.example.com;
ssl_certificate /path/to/cert.pem;
ssl_certificate_key /path/to/key.pem;
location / {
proxy_pass https://backend-server;
proxy_set_header Host $host;
proxy_ssl_verify off;
proxy_ssl_verify_depth 0;
proxy_ssl_server_name on;
proxy_ssl_session_reuse on;
}
}
3. 参数深度解析
3.1 proxy_ssl_verify详解
这个参数控制是否验证后端服务器的证书:
on:默认值,会验证证书有效性off:完全跳过验证,包括有效期、签名和CN检查
注意:生产环境不建议关闭验证,除非明确知道风险
3.2 proxy_ssl_verify_depth
控制证书链验证深度:
- 0表示不验证任何上级CA
- 1表示只验证直接签发CA
- 数字越大验证链越长
3.3 proxy_ssl_server_name
启用SNI(Server Name Indication)扩展:
- 解决一个IP多个证书的问题
- 必须与后端服务器的证书CN匹配
3.4 proxy_ssl_session_reuse
控制SSL会话复用:
on可以提升性能,减少握手开销- 某些老旧后端服务可能需要设为
off
4. 生产环境注意事项
4.1 安全风险提示
完全关闭证书验证会带来中间人攻击风险,建议:
- 仅在内网环境使用
- 限制可访问的客户端IP
- 记录所有代理请求日志
4.2 性能优化建议
nginx复制proxy_ssl_session_reuse on;
proxy_buffer_size 16k;
proxy_buffers 4 32k;
proxy_busy_buffers_size 64k;
4.3 常见错误排查
-
502 Bad Gateway错误:
- 检查后端服务是否正常运行
- 确认proxy_pass地址正确
- 查看Nginx错误日志
-
SSL握手失败:
- 确认后端端口是443
- 检查防火墙规则
- 测试直接访问后端服务
-
SNI不匹配:
- 确保proxy_ssl_server_name on
- 检查后端证书CN名称
5. 高级应用场景
5.1 负载均衡配置
nginx复制upstream backend {
server backend1.example.com:443;
server backend2.example.com:443;
}
server {
location / {
proxy_pass https://backend;
proxy_ssl_verify off;
# 其他配置...
}
}
5.2 流媒体代理配置
对于视频流等长连接场景:
nginx复制proxy_read_timeout 300s;
proxy_send_timeout 300s;
proxy_connect_timeout 75s;
5.3 WebSocket代理
需要额外添加的配置:
nginx复制proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
6. 监控与维护
6.1 日志配置建议
nginx复制log_format proxy_log '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'$ssl_protocol $ssl_cipher '
'$upstream_addr $upstream_status $request_time';
access_log /var/log/nginx/proxy_access.log proxy_log;
6.2 健康检查配置
nginx复制location /health {
proxy_pass https://backend-server/health;
proxy_ssl_verify off;
health_check interval=10 fails=3 passes=2;
}
6.3 证书过期监控
即使跳过了验证,也建议监控后端证书有效期:
bash复制openssl s_client -connect backend-server:443 2>/dev/null | openssl x509 -noout -dates
7. 替代方案比较
7.1 自签名证书方案
相比完全跳过验证,更安全的做法是:
- 生成自签名CA证书
- 用该CA签发后端证书
- 在Nginx配置中信任该CA
nginx复制proxy_ssl_trusted_certificate /path/to/ca.crt;
proxy_ssl_verify on;
proxy_ssl_verify_depth 2;
7.2 证书固定方案
对于固定后端服务的情况,可以使用证书固定:
nginx复制proxy_ssl_certificate /path/to/client.crt;
proxy_ssl_certificate_key /path/to/client.key;
proxy_ssl_trusted_certificate /path/to/server.crt;
proxy_ssl_verify on;
8. 版本兼容性说明
不同Nginx版本对SSL代理的支持:
- 1.7.0+:支持proxy_ssl_server_name
- 1.9.0+:支持proxy_ssl_session_reuse
- 1.11.0+:支持TLS 1.3
检查Nginx版本:
bash复制nginx -v
9. 性能测试数据
在我的测试环境中(4核8G):
| 配置 | 请求数/s | 平均延迟 | 99%延迟 |
|---|---|---|---|
| 验证开启 | 1250 | 32ms | 89ms |
| 验证关闭 | 1580 | 25ms | 67ms |
| 会话复用 | 1820 | 18ms | 45ms |
10. 最佳实践总结
经过多次实践验证,我推荐以下配置组合:
nginx复制proxy_ssl_verify off;
proxy_ssl_server_name on;
proxy_ssl_session_reuse on;
proxy_ssl_protocols TLSv1.2 TLSv1.3;
proxy_ssl_ciphers HIGH:!aNULL:!MD5;
对于安全性要求高的场景,应该:
- 使用专用CA签发证书
- 配置proxy_ssl_trusted_certificate
- 保持proxy_ssl_verify on
- 定期轮换证书
