iptables不能直接识别端口扫描,但可通过recent模块检测同一IP在60秒内发起5个跨端口SYN包即拉黑,结合connlimit限制半开连接数、tcp-flags拦截Null/Xmas等非法标志包,并调优内核参数收窄暴露面,实现对慢速及快速扫描的精准拦截。

iptables 不能直接“识别”端口扫描,但能通过连接行为特征(如SYN频次、标志异常、并发连接数)精准拦截慢速和快速扫描。核心不是堵单个端口,而是封住扫描器的试探模式。
用 recent 模块揪出慢扫IP
慢速扫描(如 nmap -sS -T2)的特点是:同一IP在几十秒内向多个不同端口发 SYN,但每个都不完成握手。recent 模块正是为此设计:
- 记录每个新 SYN 的源 IP:
iptables -A INPUT -p tcp --syn -m recent --name scantrack --set -j ACCEPT - 60 秒内命中 5 次即拉黑:
iptables -A INPUT -p tcp --syn -m recent --name scantrack --rcheck --seconds 60 --hitcount 5 -j DROP - 加一条日志便于确认效果:
iptables -A INPUT -p tcp --syn -m recent --name scantrack --rcheck --seconds 60 --hitcount 5 -j LOG --log-prefix "SLOW-SCAN-BLOCK: "
用 connlimit 控制半开连接数
即使节奏慢,扫描器也常维持大量未完成的 TCP 连接(SYN_RECV 状态),用来探测端口响应或绕过速率限制:
- 对非 SSH 服务,限制单 IP 最多 3 个半开连接:
iptables -A INPUT -p tcp -m connlimit --connlimit-above 3 --connlimit-mask 32 -j REJECT --reject-with tcp-reset - SSH 可放宽至 5 个,但规则要放在该限流规则之前,避免误拒合法多会话:
iptables -A INPUT -p tcp --dport 22 -m connlimit --connlimit-above 5 -j ACCEPT
用 tcp-flags 拦截非法扫描包
Null、Xmas、FIN 等隐蔽扫描依赖违反 TCP 协议规范的标志组合,这类包正常业务几乎不会发出:
- 全零标志(Null 扫描):
iptables -I INPUT -p tcp --tcp-flags ALL NONE -j DROP - FIN+URG+PSH(Xmas Tree):
iptables -I INPUT -p tcp --tcp-flags ALL FIN,URG,PSH -j DROP - SYN+FIN 同时置位(非法):
iptables -I INPUT -p tcp --tcp-flags SYN,FIN SYN,FIN -j DROP - 纯 ACK 且无对应连接(伪造会话探测):
iptables -I INPUT -p tcp --tcp-flags ALL ACK -m state --state INVALID -j DROP
配合内核参数收窄暴露面
光靠规则不够,还要让系统本身少“说话”,降低被指纹识别的风险:
- 关闭 ICMP timestamp 请求/响应(防时钟指纹):
echo 1 > /proc/sys/net/ipv4/icmp_echo_ignore_all
再配合 iptables 屏蔽类型 13/14 报文 - 启用 SYN Cookies 防御基础 SYN Flood:
echo 1 > /proc/sys/net/ipv4/tcp_syncookies - 限制半开连接队列长度,减少资源占用:
echo 512 > /proc/sys/net/ipv4/tcp_max_syn_backlog

















