我正在本地生成的流量上使用 IP 伪装进行测试,但它似乎破坏了 DNS 查找。其他一切都工作正常——所有没有 DNS 查询的 IP 流量都可以工作。
$ iptables -t mangle -A OUTPUT -j MARK --set-mark 2
$ iptables -t nat -A POSTROUTING -m mark --mark 0x2 -j MASQUERADE
为什么这适用于除 DNS 查询之外的所有 IP 流量?
请求命令的结果如下:
# ip address
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp2s0f1: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc fq_codel state DOWN group default qlen 1000
link/ether 54:21:c6:28:99:1f brd ff:ff:ff:ff:ff:ff
3: wlp3s0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether c1:b2:a1:55:34:d2 brd ff:ff:ff:ff:ff:ff
inet 192.168.1.108/24 brd 192.168.1.255 scope global dynamic noprefixroute wlp3s0
valid_lft 242078sec preferred_lft 242078sec
inet6 fe80::1dd6:f094:be8d:ef51/64 scope link noprefixroute
valid_lft forever preferred_lft forever
# ip route
default via 192.168.1.1 dev wlp3s0 proto dhcp metric 600
169.254.0.0/16 dev wlp3s0 scope link metric 1000
192.168.1.0/24 dev wlp3s0 proto kernel scope link src 192.168.1.108 metric 600
令人惊讶的是,systemd 充当 127.0.0.53 上的 DNS 服务器。
systemctl status systemd-resolved
正在报告“systemd-resolved[3315]:在意外的 IP 范围内收到数据包,拒绝。”启用这两个命令后。
我相信这个问题可能是相关的。
- https://github.com/kubernetes/kubernetes/issues/66067
- https://github.com/kontena/pharos-cluster/issues/482
这两个链接的相关部分是:
所有对 127.0.0.53:53 的查询都不是来自 127.0.0.0/8,而是来自由于伪装而具有默认路由的接口,并且 systemd-resolved 拒绝所有这些请求
systemd-resolved[21366]:在意外的 IP 范围内收到数据包,拒绝。
systemd-resolved
需要付出额外的努力来验证存根解析器源/目标地址,因此 MASQUERADE 规则打破了这些假设:
if (in_addr_is_localhost(p->family, &p->sender) <= 0 ||
in_addr_is_localhost(p->family, &p->destination) <= 0) {
log_error("Got packet on unexpected IP range, refusing.");
dns_stub_send_failure(m, s, p, DNS_RCODE_SERVFAIL, false);
goto fail;
}
答案1
这对我来说效果很好。只需排除本地接口,nslookup 就可以正常工作。
sudo iptables ! -o lo -t nat -A POSTROUTING -j MASQUERADE
答案2
对我来说,基于 systemd 解析行为的解决方案是实现如下规则:
$ iptables -t mangle -A OUTPUT ! -s 127.0.0.1 -j MARK --set-mark 2
$ iptables -t nat -A POSTROUTING -m mark --mark 0x2 -j MASQUERADE
答案3
我关闭了 systemd-resolved,但仍然存在 dns 解析器问题,我使用您的 mangle 解决方案修复了该问题。
提出一个替代答案,因为也许我们只想要 iptables 而不是 systemd-resolved 作为我们的防火墙:
hostname
/etc/systemd/resolved.conf.d/00-.conf中的 StubListener 为 no
令人不舒服的是,我们只是解决了 systemd,无法阻止它运行并从 iptables 中夺走防火墙域。
一段时间以来,我们可以选择阻止这种情况,要么返回到仅遵循 google 解析器,要么使用 opennic 解析器。检查名称库,以获取本地最快的选择。
或者,我们可以使用 dnsmasq,或者老式的 djbdns dnscache。我们可以通过 dnsmasq 或 dnscache 或组合来改进 google 和/或 opennic 或其他任何东西。我使用的是 dnsmasq 和 namebench-ed opennic 加上 127.0.0.53 dnscache,所以 www.bigtube.com SERVFAIL 不需要三分钟!我在 /etc/resolvconf 和 NetworkManager 中有 dnsmasq 127.0.0.1。 Erwin Hoffmann 的 djbns dnscache 确实有 ipv6,我个人并不关心。