nftables 命名集更新延迟

nftables 命名集更新延迟

我有以下内容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 ingressIP 时,立即被阻止。也许这种调查途径可能会揭示一些东西。

答案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模块)。

相关内容