iptables的length模块用于匹配ip层总长度(ipv4为total length字段,ipv6为payload length字段),可高效识别异常长短探测包,常配合其他模块实现精准过滤。

Iptables 的 length 模块用于匹配 IP 数据包的总长度(单位:字节),常被用来识别异常小或异常大的探测包,比如某些扫描器、flood 工具或畸形 payload 发送的非典型长度数据包。它不看载荷内容,只看 IP 头里的 Total Length 字段(IPv4)或有效载荷长度(IPv6),因此开销低、规则简洁,适合做初步过滤。
识别超短探测包(如 TCP SYN 扫描、空包探测)
正常 TCP SYN 包最小长度为 60 字节(无选项的 IPv4 + 20 字节 IP 头 + 20 字节 TCP 头)。但部分扫描工具(如某些自定义脚本或 nmap 的 -sS 配合 --min-rate)可能发送更短的包(如 40–55 字节),甚至仅含 IP 头(20 字节)的无效包。
- 拦截总长小于 48 字节的包(排除合法 ICMP echo request 等极简情形):
iptables -A INPUT -m length --length 0:47 -j DROP - 重点监控 48–59 字节区间的 TCP 包(可疑 SYN 或畸形头):
iptables -A INPUT -p tcp -m length --length 48:59 -j LOG --log-prefix "SHORT-TCP: "
再配合 DROP 或限速策略
识别超长或可疑分片探测包
标准以太网 MTU 为 1500,IPv4 允许最大包长 65535,但实际中超过 1500 的单包多为分片或恶意构造(如 ping of death 变种、Jumbo Frame 探测)。length 模块可快速筛出非常规大包。
- 记录并丢弃大于 1500 字节的非分片 IPv4 包(正常路径下极少出现):
iptables -A INPUT -f -m length --length 1501:65535 -j DROP
注意:-f匹配分片包;若要匹配首片或非分片大包,需去掉-f并结合--fragid或! -f - 对 UDP 包限制常见探测长度(如 DNS 放大攻击常用 512+ 字节响应,但客户端请求通常 ≤ 512):
iptables -A INPUT -p udp --dport 53 -m length --length 513:65535 -j LOG --log-prefix "LARGE-DNS-REQ: "
结合其他模块提升准确性
length 单独使用易误判(如含大量 TCP 选项的合法 SYN 包可达 72 字节),建议组合判断:
- 只对无 ACK 标志的 TCP 包检查短长度(聚焦扫描行为):
iptables -A INPUT -p tcp ! --tcp-flags ALL ACK -m length --length 0:59 -j DROP - 排除已建立连接的流量(避免干扰业务):
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
放在 length 规则之前,确保只检测新建连接初期的异常包 - 配合 TTL 值过滤(如探测包常设 TTL=64/128,而中间设备转发后会减小):
iptables -A INPUT -m length --length 0:47 -m ttl ! --ttl-eq 64 -j DROP
注意事项与局限性
length 匹配的是三层(IP 层)总长度,不是四层载荷长度。它无法识别加密流量中的异常 payload,也不适用于隧道封装包(如 GRE、IPsec)的内层长度判断。IPv6 下 length 指的是 Payload Length 字段,不含 IPv6 头固定 40 字节,需换算。另外,Netfilter 在 conntrack 启用时可能对分片包做重组,导致 length 匹配失效——此时应优先在 raw 表处理:
iptables -t raw -A PREROUTING -m length --length 0:47 -j DROP










