要实现“非明确白名单即drop”的基线策略,核心是将input/forward/output链默认策略设为drop,再正向添加accept规则放行必要流量(如lo、established、指定端口与源),严禁依赖反向匹配(!)构建主干逻辑,最后保存并验证规则生效。

要实现“非明确白名单即 DROP”的基线策略,核心是用 iptables 的反向匹配(!)配合默认策略为 DROP 的链,确保只有显式允许的流量才能通过,其余一律拒绝。这不是单纯加一条 -j DROP 就完事,而是需从策略设计、链初始化、规则顺序和反向逻辑四个层面协同落地。
设置默认策略为 DROP
这是整个白名单模型的前提。若 INPUT/FORWARD/OUTPUT 链默认是 ACCEPT,再精细的白名单也形同虚设。
- 执行:
iptables -P INPUT DROP、iptables -P FORWARD DROP、iptables -P OUTPUT DROP(生产环境慎设 OUTPUT,默认可保留 ACCEPT,按需收紧) - 注意:执行后若未提前放行 SSH/控制通道,可能失连。建议搭配
iptables-restore原子加载,或先加基础放行再改策略 - 查看当前策略:
iptables -L -n -v中 Chain 开头的 policy 字段即为当前默认动作
用 ! 精确排除非白名单项(慎用场景)
! 是反向匹配符号,用于“不满足某条件则匹配”,常用于快速封禁特定源、端口或协议,但**不推荐作为白名单主干逻辑**——它易引发语义混淆和维护风险。更安全的做法是“正向放行 + 默认 DROP”,而 ! 更适合辅助控制,例如:
- 封禁除特定管理网段外的所有 SSH 连接:
iptables -A INPUT -p tcp --dport 22 ! -s 192.168.10.0/24 -j DROP - 仅允许本地回环的 DNS 查询:
iptables -A INPUT -p udp --dport 53 ! -i lo -s 127.0.0.1 -j DROP(注意:此例有逻辑缺陷,仅作语法示意;实际应正向允许-i lo -p udp --dport 53 -j ACCEPT) - 关键原则:含
!的规则必须出现在所有正向 ACCEPT 规则之后、且在默认 DROP 生效前,否则可能绕过预期控制
构建可维护的白名单规则集(推荐主干方式)
真正的基线应基于“最小权限正向声明”:只写 ACCEPT 规则,靠默认 DROP 收口。反向匹配仅用于例外压制,而非白名单主体。
- 先放通必要基础设施:
iptables -A INPUT -i lo -j ACCEPT(本地通信) - 放通已建立连接:
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT(必须放在白名单规则之前,否则新连接无法响应) - 按服务显式放行:
iptables -A INPUT -p tcp -s 10.0.5.0/24 --dport 80 -j ACCEPT(仅允许可信子网访问 Web) - 避免使用
!写“除 A 外都拒”,而应写“只允 A”,逻辑清晰、审计直观、不易漏配
验证与固化策略
策略生效≠策略正确。需验证是否真达成“非白名单即丢弃”,并防止重启失效。
- 用
iptables -S查看原始规则列表,确认无隐式 ACCEPT、默认策略为 DROP、且 ACCEPT 规则无宽泛匹配(如-s 0.0.0.0/0) - 用
tcpdump或nc从非白名单地址测试端口,确认连接被静默丢弃(无 RST,超时) - 保存规则:
iptables-save > /etc/iptables/rules.v4(Debian/Ubuntu)或service iptables save(RHEL/CentOS 6),并启用开机加载服务 - 考虑用 nftables 替代 iptables(iptables 命令实际调用 nft 后端),规则结构更清晰,原生支持集合与字典,更适合白名单建模










