iptables不能直接匹配HTTP请求头,但可通过xt_string模块在数据包载荷中字符串匹配User-Agent,如拦截"python-requests"或"sqlmap",需注意HTTPS加密导致443端口匹配失效,且UA可伪造,建议交由Nginx、WAF或应用层处理。

iptables 本身不能直接识别或匹配 HTTP 请求头(比如 User-Agent),因为它工作在网络层(IP/端口层面),不解析应用层内容。但你可以借助 xt_string 模块,在内核支持的前提下,对数据包载荷中的字符串做简单匹配,从而实现对特定 User-Agent 的拦截。
确认内核是否支持 xt_string 模块
执行以下命令检查模块是否可用:
-
modprobe xt_string(加载模块) -
lsmod | grep string(查看是否已加载) -
iptables -m string --help(验证 iptables 能否调用该模块)
如果报错 “No such module”,说明当前内核未编译此模块,需重新编译内核或更换支持的发行版(如较新 CentOS/RHEL、Ubuntu 内核通常默认启用)。
编写基于 User-Agent 的拦截规则
假设你想屏蔽所有包含 python-requests 或 sqlmap 的 User-Agent 请求(常见扫描工具标识),可添加如下规则:
- 匹配 TCP 80/443 端口的入站请求中含指定字符串:
iptables -A INPUT -p tcp --dport 80 -m string --string "python-requests" --algo bm --to 65535 -j DROPiptables -A INPUT -p tcp --dport 443 -m string --string "sqlmap" --algo bm --to 65535 -j DROP
说明:
– --string 指定要匹配的文本;
– --algo bm 使用 Boyer-Moore 算法提升匹配效率;
– --to 65535 表示在数据包前 65535 字节内搜索(覆盖典型 HTTP 头长度);
– 规则需放在允许 ESTABLISHED/RELATED 和 lo 接口之后、放行 80/443 之前,否则可能误杀合法连接。
注意事项与局限性
这种方案有明显限制,实际使用时需注意:
- User-Agent 可被轻易伪造或分段传输,无法完全防住高级爬虫;
- HTTPS 流量加密后,User-Agent 在 TLS 握手后才出现在应用层,iptables 无法解密,因此 对 443 端口的匹配仅对未加密部分(如 SNI 或早期明文 ClientHello)有效,多数情况下不生效;
- 匹配位置靠前的规则优先执行,若已有 ACCEPT 规则放行了整个端口,string 规则将不会触发;
- 建议仅用于初步过滤明显恶意标识,关键防护应交由 Web 层(如 Nginx 的
if ($http_user_agent ~* ...)或 WAF)完成。
替代更可靠的做法
若目标是精准拦截 User-Agent,推荐组合使用:
- Nginx 配置中用
map或if判断并返回 403; - 结合 fail2ban 监控访问日志,自动封禁高频恶意 UA 的 IP;
- 在应用层(如 Django/Flask 中间件)做 UA 过滤,逻辑更灵活可控。


















