在基于Netplan和systemd-networkd的系统上开启systemd-resolved的mDNS功能

Ubuntu Server 24.04版本是一个默认启用systemd-resolved和system-networkd的发行版。通过配置可以启用systemd-resolved上的mDNS功能。但是Ubuntu上默认通过Netplan来管理systemd-networkd配置,给我们的配置工作增加了难度。

以下是这些组件的简要介绍。如果您不确认这篇文章是否适用于您使用的系统,下面也介绍了如何判断您的系统是否使用了这几个组件。

systemd-resolved

systemd-resolved(以下简称resolved)是一个systemd服务,可为其他应用程序提供域名解析功能(systemd-resolved – Arch Wiki、Linux手册页《systemd-resolved(8)》)。

resolved通过以下三种方式为应用程序提供域名解析服务:

  1. 基于D-bus协议的通讯接口:应用程序可以通过改接口获得最完善的功能。
  2. glibc的nss插件:调用glibc的域名解析相关函数时会按照nss配置将请求转发到resolved。
  3. 本地DNS代理:resolved会运行一个在127.0.0.1上监听的DNS服务器,并修改/etc/resolv.conf指向该DNS服务器,因此软件不通过glibc自行发起的DNS查询也能由resolved处理。

resolved能够为应用程序提供mDNS解析,也能响应网络上其他设备的mDNS查询请求。除此之外resolved还支持由微软提出的LLMNR协议。不过,这两项功能都需要在配置中启用方可使用。

另一款提供mDNS查询功能的软件avahi-daemon只能通过nss功能为使用glibc查询域名的软件提供服务,不能服务于不使用glibc的软件以及基于musl的系统上的软件,因此在mDNS域名查询这方面稍逊色于resolved。

运行命令resolvectl,如果设备上安装了resolved,则会返回其配置状态。示例如下:

$ resolvectl
Global
         Protocols: -LLMNR +mDNS -DNSOverTLS DNSSEC=no/unsupported
  resolv.conf mode: stub

Link 2 (enp0s3)
    Current Scopes: DNS mDNS/IPv4 mDNS/IPv6
         Protocols: +DefaultRoute -LLMNR +mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 172.28.1.1
       DNS Servers: 172.28.1.1 2408:{masked}::1

systemd-networkd

systemd-networkd(以下简称networkd)是systemd中用于管理网络配置的服务。

运行命令networkctl,如果当前操作系统已启用networkd,那么该命令会显示哪些网络接口是由networkd管理的(显示为configured),例如:

$ networkctl
IDX LINK   TYPE     OPERATIONAL SETUP
  1 lo     loopback carrier     unmanaged
  2 enp0s3 ether    routable    configured

2 links listed.

Netplan

Netplan是一款用于使用统一的配置文件来配置不同的网络管理后端的软件。系统管理员只需要配置Netplan特有的YAML配置文件,Netplan就能为NetworkManager或systemd-networkd生成相应的配置文件。Ubuntu 24.04系统默认启用了Netplan来简化网络配置工作。

如果系统网络是通过Netplan配置的,那么系统上应该有netplan命令,以及位于/etc/netplan/的Netplan配置文件。

配置过程

要启用resolved在某个网络接口上的mDNS功能,需要同时启动resolved的全局mDNS开关,并在networkd中启用该网络接口的mDNS功能。虽然Netplan能够生成networkd配置文件,但其并不支持mDNS相关设置,因此我们需要直接编写networkd配置来对Netplan生成的配置文件进行补充。

resolved

resolved的主配置文件位于/etc/systemd/resolved.conf。位于/etc/systemd/resolved.conf.d/文件夹内的.conf文件会按文件名顺序补充或替代主配置文件和之前的.conf文件中的配置(其他的配置文件和文件夹请参考Linux手册页《systemd-resolved》)。建立文件/etc/systemd/resolved.conf.d/60-enable-mdns.conf,输入以下内容即可完成resolved的配置:

/etc/systemd/resolved.conf.d/60-enable-mdns.conf
[Resolve]
MulticastDNS=yes

运行命令sudo systemctl restart systemd-resolved重启resolved以使新配置生效。运行命令resolvectl,应当显示全局mDNS设置已处于开启状态(+mDNS),但网络接口上的mDNS处于关闭状态(-mDNS):

$ resolvectl
Global
         Protocols: -LLMNR +mDNS -DNSOverTLS DNSSEC=no/unsupported
  resolv.conf mode: stub

Link 2 (enp0s3)
    Current Scopes: DNS
         Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
       DNS Servers: 172.28.1.1 2408:{masked}::1

networkd

networkd中每个网络都有一个主配置文件,文件名以.network结尾。名为{name}.network的主配置文件可以被文件夹/etc/systemd/networks/{name}.network.d中的.conf文件补充和替代。因此,我们需要找到由Netplan生成的配置文件名称,来建立相应的补充配置。

Netplan生成的.network文件位于/run/systemd/network,一般名字中包含netplan和网络接口名称,如10-netplan-enp0s3.network。相应地,我们为每一个想要启动mDNS的主配置文件{name}.network创建配置文件/etc/systemd/network/{name}.network.d/60-enable-mdns.conf,输入以下内容即可完成networkd的配置:

/etc/systemd/network/10-netplan-enp0s3.network.d/60-enable-mdns.conf
[Network]
MulticastDNS=yes

运行命令sudo systemctl restart systemd-networkd来加载新配置。运行命令resolvectl,可以看到网络接口下的mDNS功能也已经处于开启状态(+mDNS):

$ resolvectl
Global
         Protocols: -LLMNR +mDNS -DNSOverTLS DNSSEC=no/unsupported
  resolv.conf mode: stub

Link 2 (enp0s3)
    Current Scopes: DNS mDNS/IPv4 mDNS/IPv6
         Protocols: +DefaultRoute -LLMNR +mDNS -DNSOverTLS DNSSEC=no/unsupported
       DNS Servers: 172.28.1.1 2408:{masked}::1

验证

运行命令nslookup $(hostname).local,应该可以查询到本机的IP地址。这说明mDNS查询和应答功能都已经成功启用。

$ nslookup $(hostname).local
Server:         127.0.0.53
Address:        127.0.0.53#53

Name:   ubuntu-4.local
Address: 172.28.1.2
Name:   ubuntu-4.local
Address: 2408:{masked}:6d6
Name:   ubuntu-4.local
Address: fe80::{masked}:6d6

现在,我们可以在支持域名的软件里用域名.local来替代本机的IP地址了。

留言

有想法?请给我们留言!您的留言不会直接显示在网站内。