nftables在多网卡和网络分段中需显式按接口、IP段、连接状态和hook位置精准配置;必须用iifname/oifname绑定物理/逻辑接口,组合ip saddr与ct state实现跨路径策略,通过jump分链和priority分层处理,避免仅靠地址匹配导致的绕过或漏判。

nftables 在多网卡和网络分段场景下,核心在于按接口、地址段、路由路径精准分流,而不是靠“自动识别”。它不感知业务拓扑,一切依赖显式配置——接口名、IP段、连接状态、hook位置,缺一不可。
按物理/逻辑接口做流量入口控制
多网卡环境(如 eth0 接外网、eth1 接内网、br0 做桥接)必须用 `iifname` 或 `oifname` 明确绑定规则,避免策略错配。 - `iifname "eth0"`:只匹配从 eth0 进来的包,哪怕源 IP 是内网地址也不放行 - `iifname "br0"`:匹配桥接网段(如虚拟机、容器)流入的流量 - `iiftype bridge`:比具体名字更灵活,适配动态桥接设备常见误操作是只写 `ip saddr 10.0.0.0/24` 却没限定接口,结果外网伪造该地址也能绕过。正确做法是组合使用:
nft add rule inet filter input iifname "eth1" ip saddr 10.0.0.0/24 ct state established,related accept-
nft add rule inet filter input iifname "eth0" tcp dport 22 drop(外网禁 SSH)
用地址族与子网划分隔离不同业务段
网络分段本质是 IP 地址空间的逻辑切分,nftables 通过 `ip saddr/daddr` 或 `ip6 saddr/daddr` 直接匹配 CIDR,无需额外模块。 - 同一物理网卡可承载多个子网(如 eth0 配了 192.168.10.1/24 和 172.16.5.1/24),规则仍按 IP 匹配,与接口绑定无关 - 跨子网转发需确保 `forward` 链开启且策略允许,同时检查内核 `ip_forward=1`典型分段规则示例:
- 办公网段(172.16.0.0/16)只许访问 DNS 和代理:
ip saddr 172.16.0.0/16 udp dport 53 accept、ip saddr 172.16.0.0/16 tcp dport 3128 accept - 数据库网段(10.20.30.0/24)禁止外连:
iifname "eth2" ip daddr != 10.20.30.0/24 drop
利用 hook 优先级与链跳转实现分层处理
单纯靠 `input` 链堆规则易混乱。推荐按功能拆链,再用 `jump` 或 `goto` 分流: - 创建专用链:`nft add chain inet filter dmz_in { type filter hook input priority 0 \; }` - 主链中跳转:nft add rule inet filter input iifname "eth0" jump dmz_in
- 在 `dmz_in` 中专注 DMZ 策略,不影响其他接口规则
注意优先级含义:
- `priority -300`(raw):适合 bypass conntrack(如高吞吐监控流量)
- `priority 0`(filter):默认,用于常规访问控制
- `priority 100`(srcnat):仅在 `postrouting` 链生效,做 SNAT 不影响 `input`
连接跟踪(ct)是跨接口策略的关键粘合剂
多网卡环境下,一个连接可能涉及入站(eth0)、出站(eth1)、回包(eth0)多个路径。仅靠单向地址匹配会漏判。 - `ct state established,related` 必须放在允许规则前列,让返回流量自动放行 - `ct zone` 可配合 `zone` 标记实现防火墙区域模型(如 zone 1 = 内网,zone 2 = DMZ),但需配合 `ct original zone` 使用例如:DMZ 服务器访问内网数据库,需双向允许:
- 入方向(DMZ→内网):
iifname "eth0" ip daddr 10.10.0.0/16 ct state new accept - 出方向(内网→DMZ 回包):
oifname "eth0" ct state established,related accept
不复杂但容易忽略

















