systemd / systemd

The systemd System and Service Manager
https://systemd.io
GNU General Public License v2.0
13.3k stars 3.8k forks source link

systemd-resolved: allow specifying CIDRs for reverse lookup routing #21526

Open danderson opened 2 years ago

danderson commented 2 years ago

Is your feature request related to a problem? Please describe.

systemd-resolved supports search and route-only domains on a per-interface basis, which is fantastic for implementing a variety of advance DNS routing setups. However, one thing that's a little cumbersome right now is configuring routes for reverse lookups on IPs when the IP range doesn't fall neatly on an 8-bit (for ipv4) or 4-bit (for ipv6) boundary.

For example, Tailscale configures resolved to route reverse lookups to 100.64.0.0/10 to tailscale0's nameservers, but /10 doesn't decompose cleanly into the in-addr.arpa form, so we end up having to register 65 separate DNS suffixes to capture all of it:

$ resolvectl status tailscale0
Link 18 (tailscale0)
    Current Scopes: DNS
         Protocols: -DefaultRoute -LLMNR -mDNS -DNSOverTLS
                    DNSSEC=no/unsupported
Current DNS Server: 100.100.100.100
       DNS Servers: 100.100.100.100
        DNS Domain: corp.ts.net
                    tailscale.com.beta.tailscale.net
                    ts-dns.test ts.tailscale.com
                    ~0.e.1.a.c.5.1.1.a.7.d.f.ip6.arpa
                    ~100.100.in-addr.arpa ~101.100.in-addr.arpa
                    ~102.100.in-addr.arpa ~103.100.in-addr.arpa
                    ~104.100.in-addr.arpa ~105.100.in-addr.arpa
                    ~106.100.in-addr.arpa ~107.100.in-addr.arpa
                    ~108.100.in-addr.arpa ~109.100.in-addr.arpa
                    ~110.100.in-addr.arpa ~111.100.in-addr.arpa
                    ~112.100.in-addr.arpa ~113.100.in-addr.arpa
                    ~114.100.in-addr.arpa ~115.100.in-addr.arpa
                    ~116.100.in-addr.arpa ~117.100.in-addr.arpa
                    ~118.100.in-addr.arpa ~119.100.in-addr.arpa
                    ~120.100.in-addr.arpa ~121.100.in-addr.arpa
                    ~122.100.in-addr.arpa ~123.100.in-addr.arpa
                    ~124.100.in-addr.arpa ~125.100.in-addr.arpa
                    ~126.100.in-addr.arpa ~127.100.in-addr.arpa
                    ~64.100.in-addr.arpa ~65.100.in-addr.arpa
                    ~66.100.in-addr.arpa ~67.100.in-addr.arpa
                    ~68.100.in-addr.arpa ~69.100.in-addr.arpa
                    ~70.100.in-addr.arpa ~71.100.in-addr.arpa
                    ~72.100.in-addr.arpa ~73.100.in-addr.arpa
                    ~74.100.in-addr.arpa ~75.100.in-addr.arpa
                    ~76.100.in-addr.arpa ~77.100.in-addr.arpa

This makes the resolvectl output quite spammy, and makes life difficult for us in the client (we had to write a bunch of annoying bit-twiddling code to calculate the decomposition of prefixes into blocks of /8, /16, /24 and /32.

Describe the solution you'd like

I would like to extend the SetLinkDomains DBus method to accept CIDR prefix strings, in addition to DNS suffixes. so that clients can provide e.g. ~100.64.0.0/10 to mean "I want to handle PTR lookups for IPs that fall within 100.64.0.0/10".

I think this is a backwards-compatible extension to make, because / is not a valid character in DNS names, so resolved can unambiguously distinguish DNS suffixes from CIDRs by looking for the presence of a /.

Similarly, resolvectl domain should support this syntax extension, and the output of resolvectl status should list CIDRs instead of exploded .arpa suffixes where appropriate.

The spammy output above would look like this:

Link 18 (tailscale0)
    Current Scopes: DNS
         Protocols: -DefaultRoute -LLMNR -mDNS -DNSOverTLS
                    DNSSEC=no/unsupported
Current DNS Server: 100.100.100.100
       DNS Servers: 100.100.100.100
        DNS Domain: corp.ts.net
                    tailscale.com.beta.tailscale.net
                    ts-dns.test ts.tailscale.com
                    ~fd7a:115c:a1e0/48 ~100.64.0.0/10

I'm willing to work on a PR to implement this, but I figured I should file a bug first to see if anyone hates this :)

Describe alternatives you've considered

The existing method of explosively decomposing the CIDR client-side works, but is hard to wield for the client and makes the output of resolvectl ugly.

We could also add a completely separate DBus method, something like SetLinkCIDRs, but since the CIDRs are used for the same purpose as the domain suffixes, and SetLinkDomains already supports non-DNS syntax in the form of the ~ prefix, IMO it's fine to further extend SetLinkDomains instead of expanding the DBus API surface.

The systemd version you checked that didn't have the feature you are asking for

systemd 247 (247)
+PAM +AUDIT -SELINUX +IMA +APPARMOR +SMACK -SYSVINIT +UTMP +LIBCRYPTSETUP +GCRYPT -GNUTLS +ACL +XZ +LZ4 -ZSTD +SECCOMP +BLKID -ELFUTILS +KMOD +IDN2 -IDN +PCRE2 default-hierarchy=unified

I also checked the bugtracker before filing, but didn't find anything obviously related to this proposal.

poettering commented 2 years ago

makes sense

pemensik commented 2 weeks ago

Oh please, have it listed in a separate way to domains. Without ~ prefix, that is not needed for IP address.