reject比drop更隐蔽是因为它用特定icmp响应(如icmp-host-unreachable)伪装主机状态,使扫描器误判为网络故障而非防火墙拦截;需置于input链established规则后、服务规则前,并配合recent模块与日志验证。

用 iptables -j REJECT 替代 DROP 并不是为了让扫描器“知错就改”,而是通过精心选择的 ICMP 响应类型,让它误判你的主机状态——比如以为端口关闭、网络断开,甚至根本不存在。这种“伪装式拒绝”比静默丢包更隐蔽,也比直接暴露防火墙策略更安全。
用 icmp-host-unreachable 伪装“主机已下线”
对来自可疑网段的扫描流量(如 SYN、UDP、ICMP echo-request),返回 --reject-with icmp-host-unreachable(ICMP Type 3 Code 1)是最实用的伪装手段:
- nmap 收到该响应,常将端口标记为 closed 或直接跳过,不会触发深度探测
- 它模拟的是真实网络中路由设备返回的“主机不可达”,比
icmp-host-prohibited更自然 - 避免使用
icmp-port-unreachable—— 它会暴露本机在监听 UDP,等于泄露服务指纹
示例规则(针对扫描源网段 192.168.100.0/24):
iptables -A INPUT -s 192.168.100.0/24 -p tcp --syn -j REJECT --reject-with icmp-host-unreachableiptables -A INPUT -s 192.168.100.0/24 -p udp -j REJECT --reject-with icmp-host-unreachableiptables -A INPUT -s 192.168.100.0/24 -p icmp --icmp-type echo-request -j REJECT --reject-with icmp-net-unreachable
把 REJECT 放在 INPUT 链靠前,但避开合法连接
规则顺序决定行为逻辑。必须确保这些伪装规则在服务放行规则之前生效,同时又不能干扰已有通信:
- 所有
REJECT --reject-with规则应加在ESTABLISHED,RELATED允许规则之后、具体服务ACCEPT规则之前 - 绝对不要对
ESTABLISHED或RELATED状态的包使用 REJECT,否则会中断正在运行的连接 - 不支持
--reject-with的链(如 OUTPUT、PREROUTING)请改用 DROP,避免语法错误
配合 recent 模块实现“先试探、再伪装”
单纯按协议类型拒绝容易误伤;结合访问频次识别,能让伪装更精准:
- 先用
-m recent --set记录首次扫描行为 - 再用
--rcheck --seconds 60 --hitcount 5判定慢速跨端口试探 - 命中后统一返回
icmp-host-unreachable,既降低响应特征,又避免规则爆炸
例如:
iptables -A INPUT -p tcp --syn -m recent --name scanlog --set -j ACCEPTiptables -A INPUT -m recent --name scanlog --rcheck --seconds 60 --hitcount 5 -j REJECT --reject-with icmp-host-unreachable
别忘了日志与验证
伪装是否生效,不能只靠猜测:
- 加
-j LOG --log-prefix "FAKE-UNREACH: "在 REJECT 前记录,方便在/var/log/kern.log中确认响应发出 - 用
tcpdump -i any icmp抓包,验证返回的是 Type 3 Code 1 而非 Code 10 - 从外部用
nmap -sS -Pn 目标IP测试,观察端口状态是否显示为 closed 而非 filtered











