虚拟机的通用 DNS - 使用 iptables/netfilter

虚拟机的通用 DNS - 使用 iptables/netfilter

我的主机上有一个 Bind9。
我有几个来宾虚拟机。
我希望我的虚拟机使用主机上的 Bind9。

我知道如何使 Bind9 接受来自我的虚拟机的请求(监听+允许递归)。
我想使用 iptables/netfilter 实现它,而不修改 Bind9 配置(又名仅在 127.0.0.1 上监听)。
--> 这只是本地端口重定向。我知道如何使用 socat 执行此操作,但是在使用 iptables/netfilter 执行此操作时我陷入困境

仅在 127.0.0.1 上绑定侦听,因此数据包必须源自 127.0.0.1
虚拟机位于网桥 vmbr0 10.10.10.0/24
主机也在网桥 10.10.10.1 上

我应该让数据包进入自定义链,然后 DNAT+SNAT 它们,还是有更简单的方法?

我这样做了(但不起作用):

sysctl -w net.ipv4.conf.vmbr0.route_localnet=1     # not sure if necessary. Let's see that when everything will work

iptables  --table nat  --new-chain dns-prerouting
iptables  --table nat  --append PREROUTING  --source 10.10.10.0/24  --destination 10.10.10.1  --protocol udp  --destination-port 53  --jump dns-prerouting
iptables  --table nat  --append PREROUTING  --source 10.10.10.0/24  --destination 10.10.10.1  --protocol tcp  --destination-port 53  --jump dns-prerouting

iptables  --table nat  --new-chain dns-postrouting
iptables  --table nat  --append POSTROUTING  --source 10.10.10.0/24  --destination 127.0.0.1  --protocol udp  --destination-port 53  --jump dns-postrouting
iptables  --table nat  --append POSTROUTING  --source 10.10.10.0/24  --destination 127.0.0.1  --protocol tcp  --destination-port 53  --jump dns-postrouting


iptables  --table nat  --append dns-prerouting   --jump DNAT  --to-destination 127.0.0.1
iptables  --table nat  --append dns-postrouting  --jump SNAT  --to-source      127.0.0.1

答案1

您必须sysctl -w net.ipv4.conf.XXX.route_localnet=1像以前那样使用,但可能是在虚拟以太网接口上。
这允许内核保留 martin 数据包。

另请记住,本地生成的数据包不会传递到 PREROUTING 链中。所以你必须使用 OUTPUT 链。

最后,不要尝试针对这种非常特殊的情况进行 NAT。代替使用--jump TPROXY
我无法凭记忆给你一个有效的例子,你必须找到确切的设置。然后请完成答案以供将来参考。

答案2

是的。

您将需要 DNAT,因为您需要将来自虚拟机的包转到 lo 上的 127.0.0.1,而不是 10.10.10.1。显然,您也无法将虚拟机配置为作为 DNS 访问本地主机,至少这只会使事情变得更加复杂。

在 lo 上,您可能需要 SNAT,因为在 lo 中,您可能会遇到不属于网络的非本地地址的问题。

我假设 Bind 仅侦听 lo:您似乎还忘记了配置示例中 DNS 数据包从 BIND 到虚拟机的返回方式。然后 BIND 只能将包放入 lo。因此,您需要将它们从本地网络中取出并进入虚拟机网络,在这里您可能不需要 SNAT,具体取决于虚拟机上的 DNS 客户端的挑剔程度。如果您在上面使用过 SNAT,那么现在您将需要 DNAT。

最后,我有点好奇为什么值得付出努力...听起来似乎实施防火墙规则以将 BIND 与您想要隔离的任何内容隔离开来可能要容易得多,甚至给它自己的其他规则虚拟网络的话就用lo。也许如果您描述为什么 BIND 必须处于 lo 状态,也许可以找到更好的方法来解决问题。

对于DNS的方式:

iptables -F -t nat
echo 1 >| /proc/sys/net/ipv4/ip_forward
iptables -t nat -A PREROUTING -p udp -d 10.10.10.1 --dport 53 \
 -j DNAT --to 127.0.0.1:53 

返回虚拟机的方法:

iptables -A FORWARD -i lo -o vmbr0 -m state \
--state ESTABLISHED,RELATED -j ACCEPT

如果这不起作用,您可能需要:

iptables -t nat -A POSTROUTING -o lo -j MASQUERADE

这一切都有点 90%,因为我没有这样的设置可以尝试。请注意,一般情况下这不是一个好的安全决策将任何内容转发给 lo。 lo 意味着完全是本地主机。

答案3

UDP、TCP、IPv4 和 IPv6 的完整设置很复杂。为您的虚拟机使用 DNS 转发器(代理)。我的推荐是 dnsmasq:

dnsmasq -dq -I lo -S 127.0.0.1

将所有请求转发到本地主机上运行的服务器,但忽略环回设备本身。稍后,将 dnsmasq 作为守护进程运行,不带 -dp 选项。

-d or --no-daemon
-q or --log-queries
-S or --server
-I or --except-interface

相关内容