wireshark抓包-Host校验的异常
约 662 字大约 2 分钟...
wireshark抓包
nginx 负载均衡导致的400错误
背景:
因为转换服务比较耗CPU等资源,业务层针对pdf转offcie服务做负载均衡
出现问题:
未做负载均衡前,一切正常;添加负载均衡之后反而失败了
出错的nginx配置
location /aspose_sdk/
{
client_body_buffer_size 30M;
client_max_body_size 30M;
proxy_pass http://aspose_sdk/;
proxy_set_header Connection "";
proxy_http_version 1.0;
proxy_connect_timeout 10;
proxy_send_timeout 30;
proxy_read_timeout 300;
}
upstream aspose_sdk {
server 10.2.7.228:9081;
server 10.2.7.229:9081;
keepalive 10;
}
最终定位到原因:
直接原因:上游的aspose服务spring boot使用的是tomcat的网络框架,对host校验规则存在一些问题,不支持下划线。附issue 根本原因:nginx本身使用的backend别名作为Host name,没有正确处理host。(在不设置proxy_set_header的情况下,默认为 proxy_set_header $proxy_host
)
分析过程:
- 复现问题:
解析抓包结果:
- 根据错误码4XX,初步可以断定是客户端(请求端)的问题
- 客户端问题,一般可以逐个分析请求头、请求体等信息是否正确,例如HTTP/1.1 强制要求必须要有Host头等等
- 对比分析正常、异常的抓包请求,分析差异点(关键步骤)
- 最终发现仅Host存在差异。此时可以进行实验操作,对Host进行修改再测试,最终发现是Host不正确,被nginx使用成了backend的名称aspose_sdk。 相关资料:nginx 官方文档
解决方案:
- 将upstream的名称去除下划线_,aspose_sdk改为asposeSdk
- 主要是因为上游服务使用的是Springboot Tomcat历史版本问题
- 说明:https://github.com/spring-projects/spring-boot/issues/13236
- 设置正确的Host,
proxy_set_header HOST $host
- 设置为正常的Host(虽然大多时候没啥问题,出问题可难排查)
- 将upstream的名称去除下划线_,aspose_sdk改为asposeSdk
延伸:
- nginx 在使用upstream时,命名最好不要带符号和数字(避免出现问题)
- 设置正确的Host(做好规范)
- proxy_set_header的用法
proxy_set_header HOST $host
:用户请求中的Host字段,不带端口proxy_set_header HOST $http_host
:用户请求中的Host字段,带端口proxy_set_header HOST $proxy_host
:反向代理中设置的上游的主机名