iptables可匹配明文、未加密且单包内的十六进制特征,支持--hex-string和-m u32两种方式:前者匹配固定字节序列(如"|6576616C|"对应"eval"),需限定偏移范围并选合适算法;后者按IP头起算偏移精确定位字节值(如"40 & 0xFF = 0x90"),适合结构化恶意流量识别;但无法处理TLS加密、分片跨包、协议混淆等场景,生产环境应优先采用代理、DPI或eBPF等专业方案。

iptables 可以匹配报文中的十六进制特征码,但仅限于明文、未加密、且完整落在单个 TCP/UDP 数据包载荷内的攻击载荷。它不解析协议、不解密 TLS、不重组 TCP 流,因此不能当作应用层检测工具使用,而是作为轻量级网络层初筛手段。
用 --hex-string 匹配明文载荷中的固定字节序列
适用于 HTTP、DNS、Telnet 等未加密协议中已知的恶意特征,例如 Webshell 函数名、Cobalt Strike 用户代理片段或 shellcode 前缀:
- 语法示例:iptables -A INPUT -p tcp --dport 80 -m string --algo bm --hex-string "|6576616C|" -j DROP(匹配 ASCII "eval")
- 必须加 --algo bm 或 --algo kmp,推荐短模式用 bm,长模式或需抗误判时用 kmp
- 用 --from 40 --to 1000 限定搜索范围,跳过 IP/TCP 头和响应体噪声,减少开销和误匹配
- DNS 协议需按二进制格式写:如 "|03|www|06|google|03|com|00|",不能写成明文域名
用 -m u32 精准定位偏移处的字节值
比字符串匹配更高效、更确定,适合识别结构化恶意流量(如自定义 C2 协议头、畸形 ICMP 隧道、DNS 污染响应):
- 偏移从 IP 头起算:TCP 载荷第 1 字节通常是偏移 40(IP 头 20 字节 + TCP 头最小 20 字节)
- 匹配 payload 第 5 字节是否为 0x90:iptables -A INPUT -p tcp -m u32 --u32 "40 & 0xFF = 0x90" -j DROP
- 支持组合条件,例如“SYN+ACK 标志且 payload 第 12 字节是 0x41”:"20 & 0x3FFF0000 = 0x12000000 && 64 & 0xFF = 0x41"
- UDP DNS 污染常用:"8 & 0xFFFFFFFF = 0x76053106"(匹配伪造 IP 118.5.49.6)
必须避开的典型陷阱
直接依赖十六进制匹配防御攻击,极易失效,部署前务必确认以下限制:
- TLS 加密流量中所有应用层内容均为密文,--hex-string 和 --string 对正文完全无效;SNI 域名虽在 ClientHello 明文区,但位置浮动、易被 ALPN/ESNI 绕过
- HTTP 请求若被分片、压缩(gzip)、分块传输(chunked)或 URL 编码,特征必然跨包或变形,iptables 无法识别
- TCP 头含选项时长度 >20 字节,u32 的固定偏移会错位,需估算最大头长(如用 40 或 44)或结合 --tcp-option 判断
- 规则应插入 INPUT 链靠前位置,但必须放在 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT 之后,避免误杀回包
更可靠的替代路径
十六进制匹配只适合低流量、高可控环境下的辅助过滤。生产系统应转向专业方案:
- 透明代理层:Nginx 或 Squid 配合 Lua / regex ACL,可真正解析 HTTP 结构并解码
- 专用 DPI 工具:如 Suricata,支持流重组、协议解码、多包匹配和 TLS 解密(配合证书)
- eBPF 程序:在内核态实现更精细的载荷提取与上下文判断,性能远超 iptables
- 云 WAF 或网关设备:处理 HTTPS、编码、混淆等全栈问题,运维成本更低

















