我使用 Ubuntu 20.04 操作系统和 dnsjava 客户端库来查询 DNS 服务器。
我在这台机器上有 nftables 规则,它阻止除临时端口范围 32768-61000 之外的端口上的所有流量,dnsjava 将使用该端口从 DNS 服务器获取结果。
table inet tb {
chain input {
type filter hook input priority 0; policy drop;
tcp dport 32768-61000 accept
udp dport 32768-61000 accept
....
....
}
chain forward {
....
}
chain output {
.....
}
}
看起来允许 32768-61000 范围可能是安全缺陷。但完全阻止此端口范围会增加 DNS 解析的延迟,并且由于超时而导致许多失败。
我们有什么办法可以避免这条允许 nftables 中的端口范围的规则吗?是否有任何 nftable 功能可以用来避免这种情况而不影响 dns 解析延迟?
答案1
使用状态防火墙规则。有状态规则的连接状态由 Netfilter 处理连线子系统,可以使用nftables。
目标是允许(选择)传出数据包,让它们被(自动)跟踪连线并仅允许那些属于最初在传出部分中创建的流的一部分作为传入数据包返回。连线一旦规则引用它(任何ct
表达式),它就会自动工作。此外,即使没有规则,它一旦加载就应该在初始(主机)网络命名空间中自动工作。
由于OP没有提供完整的规则集,我只是替换规则,而不尝试创建完整的规则集(例如:允许接口上的数据包lo
很常见,或者可能是输出连锁店也可能有掉落政策)。不尝试简化(例如最近nftables/kernel 允许 TCP 和 UDP 使用单个规则)。
这变成:
table inet tb {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
....
....
}
chain forward {
....
}
chain output {
.....
ct state established accept
udp dport 53 accept
tcp dport 53 accept
}
}
规则集中不再使用临时端口(甚至不需要指定源端口 53)。作为对端口 53 的传出数据包的回复的传入数据包将被自动接受。该related
部分还允许接受相关数据包,例如目的地无法到达时的 ICMP 错误(从而防止在这种情况下超时)。
现在还可以使用这些命令跟踪流程状态(如果涉及容器,则在与应用程序相同的网络命名空间中运行):
对于列表:
conntrack -L
对于(准实时)事件:
conntrack -E
或者更具体地说,例如这两个命令(在两个终端中运行):
conntrack -E -p tcp --dport 53
conntrack -E -p udp --dport 53
当然,关于这一切还有更多内容。进一步的文档: