nginx无法直接匹配$server_protocol拦截非法http版本,实际应阻断暴露恶意行为特征的请求;通过强制host头校验、default_server兜底、利用内置协议解析返回400、限制http方法及ua指纹识别组合策略实现有效防护。

强制 Host 头校验,过滤掉 95% 的 HTTP/1.0 僵尸请求
绝大多数僵尸网络工具(尤其是嵌入式设备类)仍用 HTTP/1.0 且省略 Host 头。Nginx 虽不拒收 HTTP/1.0,但会将缺失 Host 的请求设为 `$host = ""`。
在 server 块中加入:
if ($host = "") { return 444; }- 搭配
server_name _;作为兜底 default_server(见下文) - 该规则对 curl -H "Host:" 或 telnet 手动发包也生效
用 default_server 拦截所有非法 Host 和协议协商失败请求
把所有未命中合法 server_name 的请求(含 IP 直连、下划线域名、空 Host、伪造协议导致的 SNI 不匹配等)统一交给一个拒绝专用 server:
- HTTP 端配置:
listen 80 default_server;+return 444; - HTTPS 端必须配真实证书(否则 TLS 握手失败,用户看到的是浏览器证书错误,而非你可控的拦截)
- 这个 default_server 实际上也捕获了大量因协议解析异常(如发送
GET / HTTP/3.0)而被 Nginx 内部拒绝后 fallback 过来的请求
利用 Nginx 内置协议解析保护机制自动拦截
Nginx 在解析请求行时,对非法协议标识有硬性校验。只要出现以下任意一种,就会记录 error log 并返回 400 Bad Request:
-
GET / HTTP/abc(非数字版本) -
POST / HTTP/3.0(HTTP/3 尚未启用,且 Nginx 不原生支持明文 HTTP/3) -
HEAD / HTTP/0.9(缺少路径和协议分隔)
你无需额外配置,只需确保:
- 没用
error_page 400覆盖默认行为 - 开启详细日志:
error_log /var/log/nginx/error.log info; - 观察日志中是否频繁出现
client sent invalid request line—— 这就是僵尸工具在试错
补充:限制高危方法 + 拦截典型工具指纹
僵尸网络工具常滥用非常规方法或固定 UA 特征:
- 禁用非业务必需方法:
limit_except GET POST HEAD { deny all; } - 用
map高效匹配已知恶意 UA(比 if 更快、更安全):
map $http_user_agent $is_bot {<br> default 0;<br> ~*(mirai|gafgyt|mozi|tsunami|dofloo|botticelli) 1;<br> ~*Go-http-client/1.1 1;<br>}
if ($is_bot) { return 444; }
注意:避免误伤正常 Go 客户端,可加额外条件如 and $request_method !~ ^(GET|HEAD)$(需用 map 组合逻辑)











