Open VariableDeclared opened 1 year ago
I cannot parse this. Any client can talk to resolved, it just answers universal truths about IP addresses/names.
Or do you want per-VRF DNS zones with different dns servers?
To be clear - i dont have a strong opinion or idea right now what the correct solution might be. Potentially systemd-resolved has no role to play. Simply raising this.
systemd-resolved
on a VRF-enabled system works in a not very intuitive way.
For example, when all your network connections are in different VRFs (a very typical configuration on an ISP core router):
# empty main routing table
root@router:~# ip -4 route show
# Internet in VRF
root@router:~# ip -4 route show vrf isp1
default via 192.0.2.1 dev ens256 proto static
192.0.2.0/24 dev ens256 proto kernel scope link src 192.0.2.2
# the local table, which will become relevant later
root@router:~# ip -4 route show table local
local 127.0.0.0/8 dev lo proto kernel scope host src 127.0.0.1
local 127.0.0.1 dev lo proto kernel scope host src 127.0.0.1
broadcast 127.255.255.255 dev lo proto kernel scope link src 127.0.0.1
and resolved correctly reads the DNS config from networkd: (ens256
is the uplink port, isp1
is the corresponding VRF loopback/L3 master interface)
root@router:~# resolvectl
Global
Protocols: +LLMNR +mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub
Link 4 (ens256)
Current Scopes: DNS LLMNR/IPv4 LLMNR/IPv6
Protocols: +DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 1.1.1.1
DNS Servers: 1.1.1.1 1.0.0.1
Link 5 (isp1)
Current Scopes: none
Protocols: -DefaultRoute +LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
A user would expect local DNS resolution to be working inside the VRF but not in main; but in reality, DNS resolution works in main but not in VRF.
root@router:~# host google.com
google.com has address 172.217.24.238
google.com has IPv6 address 2404:6800:4005:814::200e
google.com mail is handled by 10 smtp.google.com.
root@router:~# ip vrf exec isp1 host google.com
;; communications error to 127.0.0.53#53: timed out
;; communications error to 127.0.0.53#53: timed out
;; no servers could be reached
This is caused by systemd-resolved
listening explicitly on 127.0.0.53%lo:53
, thus unable to receive any requests from inside a VRF. (It correctly sends the DNS request to the upstream servers since binding the socket on a interface will correctly attach the socket to the linked VRF.)
Linux do try to workaround this issue by using a PBR rule to redirect all local traffic to the local routing table:
root@router:~# ip rule
0: from all lookup local
1000: from all lookup [l3mdev-table]
32765: from all fwmark 0x3e9 lookup 1001 proto static # isp1 table
32766: from all lookup main
32767: from all lookup default
But ip vrf exec
uses a BPF program to redirect all the sockets of a program which rendered this workaround invalid. Also it doesn't work even if net.ipv4.tcp_l3mdev_accept = 1
and net.ipv4.udp_l3mdev_accept = 1
is set because of the explicit interface bind.
Here I'd like to propose 2 changes to make systemd-resolved
work as a normal user would expect in this situation:
Component
systemd-resolved
Is your feature request related to a problem? Please describe
When enabling VRFs DNS resolution will only work on the default VRF with systemd-resolved enabled
Describe the solution you'd like
I'm not sure what the correct solution is here, this bug is to document the limitation of systemd-resolved. Davind Ahern has a great writeup on it - https://people.kernel.org/dsahern/management-vrf-and-dns
Describe alternatives you've considered
Disable systemd-resolved, and just point /etc/resolv.conf to upstream Leave systemd-resolved enabled, only having DNS resolution on the default VRF
The systemd version you checked that didn't have the feature you are asking for
249.11