Nginx access log部分条目无GET/POST标识,Python复现遇阻求助
问题:复现Nginx access.log中无请求方法标识的异常请求
生产环境Nginx的access.log中出现了无GET/POST请求方法的异常日志,示例如下:
<ip_addr> - - [27/Jan/2024:07:06:39 +0000] "\x03\x00\x00/*<snip>Cookie: mstshash=Administr" 400 166 "-" "-"
我尝试用Python复现这类请求,但测试生成的日志和生产环境不符:
<ip_addr> - - [02/Feb/2024:00:03:16 +0000] "POST / HTTP/1.1" 301 178 "-" "python-requests/2.31.0"
我的操作步骤:
- 将日志中的
"\x03..."内容转换为bytearray对象 - 假设是POST请求,用
requests.post(svrname, data=url)发送 - 发现
requests.get()不支持发送bytearray对象,尝试直接发送原字符串,生成的日志依然不匹配:
<ip_addr> - - [02/Feb/2024:00:20:37 +0000] "GET /%5Cx03%5Cx00%5Cx00<snip>Cookie:%20mstshash=Administr HTTP/1.1" 502 190 "-" "python-requests/2.31.0"
该日志显示为GET请求,内容也和生产环境的异常日志不符,请问后续该如何尝试解决?
解决思路
1. 用socket直接发送原始字节流
requests库会自动封装HTTP规范的请求头和格式,无法发送不符合规范的原始数据。直接用socket可以完全自定义发送内容,避免被框架修改:
import socket # 目标服务器信息 host = "your-server-ip" port = 80 # 从日志提取的原始字节内容(注意转义要准确) raw_data = b"\x03\x00\x00/*<snip>Cookie: mstshash=Administr" # 建立连接并发送数据 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((host, port)) s.sendall(raw_data) # 可选:接收响应 response = s.recv(1024) s.close()
这种方式发送的是完全原始的字节,更接近生产环境中异常请求的形态。
2. 分析异常请求的本质
生产环境日志返回码是400(Bad Request),说明这是不符合HTTP规范的畸形请求,不是标准的GET/POST请求。这类请求可能是:
- 非HTTP协议流量(比如RDP、SSH)误发到HTTP端口
- 恶意构造的畸形数据包
- 网络传输中被截断的不完整数据
可以把日志里的\x03\x00\x00转成十六进制分析,比如\x03是ASCII的ETX(文本结束)字符,这类非HTTP起始标识的请求会被Nginx判定为无效,因此日志不会显示请求方法。
3. 确认请求的完整性
日志中的<snip>部分可能是被截断的内容,建议在生产环境用tcpdump或Wireshark抓包,获取完整的异常请求字节流,再对比测试发送的数据是否一致。
4. 调整Nginx测试配置
部分Nginx配置会自动修正或拦截畸形请求(比如underscores_in_headers、merge_slashes),测试时可以暂时关闭这些配置,确保原始请求能被完整记录到日志中。
内容的提问来源于stack exchange,提问作者JohnA
相关产品推荐
相关产品推荐

