2

Fedora 33 中的 systemd-resolved DNS resolver

 2 years ago
source link: https://ttys3.dev/post/systemd-resolved-the-default-dns-resolver-in-fedora-33/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Fedora 33 中的 systemd-resolved DNS resolver

2020-12-20

:: 荒野無燈

:: Mod 2020-12-20(0f5a1e0)

#Fedora 

December 20, 2020

Fedora 33 中的 DNS resolver 已经由 nss-dns 默认切换成了 systemd-resolved 简单来说,这意味着 systemd-resolved 将作为daemon程序运行。所有想要将域名转换为网络地址的程序都将与之通信。 这取代了当前默认的查找机制–每个程序单独与远程服务器交谈,并且没有共享缓存。

如有必要, systemd-resolved 将查询远程DNS服务器。 systemd-resolved 是一个“stub resolver” - 它本身不会解析任何域名(通过从根DNS开始并按标签一路径往下查询),而是将查询转发到远程DNS服务器。 其实这种类型的程序我们经常用,比如我们通常用的路由器上一般会用 dnsmasq 做“stub resolver”, 其下的局域网机器,通过DHCP自动获取到DNS后通常是这个路由器自己的LAN IP, 比如常见的 192.168.1.1 等。dnsmasq 自带缓存功能,也就是说一个域名已经解析过了,它不会每次都需要通过与远程DNS服务器通信来解析,而是可以在命中缓存结果的情况下直接返回。 systemd-resolved 的引入,相当于每台 Linux 机器本身已经有了一个类似 dnsmasq 的东西在跑。同时,每台机器对于跑在上面的程序的DNS查询配置,可以更加灵活了(因为split DNS)。

单个daemon程序处理域名解析提供了显著的好处。由于daemon进程会缓存响应结果,因而可以快速响应高频请求的域名。守护进程记得哪些服务器是非响应的,而预先每个程序都必须在超时后自己弄清楚这一点。个别程序仅在本地传输上与守护程序交谈,并从网络中孤立。守护程序支持花哨的规则,该规则指定应使用哪些名称服务器用于哪些域名 - 事实上,本文的其余部分是关于这些规则。

技术相关

来自 https://fedoraproject.org/wiki/Changes/systemd-resolved#Detailed_Description

Enable systemd-resolved by default. glibc will perform name resolution using ’nss-resolve’ rather than ’nss-dns'.

systemd-resolved has been enabled by default in Ubuntu since Ubuntu 16.10, but please note we are doing this differently than Ubuntu has. Ubuntu does not use nss-resolve. Instead, Ubuntu uses the traditional nss-dns provided by glibc upstream, so glibc on Ubuntu continues to read /etc/resolv.conf, as is traditional. This extra step is not useful and not recommended by upstream. We want to follow upstream recommendations in using nss-resolve instead.

服务和命令行工具

查看服务状态:

❯ systemctl status systemd-resolved
● systemd-resolved.service - Network Name Resolution
     Loaded: loaded (/usr/lib/systemd/system/systemd-resolved.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2020-12-20 10:08:05 CST; 11h ago
       Docs: man:systemd-resolved.service(8)
             https://www.freedesktop.org/wiki/Software/systemd/resolved
             https://www.freedesktop.org/wiki/Software/systemd/writing-network-configuration-managers
             https://www.freedesktop.org/wiki/Software/systemd/writing-resolver-clients
   Main PID: 2695 (systemd-resolve)
     Status: "Processing requests..."
      Tasks: 1 (limit: 38311)
     Memory: 13.0M
        CPU: 8.384s
     CGroup: /system.slice/systemd-resolved.service
             └─2695 /usr/lib/systemd/systemd-resolved

查看当前状态:

❯ resolvectl status
Global
         Protocols: LLMNR=resolve -mDNS -DNSOverTLS DNSSEC=no/unsupported
  resolv.conf mode: stub
Current DNS Server: 127.0.0.1:5354
       DNS Servers: 127.0.0.1:5354

DNS解析(老灯这里特意查询了两次,主要是通过二者的消耗时间对比cache的效果):

❯ resolvectl query 163.com
163.com: 123.58.180.7
         123.58.180.8

-- Information acquired via protocol DNS in 7.7ms.
-- Data is authenticated: no
❯ resolvectl query 163.com
163.com: 123.58.180.7
         123.58.180.8

-- Information acquired via protocol DNS in 624us.
-- Data is authenticated: no

resolvectl statistics 可查询统计信息,比如缓存命中率,缓存条目数量等

resolvectl flush-caches 可清除查询缓存

其它参数可通过resolvectl -h 查看.

特别注意

systemd-resolved 不能当作局域网DNS cache服务器使用,它只能用于本机,因为它监听的是lo (loopback网卡)

stackoverflow上已经有大佬回复了,甚至把相关的代码都贴出来了. https://unix.stackexchange.com/a/549315/405754

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

参考文档

https://fedoramagazine.org/systemd-resolved-introduction-to-split-dns/ https://www.freedesktop.org/software/systemd/man/systemd-resolved.service.html https://fedoraproject.org/wiki/Changes/systemd-resolved


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK