如何用nftables封禁所有未使用端口?嵌入式配置问题
nftables动态配置问题解决方法
你的核心问题在于对nftables的hook链执行逻辑理解有误:所有挂载到同一个hook(比如input)的链会按优先级顺序依次执行,只要有任意一个链的策略为drop,且流量未被该链的accept规则匹配,就会直接被丢弃。你之前尝试添加的drop策略表,会让所有未被其他表规则匹配的流量直接被拦截,甚至可能因为链的执行顺序问题,把原本允许的流量也给封了。
针对你的动态配置需求(每个服务独立表,可单独flush),正确的做法是调整架构:
1. 架构调整思路
- 保留一个主
firewall表,负责处理基础通用规则(如已建立连接、回环接口、状态检查),并作为流量的入口。 - 各个服务表(web、snmp、opc等)的链不再直接挂载input hook,改为普通链。
- 主表的input链通过
jump动作,将流量转发到各个服务表的链进行匹配,最后主表设置policy drop,实现未匹配端口的封禁。
2. 修改后的配置示例
table inet firewall { chain input { type filter hook input priority 0; policy drop; # 最后默认丢弃未匹配流量 ct state invalid drop ct state established,related accept iifname "lo" accept iifname "lo" ip saddr != 127.0.0.0/8 drop iifname "lo" ip6 saddr != ::1 drop # 跳转至各个服务表的input链 jump web_input jump snmp_input jump opc_input } chain forward { type filter hook forward priority 0; policy drop; } chain output { type filter hook output priority 0; policy accept; ct state established accept oifname "lo" accept oifname "lo" ip daddr != 127.0.0.0/8 drop oifname "lo" ip6 daddr != ::1 drop } } # 服务表改为普通链,不再挂载hook table inet web { chain web_input { tcp dport 80 accept tcp dport 443 accept } } table inet snmp { chain snmp_input { udp dport 161 accept } chain output { type filter hook output priority 0; policy accept; udp dport 162 drop } } table inet opc { chain opc_input { tcp dport 4840 drop udp dport 4840 drop } }
3. 关键说明
- 主表的input链作为唯一的hook入口,先处理通用规则,再跳转至各服务链,最后默认drop,确保只有被服务规则允许的流量能通过。
- 每个服务表可以单独用
nft flush inet web(以web表为例)清空规则,不影响其他服务和主表的基础配置。 - 服务表的链不用挂载hook,避免多链并行处理导致的规则冲突。
内容的提问来源于stack exchange,提问作者madam
相关产品推荐
相关产品推荐

