是否可以循环 DNS 请求?

是否可以循环 DNS 请求?

我不确定我是否恰当地表达了这一点,但我想要实现的是通过以循环格式向 DNS 服务器列表发出 DNS 查询来对机器的在线足迹进行轻微的匿名化,而不是因为它的响应速度最快而继续一遍又一遍地使用相同的服务。

我已经dnsmasq在 CentOS 系统上进行了设置,并且查询正在按预期通过它进行路由。 /etc/dnsmasq.conf如下...

domain-needed
bogus-priv
no-resolv
log-queries
user=dns
group=dns

listen-address=127.0.0.1

server=1.1.1.1
server=1.0.0.1
server=208.67.222.222
server=208.67.220.220
server=8.8.8.8
server=8.8.4.4

因此目前,我可以在日志中看到,在收到 DNS 查询请求时,dnsmasq 正在向全部 6的服务...

dnsmasq[5801]: query[A] example.com from 127.0.0.1
dnsmasq[5801]: forwarded example.com to 8.8.4.4
dnsmasq[5801]: forwarded example.com to 8.8.8.8 
dnsmasq[5801]: forwarded example.com to 208.67.220.220 
dnsmasq[5801]: forwarded example.com to 208.67.222.222
dnsmasq[5801]: forwarded example.com to 1.0.0.1 
dnsmasq[5801]: forwarded example.com to 1.1.1.1 

...并返回第一个回应。

我希望它只向第一台服务器发出查询,并返回/缓存响应,除非出现错误。如果出现错误,它应该移动到列表中的下一个服务器,直到得到正确的响应。然后,新请求的下一个查询应该转到列表中的下一个服务器.....就像循环一样。

那可能吗?

答案1

dnsmasq 或 bind 无法实现这一点。可能有其他 DNS 服务执行一些负载平衡。

如果我不得不这样做,我会查看负载均衡器或“流量管理器”服务以接收 DNS 请求,然后将其循环发送到多个 dnsmasq 解析器(在 docker 容器中或在不同端口上运行)。这样,我可以配置每个 dnsmasq 服务以使用其中一个转发器。

但实际的负载平衡必须由不同的服务来完成。

答案2

如果你使用其他东西没有问题dnsmasq,或者bind你可能想尝试一下corednspolicy round_robin插件forward

  • 政策指定用于选择上游服务器的策略。默认值为随机的

    • 随机的是实现随机上游选择的策略。

    • 循环法是一种根据循环顺序选择主机的策略。

    • 顺序的是一种根据顺序选择主机的策略。

(从https://coredns.io/plugins/forward/

davidgo 的评论也很有趣,但你必须注意可能自动发生的[伪]连接跟踪,以避免以任何方式向选择的第一个 IP 地址发送大量请求。

答案3

解决方案遵循@madacoda 的想法:

使用 iptables 作为负载均衡器从默认 53 端口接收 DNS 请求,然后将请求(DNAT)发送到 dockerized dnsmasqs 监听的不同端口。

这需要几个 iptables DNAT 规则和“统计”模块。假设您有 3 个解析器,并且想要在它们之间进行负载平衡。iptables 规则如下:

sudo iptables -t nat -A PREROUTING -p udp -d <listen_address> -m udp \
--dport 53 -m state --state NEW -m statistic --mode nth --every <N> --packet 0 \
-j DNAT --to-destination <listen_address>:<resolver_listen_port(N)>

sudo iptables -t nat -A OUTPUT -p udp -o lo -m udp --dport 53 -m state --state NEW \
-m statistic --mode nth --every <N> --packet 0 -j DNAT --to-destination \
 <listen_address>:<resolver_listen_port(N)>

其中 N=1,2,3 且“监听地址”用于接收所有 DNS 查询。在这种情况下,“resolver_listen_port”将类似于“5301,5302,5303”。

由于本地查询不经过 PREROUTING 链,因此应用上述示例中的第二条规则,以允许本地查询在解析器之间进行负载平衡。

使用带有“nth”模式的统计模块将以循环方式在后端解析器之间分派查询流,但我认为这不是处理 DNS 请求的最佳方式。使用 Nginx 作为负载平衡器将提供更合理的平衡方案,但不幸的是,处理 UDP 流需要 Nginx Plus,这是一项非免费功能。

相关内容