我有以下内容nftables.conf
:
table inet nat {
set blocked {
type ipv4_addr
}
chain postrouting {
type nat hook postrouting priority 100; policy accept;
ip daddr @blocked counter drop;
oifname "ppp0" masquerade;
iifname "br-3e4d90a574de" masquerade;
}
}
该集合blocked
是一个命名集可以动态更新。正是在这个集合中,我希望有一组要阻止的 IP,并且每个 IP 都会更新n分钟。为了保存原子性, 我是不是使用以下 ( updateblock.sh
) 更新列表:
#!/bin/bash
sudo nft flush set inet nat blocked
sudo nft add element inet nat blocked {$nodes}
反而blockediplist.ruleset
:
#!/usr/sbin/nft -f
flush set inet nat blocked
add element inet nat blocked { <example_ip> }
我使用以下命令顺序:
nft -f /etc/nftables.conf
nft -f blockediplist.ruleset
但是,这些更改blockediplist.ruleset
不会立即应用。我知道规则集现在包含新的 IP,因为这些 IP 存在于nft list ruleset
和中nft list set inet nat blocked
。即使只是使用,nft add element inet nat blocked { <IP> }
IP 也不会立即被阻止。
另一种方法是定义一个新的集合并重新加载nftables.conf
整个集合,尽管我认为这将是一种糟糕且低效的做事方式。
有没有办法强制blockediplist.ruleset
立即应用更改?
更新:我刚刚发现,当我阻止一个我没有 ping 过的 IP 时,它会立即被阻止。然而,当将 IP 添加到阻止列表中时,需要一段时间才能阻止它。当我尝试设置netdev ingress
IP 时,立即被阻止。也许这种调查途径可能会揭示一些东西。
答案1
nat 挂钩(与所有其他挂钩一样)由 Netfilter 提供给 nftables。 NAT 挂钩很特殊:只有连接的第一个数据包会穿过此挂钩。已由 conntrack 跟踪的连接的所有其他数据包不再遍历任何 NAT 挂钩,而是直接由连线继续执行为此流配置的 NAT 操作。
这就解释了为什么你永远不应该使用这个钩子来删除:它不会影响已经跟踪的连接,无论是否经过 NAT。
只需将丢弃流量的部分的钩子类型从 更改为type nat
即可。type filter
与之相反iptables一个表不限于一种钩子类型,实际上对于这种情况必须使用多种类型,因为放是表本地的,不能在两个表之间共享。出于同样的原因,这个表在逻辑上不应该inet nat
再被调用,因为它不只是做NAT(但我没有重命名它)。
所以最后:
nftables.conf
:
table inet nat {
set blocked {
type ipv4_addr
}
chain block {
type filter hook postrouting priority 0; policy accept;
ip daddr @blocked counter drop
}
chain postrouting {
type nat hook postrouting priority 100; policy accept;
oifname "ppp0" masquerade
iifname "br-3e4d90a574de" masquerade
}
}
现在:
所有数据包都将由链检查,
inet nat block
允许该blocked
组立即影响流量,而不必等待下一个流量受到影响。像往常一样,只有新流(暂定 conntrack 状态 NEW)的第一个数据包将遍历该
inet nat postrouting
链。
另请注意,iifname "br-3e4d90a574de" masquerade;
需要足够新的内核(Linux内核 >= 5.5):之前,后路由挂钩仅支持按传出接口进行过滤。另外,这看起来像一个与 Docker 相关的接口,并且添加这种规则可能会与 Docker 交互(例如:它可能对同一网络中的两个容器之间的流量进行 NAT),因为它引用了桥接接口。这是因为 Docker 使桥接流量被nftables(也iptables)通过加载br_netfilter
模块)。