I'm testing something with IP masquerade on locally generated traffic but it seems to be breaking DNS lookups. Everything else works fine--all IP traffic without DNS queries work.
$ iptables -t mangle -A OUTPUT -j MARK --set-mark 2 $ iptables -t nat -A POSTROUTING -m mark --mark 0x2 -j MASQUERADE Why does this work with all IP traffic except DNS queries?
Results of requested commands below:
# 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 In a surprise twist, systemd is acting as a DNS server on 127.0.0.53.
systemctl status systemd-resolved is reporting "systemd-resolved[3315]: Got packet on unexpected IP range, refusing." after enabling the two commands.
I believe this issue may be related.
- https://github.com/kubernetes/kubernetes/issues/66067
- https://github.com/kontena/pharos-cluster/issues/482
The relevant portions of those two links are:
all queries to 127.0.0.53:53 goes not from 127.0.0.0/8, but from interface with default route due to masquerading, and systemd-resolved rejects all of these requests with
systemd-resolved[21366]: Got packet on unexpected IP range, refusing.
systemd-resolved goes to the extra effort of validating the stub resolver source/dest addresses, and thus MASQUERADE rule breaks those assumptions:
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; }
anyor eg 127.0.1.1 and superseding the dhcp's dns setting in /etc/resolv.conf, then doing a query to 127.0.1.1 (anything else than 127.0.0.1) can go wrong, eg (conntrack -E):[NEW] udp 17 30 src=127.0.0.1 dst=127.0.1.1 sport=38781 dport=53 [UNREPLIED] src=127.0.1.1 dst=10.0.3.66 sport=53 dport=38781. Answer fails (EINVAL) if answering with sendto(). I have some theories, but first there are a lot of ifs that OP should confirm. doesn't involve mark. btw avoiding it is simple: state the interface in iptables to filter outlo.