Docker中Nginx反向代理SSL握手失败(错误码525)的解决方法
一、修正Docker环境下的Nginx代理目标配置
你的Nginx运行在Docker容器中,配置里的proxy_pass http://localhost:8899指向的是Nginx容器自身,而非宿主机的8899端口,这会导致Nginx无法转发请求到Web应用。有两种修正方式:
方式1:使用Web应用容器的名称(推荐)
因为Nginx已经加入了Web应用所在的172.16.20.0/24网桥网络,Docker内部可以通过容器名称直接通信。假设Web应用容器名称为web-app,修改proxy_pass为:proxy_pass http://web-app:80;(注:这里用容器内部的80端口,不需要用宿主机的8899映射端口,Docker网络内直接访问容器端口更高效)
方式2:使用宿主机的Docker网关IP
如果一定要用宿主机映射的8899端口,可以找到宿主机在Docker网桥的IP(通常是网桥网段的第一个IP,比如172.16.10.1或172.16.20.1),替换localhost:proxy_pass http://172.16.10.1:8899;可通过
docker network inspect <网络名称>查看网关IP。
二、排查并修复SSL握手失败(错误码525)问题
错误码525是Cloudflare与源站(你的Nginx)之间无法完成SSL握手导致的,按以下步骤排查:
验证Nginx的SSL证书配置
- 检查证书和密钥文件是否正确挂载到Nginx容器的
/ssl目录下,确保文件存在且权限正确(容器内证书文件权限建议设为644,密钥文件设为600)。 - 确认证书和密钥匹配:在Nginx容器内执行
openssl x509 -noout -modulus -in /ssl/my_domain_cert.pem | openssl md5和openssl rsa -noout -modulus -in /ssl/my_domain.key | openssl md5,两个输出的MD5值必须一致,否则说明证书和密钥不匹配。 - 补充基础SSL优化配置,避免因协议或套件不兼容导致握手失败:
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:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384; ssl_prefer_server_ciphers off;
- 检查证书和密钥文件是否正确挂载到Nginx容器的
确认Nginx正确监听443端口
在宿主机执行docker exec <nginx容器名称> netstat -tulpn | grep 443,确认Nginx正在监听443端口;同时检查宿主机防火墙/安全组是否开放443端口,允许Cloudflare的IP段访问。检查Cloudflare的SSL模式设置
登录Cloudflare控制台,进入域名的「SSL/TLS」设置:- 若Nginx使用自签名证书,需将SSL模式设置为「灵活」;
- 若使用受信任CA颁发的证书(如Let's Encrypt),可设置为「严格」或「完全」。
注意:「严格」模式下,源站SSL证书必须能被Cloudflare信任,否则会触发525错误。
三、验证配置并重启Nginx
修改配置后,在Nginx容器内执行nginx -t验证配置语法是否正确,若输出test is successful,则执行nginx -s reload重启Nginx应用新配置。
内容的提问来源于stack exchange,提问作者Owen

