iptables的NFQUEUE可将未使用端口的扫描流量导向用户态诱饵程序,通过匹配非业务端口SYN包(如! --dport 22 ! --dport 80 ! --dport 443)并结合--state NEW和hashlimit限速识别异常连接,再由Python程序伪造SYN-ACK、记录指纹、调用ipset封禁,实现干扰扫描、收集特征与联动防御。

用 iptables 的 NFQUEUE 把未使用端口的扫描流量导向诱饵,本质是“先识别异常连接行为,再引流到用户态程序做响应控制”,而不是真把包转发给某个服务端口。这里的“诱饵”不是监听端口的进程,而是由你写的用户态程序模拟响应(如伪造 SYN-ACK、返回特定载荷、记录指纹),从而干扰扫描器判断、收集攻击特征或触发联动封禁。
识别并拦截可疑扫描连接
扫描器探测未使用端口时,最典型的行为是发送大量 TCP SYN 包到非常规端口(如 12345、31337、65535 等),且源 IP 往往短时间内高频尝试多个端口。需用 iptables 规则精准捕获这类流量:
- 匹配非业务端口的 SYN 包:例如只放行 22/80/443,其余新连接一律入队:
iptables -I INPUT -p tcp --syn ! --dport 22 ! --dport 80 ! --dport 443 -j NFQUEUE --queue-num 0 - 避免误伤:加
-m state --state NEW确保只抓首次握手,不干扰已建立连接的 ACK 或数据包 - 若想更严格,可结合
hashlimit限制单 IP 每秒新建连接数(如 >5 个就入队):iptables -I INPUT -p tcp --syn -m hashlimit --hashlimit-above 5/sec --hashlimit-burst 3 --hashlimit-mode srcip --hashlimit-name scan_detect -j NFQUEUE --queue-num 0
用户态程序实现“诱饵响应”逻辑
Python 示例(需 root 权限运行,依赖 python3-netfilterqueue 和 scapy):
- 监听队列 0,解析每个包的源 IP、目标端口、TCP 标志
- 对匹配的扫描包,不直接 DROP,而是构造伪造响应(如伪造 SYN-ACK 诱导扫描器继续交互):
– 用 scapy 构造 IP/TCP 层,设置flags="SA"、随机seq和ack;
– 调用send()发回,再调用payload.set_verdict(nfqueue.NF_STOLEN)阻止原包进入协议栈(避免内核发 RST) - 同时记录源 IP、时间、端口列表,供后续写入 ipset 封禁:
os.system(f"ipset add scanner-ip-set {src_ip} 2>/dev/null || true")
配套加固与防暴露机制
单纯引流还不够,要防止诱饵被识破或暴露真实环境:
- 确保系统不监听这些“陷阱端口”:检查
ss -tln或netstat -tln,确认无残留服务绑定在 12345、65535 等端口上 - 关闭内核自动回复 RST:扫描包若未被 NFQUEUE 拦截,内核默认会对未监听端口发 RST,暴露端口状态。可在入队规则前加一条 DROP(仅针对已知扫描 IP)或启用
net.ipv4.tcp_rmem调优,但更稳妥的是确保 NFQUEUE 规则优先级足够高(用-I插入链首) - 配合 ipset 实现闭环:用户态程序识别出扫描行为后,立即调用 ipset 添加该 IP,并在 iptables 中添加规则拦截其所有后续流量:
iptables -I INPUT -m set --match-set scanner-ip-set src -j DROP
验证与调试要点
部署后务必验证流程是否连贯:
- 用另一台机器执行
hping3 -S -p 12345 target_ip或nmap -sS -p 12345,31337 target_ip触发规则 - 运行
tcpdump -i any port 12345 or port 31337 -nn查看是否有伪造 SYN-ACK 发出 - 检查
ipset list scanner-ip-set是否新增条目 - 确认
cat /proc/sys/net/ipv4/ip_forward为 0(本机非网关时),避免 FORWARD 链干扰 INPUT 流量路径

















