Wie kann systemd-Resolution eine andere Schnittstelle als Loopback abhören?

11

systemd-Resolution ist ein Daemon, der unter anderem als DNS-Server fungiert, indem er die IP-Adresse 127.0.0.53 auf der lokalen Loopback-Schnittstelle überwacht.

Ich möchte den Daemon eine andere Schnittstelle abhören lassen. Mein Anwendungsfall besteht darin, es Docker-Containern zur Verfügung zu stellen, damit Docker-Container das von systemd-aufgelöste DNS-Caching gemeinsam nutzen. Ich weiß, wie der Host als DNS-Server für Docker-Container konfiguriert wird, aber zumindest standardmäßig lehnt systemd-Resolution diese DNS-Abfragen ab, da sie nicht von der Loopback-Schnittstelle, sondern von der Docker-Bridge-Schnittstelle stammen.

Mit dnsmasq (einem Tool ähnlich dem von systemd aufgelösten) habe ich dies durch Hinzufügen listen-address=172.17.0.1zur Konfigurationsdatei getan . Leider konnte ich kein vom System aufgelöstes Äquivalent finden.

Da systemd-Resolution zumindest unter Ubuntu 18.04 die Standardeinstellung ist, möchte ich eine Lösung, die in dieser Konfiguration funktioniert.

Gibt es eine Möglichkeit zu konfigurieren, auf welcher Schnittstelle das vom System aufgelöste Abhören abhört?

Matthieu Moy
quelle
1
Was ist Ihr Anwendungsfall? Ich meine, warum beschäftigst du dich systemd-resolvedals Stub Resolver? Es gibt eine Reihe von etablierten, für diesen Zweck hergestellt Alternativen, einschließlich , aber nicht beschränkt auf bind, dnsmasq, unboundusw. Beachten Sie, dass dies keine rant oder sinnloser Hass auf der systemd Suite. Ich möchte nur wissen, was Sie dazu veranlasst hat, diesen bestimmten Service auszuwählen. Gibt es Funktionen, die die anderen nicht bieten?
Nubarke
1
Mein Anwendungsfall ist ein Docker, der auf meinem Computer und auf dem Computer typischer Leute (z. B. meinen Schülern, da ich Lehrer bin) "nur funktioniert". Ich habe nicht systemd-Resolution ausgewählt: Meine Distribution (Ubuntu) hat es für mich ausgewählt, als ich ein Upgrade durchgeführt habe (auf 18.04). Ich kann systemd-Resolution deinstallieren und dnsmasq neu installieren (was ich vorher hatte), aber das ist eine ziemlich aufdringliche Lösung, und insbesondere keine Lösung, die ich jedem leicht empfehlen würde (zum Beispiel habe ich versucht, dnsmasq zu installieren, ohne systemd- zu deinstallieren). Mein Paketmanager nahm das gerne an und dann wurde mein Computer wahnsinnig und aß 100% CPU für nichts ...).
Matthieu Moy
1
Danke für die Antwort. Ich denke also, die Frage ändert sich von "Warum haben Sie systemd aufgelöst ausgewählt" zu "warum haben die Ubuntu-Mantainer systemd aufgelöst ausgewählt". Es scheint klar, dass zumindest Pakete dnsmasqund systemd-resolvedeine breaksBeziehung haben sollten . Und wieder, warum haben die Distro-Betreuer diese Wahl getroffen? Scheint eher aufdringlich.
Nubarke

Antworten:

9

Resolved ist weder für Ihren Anwendungsfall vorgesehen noch für die Bereitstellung von Diensten im lokalen Loopback vorgesehen. Daher ist die Abhöradresse fest codiert.

Cristian Rodríguez
quelle
3
Hmm, leider scheinen Sie Recht zu haben: Der Code setzt setsockopt (fd, SOL_SOCKET, SO_BINDTODEVICE, "lo", 3)
Matthieu Moy
6

Das kannst du nicht. Wie Cristian-Rodríguez oben erwähnte, war es ausschließlich darauf ausgelegt, Dienste nur für Loopback bereitzustellen.

Nicht einmal eine alternative Lösung mit net.ipv4.conf.all.route_localnet=1+ iptables NAT (wie /server/211536/iptables-port-redirect-not-working-for-localhost ), /superuser/594163 / how-do-i-route-a-port-range-in-a-linux-host-to-a-guest-vm ) und /programming/18580637/iptables-redirect-from -external-interface-to-loopbacks-port ) funktioniert, da systemd-resolve explizit prüft, ob sich das Ziel außerhalb des Loopback-Netzwerks befindet. Siehe den Code unten fürstatic 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;
    }

Eine Problemumgehung besteht darin socat, Ihre Docker-Oberfläche abzuhören und an systemd-Resolution weiterzuleiten. Die folgende Zeile macht den Trick. Ändern Sie es bei Bedarf, um TCP anzuhören:

socat UDP-LISTEN:53,fork,reuseaddr,bind=172.17.0.1 UDP:127.0.0.53:53
Pcgomes
quelle