应如何重写使用主机名的 nftables 规则来处理多个地址?

应如何重写使用主机名的 nftables 规则来处理多个地址?

我有这个 nftables 规则:

ip daddr { "0.nixos.pool.ntp.org", "1.nixos.pool.ntp.org", "2.nixos.pool.ntp.org", "3.nixos.pool.ntp.org" } udp dport ntp accept comment "Allow NTP traffic for system time"

目标是允许来自主机的 NTP 流量,否则将拒绝大多数流量(默认拒绝策略)。规则中的主机名来自系统的默认 NTP 配置(因此它们与 NTP 守护程序配置的主机名相同)。

但是,它加载失败,因为0.nixos.pool.ntp.org(和其他的)有多个地址:

$ host 0.nixos.pool.ntp.org
0.nixos.pool.ntp.org has address 66.228.42.59
0.nixos.pool.ntp.org has address 216.229.4.66
0.nixos.pool.ntp.org has address 216.229.0.50
0.nixos.pool.ntp.org has address 69.10.161.7

因此 nftables 会抱怨并拒绝加载规则集:

# nft -f ...-nftables-rules
...-nftables-rules:37:16-37: Error: Hostname resolves to multiple addresses
    ip daddr { "0.nixos.pool.ntp.org", ... } udp dport ntp accept comment "..."
               ^^^^^^^^^^^^^^^^^^^^^^

这些域名不在我的控制范围内。因此,我无法阻止它们解析到多个地址。我也不知道与它们关联的地址记录何时会发生变化。

我应该如何编写 nftables 规则集来处理这种情况?

答案1

首先澄清一下:这不是关于 nftables 的问题的答案。它只是提供一些其他选项。

  1. 如果您完全控制相关机器(即没有可能产生恶意 NTP 查询的不受信任的用户),那么允许向任何服务器发送 NTP 与仅允许访问 DNS 查询返回的服务器在安全性方面没有实质性差异,因为 NTP 池保证会根据池中服务器的权重更改这些主机名。因此,简单的解决方案就是允许所有发送 NTP。

  2. 如果您有不受信任的用户,并且想要锁定规则以仅允许 NTP 池 DNS 服务器针对这些特定名称返回的 IP,并且您使用 dnsmasq 作为解析器(或愿意切换到它),那么一种选择可能是使用 dnsmasq 填充 ipset,然后在 nftables 规则中引用该 ipset(假设 nftables 支持 ipset)。我将其与 iptables 一起使用,以将某些出站流量(例如 HTTPS)限制为仅那些我知道我想使用的域,而无需事先知道 IP 地址。

如果您遵循后一种方法,请使用如下 ipset 定义:

ipset create ntp       hash:ip family inet  counters  # IPv4
ipset create ntp-inet6 hash:ip family inet6 counters  # IPv6

以及如下 dnsmasq 选项:

ipset=/nixos.pool.ntp.org/ntp,ntp-inet6

使用上述配置,dnsmasq 会将其解析的名称的 IPv4 地址添加到 ipset ntp,并将 IPv6 地址添加到ntp-inet6ipset。然后,您可以在规则中引用这些 ipset。您还可以在 ipset 上配置超时,但在这种情况下这可能不建议这样做,因为如果发现源稳定,NTP 将在查询 DNS 后继续使用池服务器很长时间。

答案2

我认为目前还没有在 NFTables 中使用“真实”DNS 解析变量的原生方法。

我通过创建一个插件解决了这个问题:https://github.com/superstes/nftables_addon_dns

这是一个 Python3 脚本,用于创建和更新可包含的 NFTables 配置文件。它已在大约 100 台服务器上运行了几个月。

相关内容