<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>systemd-resolved on Chaney&#39;s MoonBook</title>
    <link>https://chaneyzorn.github.io/tags/systemd-resolved/</link>
    <description>Recent content in systemd-resolved on Chaney&#39;s MoonBook</description>
    <follow_challenge>
        <feedId>94402801171278848</feedId>
        <userId>60932538427591680</userId>
    </follow_challenge>
    <image>
      <title>Chaney&#39;s MoonBook</title>
      <url>https://chaneyzorn.github.io/cm/chaney-cover.jpg</url>
      <link>https://chaneyzorn.github.io/cm/chaney-cover.jpg</link>
    </image>
    <generator>Hugo(0.160.1) -- gohugo.io</generator>
    <language>zh</language>
    <managingEditor>chaneyzorn#gmail#com (ChaneyZorn)</managingEditor>
    <webMaster>chaneyzorn#gmail#com (ChaneyZorn)</webMaster>
    <copyright>Copyright © ChaneyZorn | CC BY-NC-ND 4.0 |</copyright>
    <lastBuildDate>Tue, 24 Dec 2024 14:37:03 +0800</lastBuildDate>
    <atom:link href="https://chaneyzorn.github.io/tags/systemd-resolved/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>AdGuard DNS 与 systemd-resolved</title>
      <link>https://chaneyzorn.github.io/codes/adguard-dns-systemd-resolved/</link>
      <pubDate>Tue, 24 Dec 2024 14:37:03 +0800</pubDate><author>chaneyzorn#gmail#com (ChaneyZorn)</author>
      <guid>https://chaneyzorn.github.io/codes/adguard-dns-systemd-resolved/</guid>
      <description><![CDATA[<p>我在家中使用零刻和树莓派自托管一些服务之后，想通过自定义域名（比如<code>pve.home.io</code>）的方式来访问这些服务，这样就可以避免记忆哪些服务在哪些节点上（以及对应的端口是什么）。</p>
<p>具体的做法是，将自定义的域名统一解析到 API Gateway 的 IP 地址上，然后使用 Gateway 的路由功能，根据请求中的具体域名，将请求代理到对应的节点和端口上：</p>
<p><img alt="域名至对应服务" loading="lazy" src="/codes/adguard-dns-systemd-resolved/asserts/dns-api-gateway.svg#center"></p>
<p>我使用的 DNS 服务是 <a href="https://github.com/AdguardTeam/AdGuardHome">AdGuard Home</a>，它默认监听在 <code>0.0.0.0:53/udp</code> 上，但是在使用 systemd 系列组件的节点上，systemd-resolved 会监听在 <code>127.0.0.53:53/dup</code> 上，因此会导致端口冲突。AdGuard <a href="https://github.com/AdguardTeam/AdGuardHome/wiki/Docker#resolved">官方 wiki 给出的解决方式</a>是修改 resolved 的配置，停止监听 <code>127.0.0.53:53</code>。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="hl"><span class="lnt"> 3
</span></span><span class="hl"><span class="lnt"> 4
</span></span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">$ sudo netstat -uanp
</span></span><span class="line"><span class="cl">Proto Recv-Q Send-Q Local Address           Foreign Address  PID/Program name
</span></span><span class="line hl"><span class="cl">udp        <span class="m">0</span>      <span class="m">0</span> 127.0.0.54:53           0.0.0.0:*        431/systemd-resolve
</span></span><span class="line hl"><span class="cl">udp        <span class="m">0</span>      <span class="m">0</span> 127.0.0.53:53           0.0.0.0:*        431/systemd-resolve
</span></span><span class="line"><span class="cl">udp        <span class="m">0</span>      <span class="m">0</span> 192.168.0.2:68          0.0.0.0:*        359/systemd-network
</span></span><span class="line"><span class="cl">udp        <span class="m">0</span>      <span class="m">0</span> 0.0.0.0:5353            0.0.0.0:*        431/systemd-resolve
</span></span><span class="line"><span class="cl">udp        <span class="m">0</span>      <span class="m">0</span> 0.0.0.0:5355            0.0.0.0:*        431/systemd-resolve
</span></span><span class="line"><span class="cl">udp6       <span class="m">0</span>      <span class="m">0</span> fe80::be24:11ff:fe1:546 :::*             359/systemd-network
</span></span><span class="line"><span class="cl">udp6       <span class="m">0</span>      <span class="m">0</span> :::5353                 :::*             431/systemd-resolve
</span></span><span class="line"><span class="cl">udp6       <span class="m">0</span>      <span class="m">0</span> :::5355                 :::*             431/systemd-resolve
</span></span></code></pre></td></tr></table>
</div>
</div><p>但如果希望避免侵入系统默认的运维配置，就需要另一种方案。</p>
<blockquote>
<p><strong>更新（2026-08-26）</strong>：补充 Ubuntu 24.04 Server 上 <code>systemd-resolved</code> 与 <code>libnss-resolve</code> 的差异，以及开启 mDNS 的完整配置条件。详见后文「Ubuntu 24.04 上开启 mDNS 的完整条件」一节。</p>
</blockquote>
<p>要找到不侵入系统默认配置的替代方案，需要先理解 systemd-resolved 实际在做什么。</p>
<h2 id="1-systemd-resolved-的作用">1. systemd-resolved 的作用</h2>
<p>resolved 对运行在本地的应用程序提供了一个 DNS 中间层，这个中间层的作用是（<a href="https://man.archlinux.org/man/systemd-resolved.8">参考：systemd-resolved(8)</a>）：</p>
<ol>
<li>对上游的 DNS 记录进行缓存，在网络配置发生变化时自动刷新缓存；</li>
<li>对上游的 DNSSEC 进行验证；</li>
<li>支持将来自本地的 DNS 请求转换为 DoT 发送给上游（暂不支持 DoH，见 <a href="https://github.com/systemd/systemd/issues/8639">issue #8639</a>）；</li>
<li>提供 mDNS 和 LLMNR 服务，以及 link-local 地址反向查找设备名；</li>
<li>提供本地特定别名的地址解析，比如：<code>&lt;hostname&gt;</code>、<code>localhost</code>、<code>*.localhost</code>、<code>_gateway</code>、<code>_outbound</code>，以及在 <code>/etc/hosts</code> 中的映射；</li>
</ol>
<h3 id="11-相关术语解释">1.1 相关术语解释</h3>
<ul>
<li><strong>DNS</strong>：将域名转换为对应的 IP 地址；</li>
<li><strong>DNSSEC</strong>：服务方在 DNS 响应中加上私钥签名，接收方使用公钥验证签名以确保服务方的真实性；</li>
<li><strong>DoT</strong>：DNS over TLS，客户端与 DNS 服务端使用 TLS 加密连接来传输查询和响应；</li>
<li><strong>DoH</strong>：DNS over HTTPS，客户端与 DNS 服务端使用 HTTPS 协议来传输查询和响应；</li>
<li><strong>mDNS</strong>：MulticastDNS，一种用于局域网中设备相互发现的去中心式的协议。传统 DNS 是中心式的，且域名和地址间的映射相对固定，无法及时反映局域网中设备加入和离开（且 IP 地址可能会被随机分配）的场景。mDNS 可以让这些设备方便地互相找到并通信，而不需要复杂的 DNS 配置。比如直接使用 <code>&lt;hostname&gt;.local</code> 来访问局域网中对应的 <code>&lt;hostname&gt;</code> 节点，而无需预先知道该节点的 IP 地址并手动进行 DNS 配置。</li>
<li><strong>LLMNR</strong>：和 mDNS 类似，主要流行于 windows 系统，可以使用类似 <code>MY-OFFICE-PC</code> 的名称来访问局域网中的设备；</li>
<li><strong>link-local addresses</strong>：仅用于局域网中<strong>单个网段</strong>内部通讯的地址，当无 DHCP 可用时设备可能会自动随机生成一个这样的本地地址。IPv4 地址范围是 <code>169.254.0.0 - 169.254.255.255</code>，IPv6 地址范围是 <code>fe80::/10</code>。虽然 IPv4 本地地址一般仅在没有 DHCP 时才会被自动生成(或被手动配置)，但当 IPv6 可用时，IPv6 本地地址却总是自动生成并一直存在的（<a href="https://www.wikiwand.com/en/articles/Link-local_address">参考：Link-local address</a>）。</li>
</ul>
<p><code>fe80</code> 正是这类地址的典型前缀：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">$ ip a <span class="p">|</span> grep <span class="s2">&#34;scope link&#34;</span>
</span></span><span class="line"><span class="cl">    inet6 fe80::be24:11ff:fe17:ef6c/64 scope link proto kernel_ll
</span></span><span class="line"><span class="cl">    inet6 fe80::42:6aff:fe71:bd0e/64 scope link proto kernel_ll
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="2-systemd-resolved-提供的接口形式">2. systemd-resolved 提供的接口形式</h2>
<p>resolved 使用以下几种接口对本地应用程序提供服务（<a href="https://man.archlinux.org/man/systemd-resolved.8">参考：systemd-resolved(8)</a>）：</p>
<ol>
<li>D-Bus 接口 <a href="https://man.archlinux.org/man/org.freedesktop.resolve1.5.en"><code>org.freedesktop.resolve1</code></a>；</li>
<li>UNIX socket <code>/run/systemd/resolve/io.systemd.Resolve</code>；</li>
<li>glibc 的 <a href="https://man.archlinux.org/man/getaddrinfo.3.en"><code>getaddrinfo</code></a> 等相关函数（通过使用 <a href="https://man.archlinux.org/man/nss-resolve.8.en"><code>nss-resolve</code></a> 模块）;</li>
<li>DNSStubListener：使用传统的 DNS 访问 <code>127.0.0.53:53</code> 和 <code>127.0.0.54:53</code>，涵盖 UDP 和 TCP；</li>
</ol>
<p>另外 resolved 还提供了本节点在局域网中的 mDNS 和 LLMNR 服务：</p>
<ul>
<li>mDNS：监听在 <code>0.0.0.0:5353/udp</code>；</li>
<li>LLMNR：监听在 <code>0.0.0.0:5355</code>，涵盖 UDP 和 TCP；</li>
</ul>
<p><img alt="本地应用使用 resolved" loading="lazy" src="/codes/adguard-dns-systemd-resolved/asserts/app-resolved.svg#center"></p>
<p>注意上图中标注的网络范围。各个接口的使用方式各不相同，且支持的特性也存在差异，更多信息请参考 <a href="https://man.archlinux.org/man/systemd-resolved.8">man page</a> 和 <a href="https://systemd.io/WRITING_RESOLVER_CLIENTS/">systemd 官方相关文档</a>。</p>
<h2 id="3-127005353-和-127005453-有什么区别">3. 127.0.0.53:53 和 127.0.0.54:53 有什么区别？</h2>
<p>文章开头的 UDP 端口列表中，不仅存在 <code>127.0.0.53:53</code>，还存在一个 <code>127.0.0.54:53</code>。这两个本地 53 端口监听分别承担什么功能？它们的区别是什么？</p>
<p>如上文中介绍的，对于使用 mDNS 和 LLMNR 的局域网设备，它们的名称和 IP 地址的映射并不是由中心化的 DNS 服务器管理的，所使用的协议也不是监听在 53 端口的传统 DNS 协议，因此对于这些特殊的设备名查询 IP 地址并不能走传统的 DNS 协议。</p>
<p>resolved 作为中间层增加了对 mDNS 和 LLMNR 的支持，因此可以将局域网设备名解析为 IP 地址。这一功能无法架设在传统 DNS 协议之上，但将解析结果暴露在 DNS 接口中是可行的，这就是 <code>127.0.0.53:53</code> 额外提供的能力。该地址还会提供 DNSSEC 校验。</p>
<p>而 <code>127.0.0.54:53</code> 仅是上游 DNS 服务器的转发代理，它既不提供 mDNS 和 LLMNR 查询结果，也不会校验 DNSSEC，但仍然支持将请求转换为 DoT 发送给上游（<a href="https://man.archlinux.org/man/systemd-resolved.8">参考：systemd-resolved(8)</a>）。</p>
<p>在被 systemd-resolved 接管的 <code>/etc/resolv.conf</code> 文件中，指定的 <code>nameserver</code> 就是 <code>127.0.0.53</code>。关于 resolved 接管 <code>resolv.conf</code> 文件的相关信息，请参考后面小节。</p>
<h2 id="4-glibc-的-getaddrinfo-名称解析">4. glibc 的 getaddrinfo 名称解析</h2>
<p>glibc 的一些库函数使用 <code>/etc/nsswitch.conf</code> 文件来控制其行为，<code>nsswitch</code> 表示 <a href="https://man.archlinux.org/man/nsswitch.conf.5.en">The GNU Name Service Switch (NSS)</a>。</p>
<p>上文中提到的 <code>nss-resolve</code> 模块即是配合 glibc 的 <code>getaddrinfo</code> 函数，将 DNS 请求交由 systemd-resolved 来处理，这个行为就配置于 <code>/etc/nsswitch.conf</code> 的 <code>hosts</code> 项中。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="hl"><span class="lnt">12
</span></span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">$ cat /etc/nsswitch.conf
</span></span><span class="line"><span class="cl"><span class="c1"># Name Service Switch configuration file.</span>
</span></span><span class="line"><span class="cl"><span class="c1"># See nsswitch.conf(5) for details.</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">passwd: files systemd
</span></span><span class="line"><span class="cl">group: files <span class="o">[</span><span class="nv">SUCCESS</span><span class="o">=</span>merge<span class="o">]</span> systemd
</span></span><span class="line"><span class="cl">shadow: files systemd
</span></span><span class="line"><span class="cl">gshadow: files systemd
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">publickey: files
</span></span><span class="line"><span class="cl">
</span></span><span class="line hl"><span class="cl">hosts: mymachines resolve <span class="o">[</span>!UNAVAIL<span class="o">=</span><span class="k">return</span><span class="o">]</span> files myhostname dns
</span></span><span class="line"><span class="cl">networks: files
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">protocols: files
</span></span><span class="line"><span class="cl">services: files
</span></span><span class="line"><span class="cl">ethers: files
</span></span><span class="line"><span class="cl">rpc: files
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">netgroup: files
</span></span></code></pre></td></tr></table>
</div>
</div><p><code>nss-resolve</code> 只是 <code>getaddrinfo</code> 解析流程中的一个环节，前后还存在多个其他模块：</p>
<ul>
<li><code>mymachines</code>：<a href="https://man.archlinux.org/man/nss-mymachines.8.en"><code>nss-mymachines</code></a> 模块，让 systemd-machined 解析由其管理的容器和虚拟机名称记录；</li>
<li><code>resolve</code>：<a href="https://man.archlinux.org/man/nss-resolve.8.en"><code>nss-resolve</code></a> 模块，让 systemd-resolved 解析由其管理的 DNS 记录，包括 mDNS 和 LLMNR；</li>
<li><code>[!UNAVAIL=return]</code>：如果上述解析模块可用，则跳过后续的解析模块（<a href="https://man.archlinux.org/man/nsswitch.conf.5.en">参考：nsswitch.conf(5)</a>）；</li>
<li><code>files</code>：nss-files 模块，对于 <code>hosts</code> 配置项来说，这个文件是指 <a href="https://man.archlinux.org/man/hosts.5.en"><code>/etc/hosts</code></a>。resolved 已提供同样的功能；</li>
<li><code>myhostname</code>：<a href="https://man.archlinux.org/man/nss-myhostname.8.en"><code>nss-myhostname</code></a> 模块，解析 <code>&lt;hostname&gt;</code>、<code>*localhost</code>、<code>_gateway</code>、<code>_outbound</code>。resolved 已提供同样的功能；</li>
<li><code>dns</code>：传统的 nss-dns 模块，将查询发送到 DNS 服务器，通过 <code>/etc/resolv.conf</code> 配置（<a href="https://github.com/bminor/glibc/blob/master/resolv/README">参考：glibc resolv README</a>）。resolved 已提供同样的功能，且接管了 <code>/etc/resolv.conf</code> 文件，并将 <code>nameserver</code> 配置为了 <code>127.0.0.53</code>；</li>
</ul>
<p>除这些模块外，如果安装了 <a href="https://github.com/avahi">Avahi</a>，也可以使用 <a href="https://github.com/avahi/nss-mdns"><code>nss-mdns</code></a> 模块，它会提供 mDNS 查询结果。systemd-resolved 本身已包含这一功能。</p>
<blockquote>
<p><strong>注意（Ubuntu 24.04 Server）</strong>：<code>systemd-resolved</code> 服务默认已经安装并启用，但 <code>libnss_resolve.so.2</code> 所在的 <code>libnss-resolve</code> 包<strong>默认不安装</strong>。如果直接照搬上面的 <code>hosts: ... resolve ...</code> 配置而不安装该包，glibc 加载 NSS 模块会失败，导致 <code>getaddrinfo</code> 返回 <code>Name or service not known</code>。需要手动安装：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt update
</span></span><span class="line"><span class="cl">sudo apt install libnss-resolve
</span></span></code></pre></td></tr></table>
</div>
</div><p>安装后库文件位于 <code>/usr/lib/x86_64-linux-gnu/libnss_resolve.so.2</code>。更多 Ubuntu 下的 mDNS 配置细节见后文「Ubuntu 24.04 上开启 mDNS 的完整条件」一节。</p>
</blockquote>
<h2 id="5-systemd-resolved-接管-etcresolvconf-的方式">5. systemd-resolved 接管 /etc/resolv.conf 的方式</h2>
<p>如上文中提及的，当程序使用 glibc 访问 DNS 时，DNS 相关信息会在 <a href="https://man.archlinux.org/man/resolv.conf.5.en"><code>/etc/resolv.conf</code></a> 文件中进行配置。一些应用程序（比如 golang）也可能按照这一惯例来自行实现 <code>resolv.conf</code> 配置文件的解析并直接访问 DNS 服务。出于这一原因，为了保持兼容性，systemd-resolved 使用了如下几种形式来接管 <code>/etc/resolv.conf</code>：</p>
<ol>
<li><strong>stub 模式</strong>：当 DNSStubListener 处于启用状态时，使用软链接 <code>/etc/resolv.conf -&gt; /run/systemd/resolve/stub-resolv.conf</code> 的方式接管配置文件，该文件会将 <code>nameserver</code> 配置为 <code>127.0.0.53</code>；这是 resolved 推荐的模式；</li>
<li><strong>static 模式</strong>：使用软链接 <code>/etc/resolv.conf -&gt; /usr/lib/systemd/resolv.conf</code> 的方式接管配置文件，该文件会将 <code>nameserver</code> 配置为 <code>127.0.0.53</code>；</li>
<li><strong>uplink 模式</strong>：使用软链接 <code>/etc/resolv.conf -&gt; /run/systemd/resolve/resolv.conf</code> 的方式接管配置文件，该文件会将 <code>nameserver</code> 直接配置为 resolved 已知的上游 DNS 列表，resolved 会时刻保持其中的内容为最新；若应用程序绕过本地接口而直接使用上游 DNS，将不会提供 mDNS 和 LLMNR 等服务；该模式即为 AdGuard wiki 中提及的模式；</li>
<li><strong>foreign 模式</strong>：由其他的软件包或管理员所管理的 <code>/etc/resolv.conf</code> 文件，这种情况下 resolved 并不是文件的提供者而是消费者，当 resolved 自己的<a href="https://man.archlinux.org/man/resolved.conf.5.en">配置文件</a>中没有显式指定上游 DNS 时，反而会根据该文件来配置上游 DNS；若文件中 <code>nameserver</code> 为 <code>127.0.0.53</code>，虽然形式上是 foreign 模式，但实际上等同于 stub 模式。</li>
</ol>
<p>可以使用 <code>resolvectl status</code> 命令来查看 <code>resolv.conf</code> 的当前模式。</p>
<p>systemd-networkd、NetworkManager 和 iwd 等软件可以通过 <code>/etc/resolv.conf</code> 软链接探查到 resolved，并与之配合来完成 DNS 配置。但传统依赖 <a href="https://man.archlinux.org/man/resolvconf.8.en">resolvconf 工具</a>的程序则无法配合 resolved 完成配置，需要安装 <code>systemd-resolvconf</code> 来伪装 resolvconf 工具（<a href="https://wiki.archlinux.org/title/Systemd-resolved#Setting_DNS_servers">参考：ArchWiki</a>）。</p>
<p><strong>注意</strong>：</p>
<ul>
<li>systemd-resolved 自己的配置文件名称为 <code>resolved.conf</code>，注意与 <code>/etc/resolv.conf</code> 进行区分；</li>
<li>man page 中未提及的一点是：当 DNSStubListener 处于停用状态时，<code>stub-resolv.conf</code> 又会变为软链接指向 <code>/run/systemd/resolve/resolv.conf</code>，这种情况下的 stub 模式实际上等同于 uplink 模式；</li>
</ul>
<h2 id="6-其他值得注意的行为">6. 其他值得注意的行为</h2>
<p>基于上述文档，整理出以下几点：</p>
<ol>
<li>在运行有 systemd-resolved 的节点之间，无需额外安装 Avahi 即可使用 mDNS 功能，即用 <code>&lt;hostname&gt;.local</code> 来访问对应的节点；并且还可以使用 LLMNR 功能，即用 <code>&lt;hostname&gt;</code> 来访问对应节点。在 Arch 等默认集成 <code>libnss-resolve</code> 的发行版上这一体验是开箱即用的，但在 Ubuntu 24.04 Server 上还需要额外配置，详见后文「Ubuntu 24.04 上开启 mDNS 的完整条件」一节；</li>
<li><strong>注</strong>：macOS 开箱支持 mDNS，但不支持 LLMNR；</li>
<li>ping <code>*.localhost</code> 总是解析到 <code>127.0.0.1</code> 或 <code>::1</code>，比如 ping <code>random-test.localhost</code>。匹配的通式是 <code>localhost</code>、<code>*.localhost</code>、<code>localhost.localdomain</code>、<code>*.localhost.localdomain</code>。</li>
<li>还有这些特殊的本地名称也是可以 ping 的：
<ol>
<li><code>_gateway</code>：解析到网关的地址；</li>
<li><code>_outbound</code>：解析到与网关进行通讯的本地地址；</li>
<li><code>_localdnsstub</code> 固定解析到 <code>127.0.0.53</code>（无论是否开启了 DNSStubListener）；</li>
<li><code>_localdnsproxy</code> 固定解析到 <code>127.0.0.54</code>（无论是否开启了 DNSStubListener）；</li>
</ol>
</li>
<li>tailscale 是通过 D-Bus 接口配合 systemd-resolved 来配置 DNS 的：<a href="https://github.com/tailscale/tailscale/blob/main/net/dns/resolved.go"><code>tailscale/blob/main/net/dns/resolved.go</code></a>；</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Dec 24 21:47:17 chaney-pi3 systemd[1]: Started Network Name Resolution.
</span></span><span class="line"><span class="cl">Dec 24 21:47:25 chaney-pi3 systemd-resolved[160303]: tailscale0: Bus client set default route setting: yes
</span></span><span class="line"><span class="cl">Dec 24 21:47:25 chaney-pi3 systemd-resolved[160303]: tailscale0: Bus client set LLMNR setting: no
</span></span><span class="line"><span class="cl">Dec 24 21:47:25 chaney-pi3 systemd-resolved[160303]: tailscale0: Bus client set MulticastDNS setting: no
</span></span><span class="line"><span class="cl">Dec 24 21:47:25 chaney-pi3 systemd-resolved[160303]: tailscale0: Bus client set DNSSEC setting: no
</span></span><span class="line"><span class="cl">Dec 24 21:47:25 chaney-pi3 systemd-resolved[160303]: tailscale0: Bus client set DNSOverTLS setting: no
</span></span><span class="line"><span class="cl">Dec 24 21:47:25 chaney-pi3 systemd-resolved[160303]: Flushed all caches.
</span></span><span class="line"><span class="cl">Dec 24 21:48:30 chaney-pi3 systemd-resolved[160303]: Using degraded feature set UDP instead of UDP+EDNS0 for DNS server 192.168.0.2.
</span></span><span class="line"><span class="cl">Dec 24 21:50:40 chaney-pi3 systemd-resolved[160303]: tailscale0: Bus client set DNS server list to: 100.100.100.100
</span></span><span class="line"><span class="cl">Dec 24 21:50:40 chaney-pi3 systemd-resolved[160303]: tailscale0: Bus client set search domain list to: tailxxxxx.ts.net., ......
</span></span><span class="line"><span class="cl">Dec 24 21:50:40 chaney-pi3 systemd-resolved[160303]: tailscale0: Bus client set default route setting: no
</span></span><span class="line"><span class="cl">Dec 24 21:50:40 chaney-pi3 systemd-resolved[160303]: Flushed all caches.
</span></span><span class="line"><span class="cl">Dec 24 21:51:03 chaney-pi3 systemd-resolved[160303]: Using degraded feature set UDP instead of UDP+EDNS0 for DNS server 100.100.100.100.
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="7-ubuntu-2404-上开启-mdns-的完整条件">7. Ubuntu 24.04 上开启 mDNS 的完整条件</h2>
<p>Arch Linux 上 <code>systemd-resolved</code> 与 <code>libnss-resolve</code> 默认已经协同工作，因此 mDNS 基本开箱即用；但 Ubuntu 24.04 Server 上需要手动把缺失的层级补齐，否则 <code>&lt;hostname&gt;.local</code> 无法解析。</p>
<h3 id="71-需要补齐的几项配置">7.1 需要补齐的几项配置</h3>
<p>要让 <code>&lt;hostname&gt;.local</code> 在 Ubuntu 24.04 Server 上正常解析，需要把下面几项都配置好。它们分别对应不同的层面，缺少任何一项都可能使 mDNS 无法正常工作。</p>
<p><strong>首先是 NSS 插件。</strong> Ubuntu 24.04 Server 默认已经运行了 <code>systemd-resolved</code>，但 <code>libnss_resolve.so.2</code> 所在的 <code>libnss-resolve</code> 包默认并没有安装。这个库负责把 glibc 的 <code>getaddrinfo()</code> 调用转发给 <code>systemd-resolved</code>，缺少它的话，即使 <code>systemd-resolved</code> 已经在监听 5353 端口，普通程序也拿不到 mDNS 结果：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt update
</span></span><span class="line"><span class="cl">sudo apt install libnss-resolve
</span></span></code></pre></td></tr></table>
</div>
</div><p>安装后库文件会出现在 <code>/usr/lib/x86_64-linux-gnu/libnss_resolve.so.2</code>。</p>
<p><strong>其次是 <code>systemd-resolved</code> 的全局开关。</strong> 可以用 drop-in 的方式开启 <code>MulticastDNS</code>，这样就不用改动原始主配置文件：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo mkdir -p /etc/systemd/resolved.conf.d
</span></span><span class="line"><span class="cl">cat <span class="s">&lt;&lt;&#39;EOF&#39; | sudo tee /etc/systemd/resolved.conf.d/60-mdns.conf
</span></span></span><span class="line"><span class="cl"><span class="s">[Resolve]
</span></span></span><span class="line"><span class="cl"><span class="s">MulticastDNS=yes
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>再次是网卡层面的开关。</strong> <code>systemd-resolved</code> 要求全局和每个网卡都打开 mDNS 才会真正生效。这里有一个容易忽略的问题：Ubuntu 24.04 Server 虽然默认用 netplan 生成 <code>systemd-networkd</code> 配置，但 <strong>netplan 的 YAML 里并没有合法的 <code>multicast-dns</code> 字段</strong>，写进去会报 <code>unknown key</code>。</p>
<p>正确的做法是给 <code>systemd-networkd</code> 生成的网卡配置写 drop-in。先查看 netplan 生成的文件名：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ls /run/systemd/network
</span></span><span class="line"><span class="cl"><span class="c1"># 示例输出：10-netplan-ens33.network</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>然后把文件名替换为实际值，创建 override：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo mkdir -p /etc/systemd/network/10-netplan-ens33.network.d
</span></span><span class="line"><span class="cl">cat <span class="s">&lt;&lt;&#39;EOF&#39; | sudo tee /etc/systemd/network/10-netplan-ens33.network.d/override.conf
</span></span></span><span class="line"><span class="cl"><span class="s">[Network]
</span></span></span><span class="line"><span class="cl"><span class="s">MulticastDNS=yes
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>然后是 <code>/etc/nsswitch.conf</code>。</strong> 需要在 <code>hosts</code> 行里加入 <code>resolve [!UNAVAIL=return]</code>，这样 <code>ping</code>、<code>curl</code> 这类走 glibc <code>getaddrinfo()</code> 的程序才会把查询交给 <code>systemd-resolved</code>：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="na">hosts: files resolve [!UNAVAIL</span><span class="o">=</span><span class="s">return] dns myhostname</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>最后是防火墙和网络环境。</strong> 需要放行 UDP 5353 的组播报文：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo ufw allow in proto udp from 224.0.0.0/4 to any port <span class="m">5353</span> comment <span class="s2">&#34;mDNS&#34;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>另外，有些虚拟机网桥或云平台会丢弃组播报文，这种环境下 mDNS 即使配置正确也无法工作。</p>
<p>完成上述配置后，应用并重启相关服务：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo netplan apply
</span></span><span class="line"><span class="cl">sudo systemctl restart systemd-resolved
</span></span></code></pre></td></tr></table>
</div>
</div><blockquote>
<p><code>MulticastDNS=yes</code> 表示本机既解析别人的 <code>.local</code> 名称，也对外广播自己的主机名；<code>MulticastDNS=resolve</code> 则只做客户端解析，不广播自己。</p>
</blockquote>
<h3 id="72-怎么确认已经生效">7.2 怎么确认已经生效</h3>
<p>可以用下面几条命令来验证：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 查看全局和每个网卡的 mDNS 开关状态（Link 那行应为 yes）</span>
</span></span><span class="line"><span class="cl">resolvectl mdns
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 直接调用 systemd-resolved 内部接口，绕过 glibc NSS</span>
</span></span><span class="line"><span class="cl">resolvectl query target.local
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># 走 glibc getaddrinfo 的真实业务路径</span>
</span></span><span class="line"><span class="cl">getent hosts target.local
</span></span></code></pre></td></tr></table>
</div>
</div><p>如果 <code>resolvectl query</code> 能解析成功，但 <code>getent hosts</code> 不行，问题通常出在 <code>/etc/nsswitch.conf</code> 或者 <code>libnss-resolve</code> 上。如果两者都失败，再检查网卡 link 层的 <code>MulticastDNS</code>、防火墙 UDP 5353 以及网络组播是否可达。</p>
<h3 id="73-几个容易忽略的地方">7.3 几个容易忽略的地方</h3>
<ul>
<li><strong>混淆 <code>systemd-resolved</code> 与 <code>libnss-resolve</code></strong>：前者是守护进程，后者是 glibc 的 NSS 插件，Ubuntu 24.04 Server 默认不装后者。</li>
<li><strong>只改 <code>resolved.conf</code> 全局配置，没开网卡层</strong>：<code>resolvectl mdns</code> 的 Link 字段仍是 <code>-</code>，mDNS 不会工作。</li>
<li><strong>在 netplan YAML 里写 <code>multicast-dns: true</code></strong>：该 key 不合法，需改用 networkd drop-in。</li>
<li><strong>没改 <code>/etc/nsswitch.conf</code></strong>：走 glibc 的程序不会使用 <code>systemd-resolved</code> 的 mDNS。</li>
<li><strong>同时运行 <code>avahi-daemon</code></strong>：会争抢 UDP 5353 端口。如果打算用 <code>systemd-resolved</code> 内置的 mDNS，就不要再装 avahi。</li>
</ul>
<h2 id="8-解决-adguard-dns-的-53-端口冲突">8. 解决 AdGuard DNS 的 53 端口冲突</h2>
<p>AdGuard <a href="https://github.com/AdguardTeam/AdGuardHome/wiki/Docker#resolved">官方 wiki 中给出的方案</a>，是新增一个 resolved 的 drop-in 配置文件 <code>/etc/systemd/resolved.conf.d/adguardhome.conf</code>:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-ini" data-lang="ini"><span class="line"><span class="cl"><span class="k">[Resolve]</span>
</span></span><span class="line"><span class="cl"><span class="na">DNS</span><span class="o">=</span><span class="s">127.0.0.1</span>
</span></span><span class="line"><span class="cl"><span class="na">DNSStubListener</span><span class="o">=</span><span class="s">no</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>然后将 resolv.conf 指向 <code>/run/systemd/resolve/resolv.conf</code>，并重启 resolved 服务:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">mv /etc/resolv.conf /etc/resolv.conf.backup
</span></span><span class="line"><span class="cl">ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">systemctl reload-or-restart systemd-resolved
</span></span></code></pre></td></tr></table>
</div>
</div><p>这一方案对应前文提到的 uplink 模式：resolved 将 <code>resolv.conf</code> 指向上游 DNS 列表。其效果如下：</p>
<p><img alt="本地应用使用 AdGuard DNS" loading="lazy" src="/codes/adguard-dns-systemd-resolved/asserts/adguard-resolved.svg#center"></p>
<p>resolved 的 DNSStubListener 被关闭后：</p>
<ol>
<li><code>127.0.0.53:53</code> 和 <code>127.0.0.54:53</code> 实际上被 AdGuard DNS 的 <code>0.0.0.0:53</code> 顶替；</li>
<li>AdGuard wiki 中建议将 <code>DNS</code> 改为 <code>127.0.0.1</code>，因为 DNSStubListener 的 <code>127.0.0.53</code> 已不再有效。由于此时任何 <code>127.x.x.x</code> 地址都会被 AdGuard DNS 的 <code>0.0.0.0:53</code> 监听所捕获，因此填写 <code>127.*.*.*</code> 也能正常工作；可用 <code>python3 -m http.server 12345</code> 与 <code>curl 127.0.0.55:12345</code> 验证；</li>
<li>这里填写的是上游 DNS server，由于该 DNS server 位于本节点，也可以填写本节点的其他 IP 地址；</li>
<li>DNSStubListener 关闭后，使用 resolved 本地接口的应用程序仍可正常使用 resolved 提供的功能；</li>
<li>绕过 resolved 本地接口的应用程序会直接访问到 AdGuard DNS，因此无法通过传统 DNS 协议获得 mDNS 和 LLMNR 的查询结果；</li>
</ol>
<h3 id="81-有没有更好的解决方式">8.1 有没有更好的解决方式？</h3>
<p>AdGuard wiki 提供的方案存在以下缺点：</p>
<ol>
<li>需要在 AdGuard Home 之外额外维护一个 resolved 的 drop-in 配置文件，增加运维负担，且会改变 systemd-resolved 的默认行为；</li>
<li>停用 resolved 的 DNSStubListener 之后，<code>resolv.conf</code> 中填写的 <code>nameserver</code> 将不是 DNSStubListener 的地址，无法通过传统 DNS 协议获得 resolved 提供的 mDNS 和 LLMNR 查询结果；</li>
</ol>
<p>AdGuard DNS 并不必须占用 <code>127.0.0.53:53</code>，它只是默认监听在 <code>0.0.0.0:53</code>。若具体使用场景中没有抢占 <code>127.0.0.53:53</code> 的需求，则可将默认监听地址改为自己所需的 IP 地址，修改方式是在 <code>conf/AdGuardHome.yaml</code> 中将 <code>dns.bind_hosts</code> 的默认值 <code>0.0.0.0</code> 修改为具体地址：</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="hl"><span class="lnt">4
</span></span><span class="hl"><span class="lnt">5
</span></span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="l">// ...</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">dns</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">bind_hosts</span><span class="p">:</span><span class="w">
</span></span></span><span class="line hl"><span class="cl"><span class="w">    </span>- <span class="m">192.168</span><span class="l">.x.x</span><span class="w">
</span></span></span><span class="line hl"><span class="cl"><span class="w">    </span>- <span class="m">10.</span><span class="l">x.x.x</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span><span class="nt">port</span><span class="p">:</span><span class="w"> </span><span class="m">53</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="l">// ...</span><span class="w">
</span></span></span></code></pre></td></tr></table>
</div>
</div><p>若使用 docker 容器运行的方式，也可以补全端口映射，指定到具体的 IP 地址上：<code>-p IP:host_port:container_port</code>。</p>
<p><img alt="AdGuard DNS 绑定到具体 IP 上" loading="lazy" src="/codes/adguard-dns-systemd-resolved/asserts/adguard-bind-ip.svg#center"></p>
<p>这样 resolved 和 AdGuard DNS 分别监听各自的 53 端口。通过路由器的 DHCP 配置（或自建的 DHCP 服务），AdGuard DNS 同时会成为 resolved 的上游 DNS，无需修改 <code>resolv.conf</code> 的接管模式。</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="hl"><span class="lnt"> 4
</span></span><span class="hl"><span class="lnt"> 5
</span></span><span class="hl"><span class="lnt"> 6
</span></span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">$ sudo netstat -uanp
</span></span><span class="line"><span class="cl">Active Internet connections <span class="o">(</span>servers and established<span class="o">)</span>
</span></span><span class="line"><span class="cl">Proto Recv-Q Send-Q Local Address       Foreign Address  PID/Program name
</span></span><span class="line hl"><span class="cl">udp        <span class="m">0</span>      <span class="m">0</span> 127.0.0.54:53       0.0.0.0:*        3047/systemd-res
</span></span><span class="line hl"><span class="cl">udp        <span class="m">0</span>      <span class="m">0</span> 127.0.0.53:53       0.0.0.0:*        3047/systemd-res
</span></span><span class="line hl"><span class="cl">udp        <span class="m">0</span>      <span class="m">0</span> 192.168.0.2:53      0.0.0.0:*        3042/AdGuardHome
</span></span><span class="line"><span class="cl">udp        <span class="m">0</span>      <span class="m">0</span> 192.168.0.2:68      0.0.0.0:*        313/systemd-network
</span></span><span class="line"><span class="cl">udp        <span class="m">0</span>      <span class="m">0</span> 0.0.0.0:5353        0.0.0.0:*        3047/systemd-res
</span></span><span class="line"><span class="cl">udp        <span class="m">0</span>      <span class="m">0</span> 0.0.0.0:5355        0.0.0.0:*        3047/systemd-res
</span></span><span class="line"><span class="cl">udp6       <span class="m">0</span>      <span class="m">0</span> :::5353             :::*             3047/systemd-res
</span></span><span class="line"><span class="cl">udp6       <span class="m">0</span>      <span class="m">0</span> :::5355             :::*             3047/systemd-res
</span></span></code></pre></td></tr></table>
</div>
</div><p>这样 systemd-resolved 与 AdGuard DNS 可以共存。</p>
<h2 id="参考链接">参考链接</h2>
<ul>
<li><a href="https://github.com/AdguardTeam/AdGuardHome/wiki/Docker#resolved">Docker · AdguardTeam/AdGuardHome Wiki</a></li>
<li><a href="https://man.archlinux.org/man/systemd-resolved.8">systemd-resolved(8) — Arch manual pages</a></li>
<li><a href="https://github.com/systemd/systemd/issues/8639">Add support for DNS-over-HTTPS to systemd-resolved · Issue #8639</a></li>
<li><a href="https://www.wikiwand.com/en/articles/Link-local_address">Link-local address - Wikiwand</a></li>
<li><a href="https://man.archlinux.org/man/org.freedesktop.resolve1.5.en">org.freedesktop.resolve1(5) — Arch manual pages</a></li>
<li><a href="https://man.archlinux.org/man/getaddrinfo.3.en">getaddrinfo(3) — Arch manual pages</a></li>
<li><a href="https://man.archlinux.org/man/nss-resolve.8.en">nss-resolve(8) — Arch manual pages</a></li>
<li><a href="https://systemd.io/WRITING_RESOLVER_CLIENTS/">Writing Resolver Clients — systemd.io</a></li>
<li><a href="https://man.archlinux.org/man/nsswitch.conf.5.en">nsswitch.conf(5) — Arch manual pages</a></li>
<li><a href="https://man.archlinux.org/man/nss-mymachines.8.en">nss-mymachines(8) — Arch manual pages</a></li>
<li><a href="https://man.archlinux.org/man/hosts.5.en">hosts(5) — Arch manual pages</a></li>
<li><a href="https://man.archlinux.org/man/nss-myhostname.8.en">nss-myhostname(8) — Arch manual pages</a></li>
<li><a href="https://github.com/bminor/glibc/blob/master/resolv/README">glibc/resolv/README — bminor/glibc</a></li>
<li><a href="https://github.com/avahi/nss-mdns">avahi/nss-mdns — GitHub</a></li>
<li><a href="https://man.archlinux.org/man/resolv.conf.5.en">resolv.conf(5) — Arch manual pages</a></li>
<li><a href="https://man.archlinux.org/man/resolved.conf.5.en">resolved.conf(5) — Arch manual pages</a></li>
<li><a href="https://man.archlinux.org/man/resolvconf.8.en">resolvconf(8) — Arch manual pages</a></li>
<li><a href="https://wiki.archlinux.org/title/Systemd-resolved#Setting_DNS_servers">systemd-resolved — ArchWiki</a></li>
<li><a href="https://github.com/tailscale/tailscale/blob/main/net/dns/resolved.go">tailscale/net/dns/resolved.go — GitHub</a></li>
</ul>
]]></description>
    </item>
  </channel>
</rss>
