用iptables过滤非标准tcp标志位可有效防御nmap扫描,核心是通过--tcp-flags参数匹配异常组合(如fin+urg+psh、全零、syn+fin等)并拒绝,配合drop实现静默丢弃以隐藏端口状态。

用iptables过滤非标准TCP标志位,是防御Nmap等扫描器探测最直接有效的一道防线。核心逻辑很简单:正常通信只用少数几种合法组合(比如SYN、SYN+ACK、FIN+ACK),而扫描器偏爱用FIN+URG+PSH、全零、全一、SYN+FIN这类违反RFC的异常标志来试探端口或绕过检测——这些包本身就不该出现在健康连接中,直接拦掉即可。
理解--tcp-flags参数的关键写法
--tcp-flags必须同时指定两个字段,缺一不可:
-
检查范围(mask):明确你要盯哪几个标志位,例如
SYN,ACK,FIN,RST或简写为ALL -
期望值(comp):在上述范围内,哪些位必须为1,其余必须为0。比如
--tcp-flags SYN,ACK,FIN,RST SYN表示只允许SYN置位、其他三个都得是0——这正是三次握手第一个包的唯一合法形态
针对常见扫描手法设拒绝规则
以下规则建议用-I INPUT插入INPUT链最前端,确保优先于服务放行规则执行:
- 拦截Xmas扫描(FIN+URG+PSH):
iptables -I INPUT -p tcp --dport 80 --tcp-flags ALL FIN,URG,PSH -j REJECT - 拦截Null扫描(全零标志):
iptables -I INPUT -p tcp --dport 80 --tcp-flags ALL NONE -j REJECT - 拦截全一标志(非法组合):
iptables -I INPUT -p tcp --dport 80 --tcp-flags ALL ALL -j REJECT - 拦截SYN+FIN共存(违反TCP规范):
iptables -I INPUT -p tcp --dport 80 --tcp-flags SYN,FIN SYN,FIN -j REJECT - 拦截仅含FIN的包(FIN扫描常用):
iptables -I INPUT -p tcp --dport 80 --tcp-flags ALL FIN -j REJECT
用DROP隐藏端口存在性
REJECT会返回RST包,等于告诉扫描器“这个端口开着但不欢迎你”;如果想让它误判为“主机不可达”或“端口关闭”,就在上述规则之后加一条静默丢弃:
iptables -I INPUT -p tcp --dport 80 -j DROP- 注意这条规则的位置:必须放在所有白名单ACCEPT之后、异常标志REJECT之前;否则会提前截断合法流量
- 部署前建议运行
iptables -L -v -n --line-numbers确认顺序是否正确
验证效果与注意事项
部署后可用Nmap发起对应扫描验证:
-
nmap -sF -p80 target_ip(FIN扫描) -
nmap -sX -p80 target_ip(Xmas扫描) -
nmap -sN -p80 target_ip(Null扫描) - 若返回
filtered或长时间无响应,说明规则已生效
实际环境中,建议先在测试机上验证,避免误拒管理流量;如需保留特定IP访问权限,务必在DROP/REJECT规则前添加白名单ACCEPT规则。










