如何允许 systemd-resolved 侦听环回以外的接口?

Mat*_*Moy 14 dns systemd docker systemd-resolved

systemd-resolved 是一个守护进程,除其他外,它通过侦听本地环回接口上的 IP 地址 127.0.0.53 充当 DNS 服务器。

我想让守护进程监听另一个接口。我的用例是将它公开给 docker 容器,以便 docker 容器共享由 systemd-resolved 提供的 DNS 缓存。我知道如何将主机配置为 docker 容器的 DNS 服务器,但至少在默认情况下,systemd-resolved 拒绝这些 DNS 查询,因为它们不是来自环回接口,而是来自 docker 桥接接口。

使用 dnsmasq(类似于 systemd-resolved 的工具),我通过添加listen-address=172.17.0.1到配置文件. 不幸的是,我找不到 systemd 解析的等效项。

由于 systemd-resolved 至少在 Ubuntu 18.04 上是默认设置,因此我想要一个适用于此配置的解决方案。

有没有办法配置 systemd-resolved 侦听的接口?

小智 13

你不能。正如上面提到的 cristian-rodríguez,它严格设计为仅提供环回服务。

甚至不使用替代溶液net.ipv4.conf.all.route_localnet=1+ iptables的NAT(如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)和/sf/ask/1300644621/ -external-interface-to-loopbacks-port ) 将起作用,因为 systemd-resolve 明确检查目的地是否在环回网络之外。请参阅下面的代码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;
    }
Run Code Online (Sandbox Code Playgroud)

一种解决方法是使用socat侦听您的 docker 界面,并将其转发到 systemd-resolved。下面的行可以解决问题。如果需要,更改它以侦听 TCP:

socat UDP-LISTEN:53,fork,reuseaddr,bind=172.17.0.1 UDP:127.0.0.53:53
Run Code Online (Sandbox Code Playgroud)

  • 显然这改变了。现在我们似乎在 `/etc/systemd/resolved.conf` 中有 `DNSStubListenerExtra` 指令,它`需要一个 IPv4 或 IPv6 地址来监听`。https://www.freedesktop.org/software/systemd/man/resolved.conf.html#DNSStubListenerExtra= (4认同)

小智 12

Resolved 不是为您的用例而设计的,而是为了在本地环回中提供服务,因此监听地址是硬编码的。

  • 嗯,不幸的是,您似乎是对的:代码确实 [setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, "lo", 3)](https://github.com/systemd/systemd/blob/4d09e1c8bab1d684172b1f277f32138259b30d -dns-stub.c#L425-L427) (3认同)

小智 12

自 systemd-resolved版本 247(提交1f05101f及后续版本)以来,通过设置 可以自由地自由实现所需的监听地址配置DNSStubListenerExtra

\n

地址、端口和协议(tcp/udp)可多次配置。甚至可以通过设置DNSStubListener为 false 来禁用 (tcp/udp) 127.0.0.53:53 处的默认侦听器。

\n

systemd 解析的配置文件/etc/systemd/resolved.conf在其注释 \xe2\x80\x93 中显示了这一点,例如在 ubuntu impish (21.10) 中。

\n
# systemd --version\nsystemd 248 (248.3-1ubuntu8)\n...\n\n# man resolved.conf\n...\nDNSStubListener=\n       Takes a boolean argument or one of "udp" and "tcp". If "udp", a DNS stub resolver will listen for UDP requests on address 127.0.0.53 port 53. If "tcp",\n       the stub will listen for TCP requests on the same address and port. If "yes" (the default), the stub listens for both UDP and TCP requests. If "no", the\n       stub listener is disabled.\n\n       Note that the DNS stub listener is turned off implicitly when its listening address and port are already in use.\n\nDNSStubListenerExtra=\n   Takes an IPv4 or IPv6 address to listen on. The address may be optionally prefixed with a protocol name ("udp" or "tcp") separated with ":". If the\n   protocol is not specified, the service will listen on both UDP and TCP. It may be also optionally suffixed by a numeric port number with separator ":".\n   When an IPv6 address is specified with a port number, then the address must be in the square brackets. If the port is not specified, then the service\n   uses port 53. Note that this is independent of the primary DNS stub configured with DNSStubListener=, and only configures additional sockets to listen\n   on. This option can be specified multiple times. If an empty string is assigned, then the all previous assignments are cleared. Defaults to unset.\n\n   Examples:\n\n       DNSStubListenerExtra=192.168.10.10\n       DNSStubListenerExtra=2001:db8:0:f102::10\n       DNSStubListenerExtra=192.168.10.11:9953\n       DNSStubListenerExtra=[2001:db8:0:f102::11]:9953\n       DNSStubListenerExtra=tcp:192.168.10.12\n       DNSStubListenerExtra=udp:2001:db8:0:f102::12\n       DNSStubListenerExtra=tcp:192.168.10.13:9953\n       DNSStubListenerExtra=udp:[2001:db8:0:f102::13]:9953\n...\n
Run Code Online (Sandbox Code Playgroud)\n

这是一个明确的答案,方便参考。@TCB13已经将其表述为评论。

\n