Nginx 400错误排查:客户端向HTTPS端口发送HTTP请求
偶发400 Bad Request错误排查分析
从你提供的Nginx错误日志和架构配置来看,偶发400错误对应两类核心问题,结合Django+Gunicorn+Nginx+AWS负载均衡的架构,具体分析及解决方案如下:
一、核心错误日志解读
client sent plain HTTP request to HTTPS port
该错误说明Nginx的443端口(HTTPS)收到了明文HTTP请求,而非加密的HTTPS请求,直接触发400错误。client sent invalid method while reading client request line
这类乱码请求通常是TCP连接复用异常导致,比如客户端或负载均衡复用了已失效的连接,发送了无效的请求数据。
二、可能根因及对应解决方案
1. AWS负载均衡监听配置不匹配(最可能原因)
你的SSL证书部署在EC2实例上,但负载均衡的协议转发规则可能存在错误:
- 若负载均衡的HTTPS监听将请求以HTTP协议转发到EC2的443端口,会导致Nginx在HTTPS端口收到明文请求,触发第一个错误。
- 若负载均衡的HTTP监听错误转发到EC2的443端口,同样会出现该问题。
解决方案:
- 推荐调整架构:将SSL证书部署在AWS负载均衡上,负载均衡的HTTPS监听转发HTTP请求到EC2的80端口,EC2上的Nginx处理HTTP并直接响应或跳转HTTPS。这种方式符合AWS架构最佳实践,还能减少EC2的SSL加密开销。
- 若坚持在EC2上处理SSL:确保负载均衡的HTTPS监听以HTTPS协议转发到EC2的443端口,HTTP监听转发到EC2的80端口,保持协议转发一致。
2. 连接复用/超时配置不兼容
Nginx和AWS负载均衡的keepalive配置不匹配,可能导致连接状态异常,引发无效请求:
- 负载均衡的空闲超时时间如果大于Nginx的
keepalive_timeout,会出现负载均衡认为连接有效,但Nginx已断开连接的情况,后续请求就会变成乱码。
解决方案:
- 在Nginx的
location /块中添加以下配置,优化与Gunicorn的连接复用:proxy_http_version 1.1; proxy_set_header Connection ""; - 调整AWS负载均衡的空闲超时时间为小于Nginx的
keepalive_timeout(比如Nginx设为65,负载均衡设为60),避免连接状态不一致。
3. Nginx配置语法错误
第一个server块中的server_name = ""写法不符合Nginx语法规范,虽然这不是偶发错误的直接原因,但可能导致部分请求匹配异常:
解决方案:
将该配置修改为:
server { listen 80; server_name ""; return 444; }
4. 异常客户端/爬虫请求
乱码请求可能来自恶意爬虫或有问题的客户端,可通过Nginx限制合法请求方法来过滤:
解决方案:
在HTTPS的server块中添加请求方法校验:
if ($request_method !~ ^(GET|POST|HEAD|OPTIONS)$ ) { return 405; }
内容的提问来源于stack exchange,提问作者ernest30
相关产品推荐
相关产品推荐

