Docker部署HTTP监听的Nginx OpenAI缓存代理遇SSL握手失败
搭建Nginx反向代理缓存OpenAI请求时的SSL握手失败问题解决
问题背景
我正尝试使用Docker搭建本地反向代理,要求如下:
- 以HTTP模式监听(无需加密)
- 将请求转发至HTTPS服务器
该代理用于缓存对OpenAI的高开销请求,使用的Nginx配置如下:
events { worker_connections 10; } http { proxy_cache_path /server_cache levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off; server { listen 80; location /v1/chat/completions { proxy_pass https://api.openai.com; proxy_cache my_cache; proxy_cache_methods POST; proxy_cache_key "$request_method$request_uri$request_body"; proxy_cache_valid 200 60m; proxy_cache_valid 404 1m; proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; proxy_cache_background_update on; proxy_cache_lock on; proxy_set_header Host $host; } location / { proxy_pass https://api.openai.com; proxy_set_header Host $host; } } }
处理请求时Nginx日志报错:
[error] 24#24: *1 SSL_do_handshake() failed (SSL: error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure:SSL alert number 40) while SSL handshaking to upstream
疑问:我得知需添加proxy_ssl_*指令并引入私钥,但我的服务是HTTP而非HTTPS,直接连接上游HTTPS服务器也无需指定证书,为何要这么做?求解决方案,这是否是Nginx缺陷?
原因解析与解决方案
原因说明
这个错误和你的代理是HTTP模式无关,是Nginx与上游OpenAI HTTPS服务器建立SSL连接时握手失败导致的。SSL alert number 40代表握手失败,常见触发原因:
- 错误传递
Host头,导致上游服务器验证不通过 - Docker容器内的Nginx缺少可信根证书,无法验证上游服务器的SSL证书
- Nginx使用的SSL协议版本或加密套件不被上游服务器支持
你说“直接连接上游无需证书”,是因为本地系统预装了完整的可信根证书,但官方Nginx Docker镜像为了精简体积,默认没有包含完整的根证书包,所以容器内的Nginx无法完成证书验证环节,进而触发握手失败。
修复步骤
- 修正Host头配置
OpenAI的API服务器会验证请求的Host头必须是api.openai.com,你之前用$host变量会把本地请求的Host(比如localhost)传递给上游,导致验证失败。需要改为固定值:
proxy_set_header Host api.openai.com;
- 确保容器内有完整可信根证书
基于Alpine的Nginx镜像可以通过以下Dockerfile安装证书包:
FROM nginx:alpine RUN apk add --no-cache ca-certificates COPY your-nginx-config.conf /etc/nginx/nginx.conf
- 指定兼容的SSL协议和加密套件
显式配置Nginx使用上游支持的SSL版本和套件,避免版本不兼容:
proxy_ssl_protocols TLSv1.2 TLSv1.3; proxy_ssl_ciphers HIGH:!aNULL:!MD5;
整合后的完整Nginx配置
events { worker_connections 10; } http { proxy_cache_path /server_cache levels=1:2 keys_zone=my_cache:10m max_size=1g inactive=60m use_temp_path=off; server { listen 80; location /v1/chat/completions { proxy_pass https://api.openai.com; proxy_cache my_cache; proxy_cache_methods POST; proxy_cache_key "$request_method$request_uri$request_body"; proxy_cache_valid 200 60m; proxy_cache_valid 404 1m; proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504; proxy_cache_background_update on; proxy_cache_lock on; proxy_set_header Host api.openai.com; proxy_ssl_protocols TLSv1.2 TLSv1.3; proxy_ssl_ciphers HIGH:!aNULL:!MD5; } location / { proxy_pass https://api.openai.com; proxy_set_header Host api.openai.com; proxy_ssl_protocols TLSv1.2 TLSv1.3; proxy_ssl_ciphers HIGH:!aNULL:!MD5; } } }
是否是Nginx缺陷?
这不是Nginx的缺陷,而是Docker容器环境的特殊性导致:
- 官方Nginx镜像为精简体积默认不包含完整根证书
- 你的配置错误传递了Host头,违反上游验证规则
- SSL握手失败是标准TLS协议错误,Nginx只是如实反馈上游服务器的拒绝信息
内容的提问来源于stack exchange,提问作者user11566205
相关产品推荐
相关产品推荐

