12

systemd-resolved is a daemon that, among other things, acts as a DNS server by listening IP address 127.0.0.53 on the local loopback interface.

I would like to let the daemon listen to another interface. My use-case is to expose it to docker containers, so that docker containers share the DNS caching provided by systemd-resolved. I know how to configure the host as a DNS server for docker containers, but at least by default, systemd-resolved rejects these DNS queries because they are not coming from the loopback interface, but from the docker bridge interface.

With dnsmasq (a tool similar to systemd-resolved), I did this by adding listen-address=172.17.0.1 to the configuration file. Unfortunately, I couldn't find a systemd-resolved equivalent.

Since systemd-resolved is the default at least on Ubuntu 18.04, I would like a solution that works in this configuration.

Is there a way to configure which interface systemd-resolved listens on?

3
  • 1
    What is your use-case? I mean, why are you employing systemd-resolved as a stub resolver? There are any number of established, purpose-made alternatives, including but not limited to bind, dnsmasq, unbound, etc. Note that this is not a rant or mindless hate on the systemd suite. I'd just like to know what prompted you to pick this particular service. Is there any functionality the others don't offer? – Nubarke May 30 '18 at 15:42
  • 2
    My use case is to have docker that "just works" on my machine and on typical people's machine (e.g. my students, as I'm a teacher). I didn't pick systemd-resolved: my distro (Ubuntu) picked it for me when I upgraded (to 18.04). I can uninstall systemd-resolved and re-install dnsmasq (which I had before), but that's a rather intrusive solution, and in particular not a solution I'd recommend lightly to anyone (for example, I tried installing dnsmasq without uninstalling systemd-resolved. My package manager happily accepted and then my machine went berserk eating 100% CPU for nothing ...). – Matthieu Moy May 31 '18 at 8:04
  • 1
    Thanks for the reply. So I guess the question changes from "why did you pick systemd-resolved" to "why did the Ubuntu mantainers pick systemd-resolved". It seems clear that, at the very least, packages dnsmasq and systemd-resolved should have a breaks relationship. And again, why did the distro maintainers make that choice? Seems rather intrusive. – Nubarke Jun 1 '18 at 8:49
12

You can't. As cristian-rodríguez mentioned above, it was strictly designed to provide services to loopback only.

Not even an alternative solution using net.ipv4.conf.all.route_localnet=1 + iptables NAT (such as https://serverfault.com/questions/211536/iptables-port-redirect-not-working-for-localhost), https://superuser.com/questions/594163/how-do-i-route-a-port-range-in-a-linux-host-to-a-guest-vm), and https://stackoverflow.com/questions/18580637/iptables-redirect-from-external-interface-to-loopbacks-port) will work, since systemd-resolve explicitly inspects if the destination is outside the loopback network. See the code below for static void dns_stub_process_query(Manager *m, DnsStream *s, DnsPacket *p)

    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;
    }

A workaround is to use socat to listen at your docker interface, and forward it to systemd-resolved. The line below does the trick. If required, alter it to listen to TCP:

socat UDP-LISTEN:53,fork,reuseaddr,bind=172.17.0.1 UDP:127.0.0.53:53
6
  • 4
    Apparently this changed. Now we seem to have the DNSStubListenerExtra directive at /etc/systemd/resolved.conf that Takes an IPv4 or IPv6 address to listen on. freedesktop.org/software/systemd/man/… – TCB13 Nov 3 '20 at 23:35
  • @TCB13 Can't get this to work on Debian Buster/Ubuntu 20.04 LTS. Switching to unbound probably – Ray Foss Feb 6 at 16:10
  • @RayFoss that's because systemd/resolved in Debian is an old version that doesn't support DNSStubListenerExtra yet. Yes, I'm also waiting for it ;) – TCB13 Feb 6 at 20:08
  • @TCB13 it runs on 127.0.0.53 which makes it easy to ignore when I stalling unbound/DNSMasq. Turns out my issue wasn't DNS related, instead my ISP was doing Deep packet inspection and blocking domains from CDN's with a low reputation. Incredibly annoying what it took to figure that out. – Ray Foss Feb 7 at 0:39
  • @RayFoss when your ISP does DPI you know it's time to get a VPN. – TCB13 Feb 7 at 10:24
10
+100

Resolved is not intended nor designed for your use-case, but to provide services in the local loopback, thus the listen address is hardcoded.

1

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.