![虚拟机的通用 DNS - 使用 iptables/netfilter](https://linux22.com/image/104248/%E8%99%9A%E6%8B%9F%E6%9C%BA%E7%9A%84%E9%80%9A%E7%94%A8%20DNS%20-%20%E4%BD%BF%E7%94%A8%20iptables%2Fnetfilter.png)
我的主机上有一个 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