iptables的string模块可匹配明文载荷中的固定字符串实现敏感词过滤,但仅支持ipv4的input/output/forward链、默认限65535字节、无法解密https、不跨包重组、不处理编码压缩,需确认内核启用config_netfilter_xt_match_string且使用完整版iptables。

iptables 的 -m string 模块可以对明文 TCP/UDP 载荷中的固定字节序列做匹配,适合拦截已知、未加密、且完整落在单个数据包内的恶意 payload。但它不是应用层检测工具,不能解析协议、不解密、不重组 TCP 流——用错场景就等于没防护。
确认系统支持并启用 string 模块
执行以下命令验证是否可用:
iptables -m string --help
若提示 “Unknown arg”,说明内核未启用 CONFIG_NETFILTER_XT_MATCH_STRING,或 iptables 编译时未包含该扩展。可检查:
-
ls /lib/modules/$(uname -r)/kernel/net/netfilter/xt_string.ko*是否存在 -
zcat /proc/config.gz | grep CONFIG_NETFILTER_XT_MATCH_STRING(如系统支持 config.gz)
精简系统(如某些容器镜像、嵌入式固件)常默认禁用,建议使用主流发行版完整版 iptables。
基础匹配语法与关键参数
核心是限定范围、选对算法、避免误杀:
-
--string "malware":指定 ASCII 字符串,注意大小写敏感(新内核支持--icase) -
--algo bm:Boyer-Moore 算法,短字符串推荐;--algo kmp更适合含重复子串的长模式 -
--from 40 --to 1500:跳过典型 IP/TCP 头部(共约 40 字节),限制扫描范围,提升性能并减少误匹配 - 必须搭配协议和端口限定,例如:
-p tcp --dport 80或-p udp --dport 53
示例:拦截 HTTP 请求中明文出现 eval( 的流量(仅限无压缩、不分片的测试环境):
iptables -A INPUT -p tcp --dport 80 -m string --algo bm --from 64 --to 1024 --string "eval(" --icase -j DROP
匹配十六进制特征(如 shellcode 片段)
对二进制级 payload(如漏洞利用载荷前缀),可用 --hex-string:
- 语法:
--hex-string "|90 90 90 90|"表示连续四个 NOP 指令(0x90) - 配合
--from/--to可缩小搜索窗口,降低开销 - 注意:该方式只匹配原始字节,无法识别编码、混淆或加壳后的变体
示例:阻断某已知 exploit 中的固定指令序列:
iptables -A INPUT -p tcp --dport 445 -m string --algo bm --hex-string "|48 83 ec 28|" --from 0 --to 200 -j DROP
必须规避的现实限制
这些限制决定它只能作为辅助手段,不可用于生产环境的核心防护:
- 不跨包匹配:HTTP POST 数据、大文件上传、长 SQL 查询常被拆成多个 TCP 分段,关键词一旦被切开就完全失效
-
不处理编码与压缩:URL 编码(
%3Cscript%3E)、Base64、gzip 压缩后的内容,--string扫不到原文本 - 无法定位字段:不能区分 HTTP 的 URI、Header、Body,也不能跳过 Cookie 或 User-Agent 干扰项
- HTTPS 完全无效:TLS 加密后载荷为密文,SNI 域名虽在 ClientHello 明文区,但位置不稳定,不建议依赖
- 性能代价高:开启后禁用 conntrack 快速路径,高并发下吞吐明显下降
真正需要深度检测的场景,请改用透明代理(如 Squid + regex ACL)、WAF(如 Nginx + ModSecurity)、或 eBPF 工具(如 Cilium)。











