Nginx搭建HTTPS代理后CONNECT请求返回HTTP 400错误排查
问题根因
你当前的Nginx配置只实现了普通HTTP正向代理的逻辑,没有适配HTTP代理所需的CONNECT方法:
- 访问HTTP站点时返回的301跳转是上游站点本身的HTTPS重定向逻辑,属于正常站点行为,和你的代理配置无关
- 跳转后客户端会发起CONNECT请求尝试建立HTTPS隧道,原生Nginx默认不支持处理CONNECT方法,所以直接返回400 Bad Request
解决方案
方案1:添加第三方CONNECT支持模块(推荐)
使用ngx_http_proxy_connect_module第三方模块为Nginx添加CONNECT方法处理能力,适配HTTPS代理隧道需求:
- 下载和你当前安装版本一致的Nginx源码,以及
ngx_http_proxy_connect_module源码 - 编译Nginx时添加参数:
--add-module=/path/to/ngx_http_proxy_connect_module - 修改你的代理配置,新增CONNECT相关配置:
server { error_log /var/log/nginx/nginx.err; access_log /var/log/nginx/nginx.acc; resolver 127.0.0.53; listen 80; listen 443 ssl default_server; server_name proxy; ssl_certificate /etc/letsencrypt/live/proxy/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/proxy/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/proxy/chain.pem; proxy_ssl_certificate /etc/letsencrypt/live/proxy/fullchain.pem; proxy_ssl_certificate_key /etc/letsencrypt/live/proxy/privkey.pem; proxy_ssl_trusted_certificate /etc/letsencrypt/live/proxy/chain.pem; large_client_header_buffers 1 128k; proxy_ssl_verify on; proxy_ssl_session_reuse off; ssl_verify_client off; ssl_protocols SSLv3 TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; ssl_ciphers RC4:HIGH:!aNULL:!MD5; ssl_prefer_server_ciphers on; # 新增CONNECT支持配置 proxy_connect; proxy_connect_allow 443 80; proxy_connect_connect_timeout 10s; proxy_connect_read_timeout 300s; proxy_connect_send_timeout 300s; location / { proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header HOST $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Access-Control-Allow-Origin *; proxy_buffering on; proxy_buffers 8 16k; proxy_buffer_size 16k; proxy_pass http://$host$request_uri; proxy_read_timeout 1800; } }
- 替换原有Nginx二进制文件后重启服务即可。
方案2:无编译临时规避方案
如果不想重新编译Nginx,也可以调整配置让Nginx直接代理HTTPS请求,不需要客户端发起CONNECT:
- 调整location块中的
proxy_pass配置,自动适配HTTP/HTTPS协议:
location / { resolver 127.0.0.53; proxy_http_version 1.1; proxy_set_header Connection ""; proxy_set_header HOST $host; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Access-Control-Allow-Origin *; proxy_buffering on; proxy_buffers 8 16k; proxy_buffer_size 16k; # 修改为适配协议的代理地址 proxy_pass $scheme://$host$request_uri; proxy_read_timeout 1800; }
- 客户端需配置信任你代理使用的Let's Encrypt证书,否则会触发证书校验错误。
内容的提问来源于stack exchange,提问作者Emma
相关产品推荐
相关产品推荐

