跳至正文
老丹的足迹 —— 代码写给机器,游记写给自己,感悟写给时间
老丹的足迹 老丹的足迹
老丹的足迹 老丹的足迹
  • 首页
  • 示例页面
  • 首页
  • 示例页面
老丹的足迹 老丹的足迹
老丹的足迹 老丹的足迹
  • 首页
  • 示例页面
  • 首页
  • 示例页面

Ubuntu DNS 配置完全指南

前言

Ubuntu 从 17.10 版本开始,DNS 配置机制发生了一次重大变革,引入 systemd-resolved 作为默认的 DNS 解析服务。这套新机制与传统的 /etc/resolv.conf 方式有很大不同,初次接触时容易感到困惑。

本文将从实际文件出发,系统性地解释 Ubuntu 的 DNS 配置机制,并结合 WireGuard VPN 场景下的真实配置案例进行说明。

一、传统方式 vs Ubuntu 方式

1.1 传统 Linux DNS 配置

在传统 Linux 系统中,DNS 配置非常简单:

# /etc/resolv.conf
nameserver 8.8.8.8
nameserver 114.114.114.114

所有应用程序的 DNS 查询都直接发给 8.8.8.8。

特点:

  • 配置简单直接
  • 只有一个配置文件
  • 所有程序共用一套 DNS

缺点:

  • 多网卡(Wi-Fi/有线/VPN)切换时,DNS 配置互相覆盖
  • 无法实现域名分流(内网域名走内网 DNS,公网域名走公网 DNS)
  • 不支持 mDNS(.local 域名解析)

1.2 Ubuntu 的 DNS 配置(systemd-resolved)

Ubuntu 引入了一套更复杂的机制,核心组件是 systemd-resolved。

# /etc/resolv.conf(实际是软链接)
nameserver 127.0.0.53

所有应用程序的 DNS 查询都先发给 127.0.0.53,由 systemd-resolved 服务决定转发给谁。

特点:

  • 按网卡独立管理 DNS
  • 支持域名分流
  • 统一 DNS 缓存
  • 原生支持 mDNS 和 LLMNR

二、核心概念详解

2.1 /etc/resolv.conf 到底是什么?

执行 ls -l /etc/resolv.conf:

/etc/resolv.conf -> ../run/systemd/resolve/stub-resolv.conf

它不是一个真正的配置文件,而是指向 /run/systemd/resolve/stub-resolv.conf 的软链接。

查看实际内容:

cat /etc/resolv.conf
# This is /run/systemd/resolve/stub-resolv.conf managed by man:systemd-resolved(8).
# Do not edit.
#
# This file might be symlinked as /etc/resolv.conf. If you're looking at
# /etc/resolv.conf and seeing this text, you have followed the symlink.
#
# This is a dynamic resolv.conf file for connecting local clients to the
# internal DNS stub resolver of systemd-resolved. This file lists all
# configured search domains.
#
# Run "resolvectl status" to see details about the uplink DNS servers
# currently in use.
#
# Third party programs should typically not access this file directly, but only
# through the symlink at /etc/resolv.conf. To manage man:resolv.conf(5) in a
# different way, replace this symlink by a static file or a different symlink.
#
# See man:systemd-resolved.service(8) for details about the supported modes of
# operation for /etc/resolv.conf.

nameserver 127.0.0.53
options edns0 trust-ad
search .

三行配置的含义:

配置项含义
nameserver 127.0.0.53DNS 查询发往本地 127.0.0.53(systemd-resolved 服务)
options edns0 trust-ad启用 EDNS0 协议扩展和 DNSSEC 信任锚
search .搜索域为根域,不追加任何域名后缀

关键结论: 这个文件只是一个”路牌”,告诉系统”DNS 查询请去 127.0.0.53″。真正的 DNS 配置在别处。

文件开头的所有 # 注释都在强调一件事:不要编辑这个文件。

2.2 127.0.0.53 是什么?

127.0.0.53 是 systemd-resolved 服务监听的本地地址。

ss -tuln | grep 127.0.0.53
udp   UNCONN 0  0  127.0.0.53%lo:53  0.0.0.0:*
tcp   LISTEN 0  4096  127.0.0.53%lo:53  0.0.0.0:*

它不指向任何物理网卡,而是指向一个运行在系统本地的服务。

2.3 systemd-resolved 是什么?

systemd-resolved 是 Ubuntu 系统的 DNS 解析核心服务,它负责:

  1. 接收 DNS 查询:监听 127.0.0.53:53,接收所有应用程序的 DNS 请求
  2. 按规则转发:根据各网卡的 DNS 配置,决定查询转发给哪个上游 DNS
  3. DNS 缓存:缓存解析结果,加速重复查询
  4. 域名分流:支持不同域名走不同 DNS 服务器

查看服务状态:

systemctl status systemd-resolved

2.4 resolvectl 是什么?

resolvectl 是管理 systemd-resolved 的命令行工具。

resolvectl status

这个命令会显示当前所有网卡的 DNS 配置状态。

2.5 DNS Domain 是什么?

DNS Domain 是 systemd-resolved 中一个重要的概念,它决定了哪些域名的查询走该网卡的 DNS。

值含义
~.所有域名都走该网卡的 DNS
~example.com只有 example.com 及其子域名走该网卡 DNS
~internal只有 internal 域名走该网卡 DNS
空只有明确指定的域名走该网卡 DNS

~. 就像一个通配符,匹配所有域名。

2.6 这个 ~. 是谁加的?

当你在 WireGuard 配置文件 wg0.conf 的 [Interface] 段中写了 DNS = 1.1.1.1 时,wg-quick up 脚本会自动执行:

resolvectl dns wg0 1.1.1.1 2606:4700:4700::1111 223.5.5.5 2400:3200::1
resolvectl domain wg0 "~."   # ← 自动加上这一条

所以 DNS Domain: ~. 是 wg-quick 自动添加的,不是手动配置的。

三、网卡 DNS 配置的完整流程

3.1 应用程序发起 DNS 查询

3.2 systemd-resolved 如何决定上游 DNS?

systemd-resolved 按以下逻辑决定将查询转发给谁:

  1. 检查网卡的 DNS Domain 配置
  • 如果有 ~.,该网卡处理所有域名
  • 如果有 ~example.com,只处理 example.com 域名
  • 如果多个网卡都匹配,优先级按数字顺序(Link 编号小优先)
  1. 回退机制
  • 如果没有任何网卡匹配,使用 Global 配置
  • 如果 Global 也为空,使用系统默认 DNS

3.3 DNS 查询的完整路径

四、正确配置示例(WireGuard + DNS)

4.1 配置目标

让所有 DNS 查询走 wg0 的 DNS(1.1.1.1),并通过 wg0 隧道发出。

4.2 配置文件

# /etc/wireguard/wg0.conf
[Interface]
PrivateKey = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
Address = 10.8.0.4/32, fdcc:ad94:bacf:61a4::cafe:4/128
MTU = 1420
DNS = 1.1.1.1, 2606:4700:4700::1111, 223.5.5.5, 2400:3200::1

[Peer]
PublicKey = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
PresharedKey = xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=
AllowedIPs = 1.1.1.1/32, 172.65.46.172/32, 10.8.0.0/24, fdcc:ad94:bacf:61a4::cafe:0/112
PersistentKeepalive = 25
Endpoint = wg.tanglinux.com:8082

关键配置:

配置项值作用
DNS = 1.1.1.1, ...四个 DNS 地址告诉 systemd-resolved 用这些 DNS 服务器
AllowedIPs = 1.1.1.1/32, ...包含 DNS 地址允许 DNS 查询流量走 wg0 隧道

两者缺一不可:

  • 只有 DNS = 1.1.1.1 没有 AllowedIPs → DNS 查询走 default 路由(eth0)
  • 只有 AllowedIPs 没有 DNS = 1.1.1.1 → 系统不知道用这个 DNS

4.3 验证结果

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

Link 2 (eth0)
    Current Scopes: DNS
         Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 100.100.2.136
       DNS Servers: 100.100.2.136 100.100.2.138

Link 4 (wg0)
    Current Scopes: DNS
         Protocols: +DefaultRoute -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
Current DNS Server: 1.1.1.1
       DNS Servers: 1.1.1.1 2606:4700:4700::1111 223.5.5.5 2400:3200::1
        DNS Domain: ~.

输出解读:

字段值含义
wg0 Current Scopes: DNSDNSwg0 负责 DNS 解析
wg0 Current DNS Server1.1.1.1当前实际使用的 DNS
wg0 DNS Servers四个地址配置的所有 DNS 服务器
wg0 DNS Domain~.所有域名都走 wg0
eth0 Current DNS Server100.100.2.136eth0 的 DNS(作为回退)

4.4 验证 DNS 解析

# 测试 DNS 解析
dig @127.0.0.53 acme-staging-v02.api.letsencrypt.org

# 查看实际使用的 DNS
dig acme-staging-v02.api.letsencrypt.org | grep SERVER
# ;; SERVER: 127.0.0.53#53(127.0.0.53)

# ping 测试
ping acme-staging-v02.api.letsencrypt.org
# ✅ 成功

五、常见配置场景

5.1 场景一:单网卡(最简单的配置)

# 查看当前 DNS
resolvectl status eth0

# 设置 DNS
sudo resolvectl dns eth0 8.8.8.8 114.114.114.114

# 让所有域名走这个 DNS
sudo resolvectl domain eth0 "~."

5.2 场景二:VPN 分流(内网域名走 VPN,公网走本地)

# eth0:本地 DNS
sudo resolvectl dns eth0 100.100.2.136

# wg0:VPN DNS(只处理内网域名)
sudo resolvectl dns wg0 10.0.0.1
sudo resolvectl domain wg0 "~internal" "~corp"

这样 *.internal 和 *.corp 走 VPN DNS,其他走本地 DNS。

5.3 场景三:所有 DNS 查询走 VPN(你的配置)

在 wg0.conf 中配置:

[Interface]
DNS = 1.1.1.1, 2606:4700:4700::1111, 223.5.5.5, 2400:3200::1

[Peer]
AllowedIPs = 1.1.1.1/32, 10.8.0.0/24, ...

wg-quick up 自动执行:

resolvectl dns wg0 1.1.1.1 2606:4700:4700::1111 223.5.5.5 2400:3200::1
resolvectl domain wg0 "~."

结果:所有 DNS 查询走 wg0 的 1.1.1.1。

5.4 场景四:保留 VPN DNS 但不接管所有域名

# 去掉 ~.,只让特定域名走 wg0
sudo resolvectl domain wg0 "~example.com"

这样只有 example.com 走 wg0 DNS,其他域名走 eth0。

六、常用配置和管理命令

6.1 resolvectl 命令大全

# 查看所有网卡的 DNS 配置
resolvectl status

# 查看特定网卡的 DNS 配置
resolvectl status eth0
resolvectl status wg0

# 为网卡设置 DNS
sudo resolvectl dns eth0 100.100.2.136 100.100.2.138
sudo resolvectl dns wg0 1.1.1.1 223.5.5.5

# 为网卡设置域名规则
sudo resolvectl domain wg0 "~."          # 所有域名
sudo resolvectl domain wg0 "~example.com" # 特定域名
sudo resolvectl domain wg0 ""            # 清空

# 设置默认路由(优先级)
sudo resolvectl default-route wg0 true   # 优先使用 wg0
sudo resolvectl default-route wg0 false  # 不优先使用 wg0

# 刷新 DNS 缓存
sudo resolvectl flush-caches

# 清除网卡的 DNS 配置
sudo resolvectl dns wg0 ""
sudo resolvectl domain wg0 ""

6.2 查看 DNS 状态

# 查看完整的 DNS 状态
resolvectl status

# 查看 127.0.0.53 监听状态
ss -tuln | grep 127.0.0.53

# 查看服务日志
sudo journalctl -u systemd-resolved -n 20

6.3 测试 DNS 解析

# 通过 systemd-resolved 解析(走 127.0.0.53)
dig @127.0.0.53 google.com
nslookup google.com 127.0.0.53

# 直接指定 DNS 服务器解析(绕过 systemd-resolved)
dig @1.1.1.1 google.com
dig @100.100.2.136 google.com

# 查看实际走哪个 DNS
dig google.com | grep SERVER

# ping 测试
ping google.com

七、常见问题排查

7.1 排查流程

7.2 常见问题

问题可能原因解决方案
dig @127.0.0.53 超时systemd-resolved 未运行sudo systemctl restart systemd-resolved
DNS 配置不生效/etc/resolv.conf 不是软链接sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
VPN DNS 不工作DNS Domain 未设置sudo resolvectl domain wg0 "~."
DNS 查询走错网卡路由表或 AllowedIPs 问题ip route 检查路由
配置重启后丢失wg-quick 覆盖使用 systemd 服务或修改配置文件
DNS 配置了但 ping 不通AllowedIPs 没包含 DNS 地址在 AllowedIPs 中加入 DNS 服务器 IP

7.3 修复 resolv.conf

如果 /etc/resolv.conf 被手动修改或损坏:

# 恢复为 systemd-resolved 管理
sudo rm -f /etc/resolv.conf
sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf
sudo systemctl restart systemd-resolved

第八章:核心要点总结

8.1 关键概念

概念说明
/etc/resolv.conf软链接,指向 127.0.0.53,不要手动编辑
127.0.0.53systemd-resolved 服务的本地监听地址
systemd-resolvedUbuntu DNS 解析核心服务
resolvectl管理 DNS 配置的命令行工具
DNS Servers网卡关联的 DNS 服务器列表
DNS Domain决定哪些域名走该网卡 DNS
~.匹配所有域名的特殊标记,由 wg-quick 自动添加

8.2 配置要点

要点说明
不要编辑 /etc/resolv.conf它是 systemd-resolved 管理的软链接
用 resolvectl 查看配置resolvectl status 是唯一可靠的查看方式
WireGuard DNS 需配合 AllowedIPsDNS= 配置后,必须确保 DNS 地址在 AllowedIPs 中
~. 由 wg-quick 自动添加在 [Interface] 中写 DNS= 就会自动生成
DNS 也是网络流量必须走路由表,受 AllowedIPs 和路由规则约束

8.3 一句话总结

Ubuntu 的 DNS 配置是一个两层结构:/etc/resolv.conf 指向本地 127.0.0.53(systemd-resolved),由 systemd-resolved 根据各网卡的 DNS Servers 和 DNS Domain 规则转发给上游 DNS。真正的配置通过 resolvectl 管理,而非直接编辑 /etc/resolv.conf。

附录一:传统方式 vs systemd-resolved

对比项传统方式systemd-resolved (Ubuntu)
配置文件/etc/resolv.conf 直接写 DNS指向 127.0.0.53
多网卡 DNS后覆盖前,混乱各网卡独立管理
域名分流不支持支持 DNS Domain 规则
缓存无统一缓存统一缓存层
mDNS/.local不支持原生支持
配置方式手动编辑文件resolvectl 命令
适合场景简单单网卡环境多网络/多 VPN 复杂环境

附录二:常用命令速查表

目的命令
查看所有 DNS 配置resolvectl status
查看网卡 DNSresolvectl status eth0
设置 DNSsudo resolvectl dns eth0 1.1.1.1
设置域名规则sudo resolvectl domain wg0 "~."
清除 DNSsudo resolvectl dns wg0 ""
清除域名规则sudo resolvectl domain wg0 ""
刷新缓存sudo resolvectl flush-caches
重启服务sudo systemctl restart systemd-resolved
查看监听ss -tuln | grep 127.0.0.53
检查软链接ls -l /etc/resolv.conf
修复软链接sudo ln -sf /run/systemd/resolve/stub-resolv.conf /etc/resolv.conf

附录三:你当前的配置状态

项目值
操作系统Ubuntu 24.04
云平台阿里云 ECS
eth0 DNS100.100.2.136 / 100.100.2.138
wg0 DNS1.1.1.1 / 2606:4700:4700::1111 / 223.5.5.5 / 2400:3200::1
wg0 DNS Domain~.(所有域名走 wg0)
wg0 Current ScopesDNS
wg0 Current DNS Server1.1.1.1
配置状态✅ 正常工作
作者

老丹

关注我
其他文章
上一个

在 Ubuntu 中使用 Certbot 的操作指南

下一个

互联网的”导航”安全卫士:深入解读DNSSEC

关于博主

    老丹是一名C/C++后台开发工程师,信奉“无抽象不设计,无性能不生产”。

  • 技术栈:Modern C++、Linux环境编程、多线程/并发、网络编程等。
  • 信条:能用constexpr解决的问题绝不拖到运行时,能靠RAII避免的泄漏绝不写析构。
  • 正在填坑:从解封装到渲染的C++全链路实现,正在驯服FFmpeg与H.264/H.265。
  • 输出原则:这里的每一段代码都经过-Wall -Wextra -Werror -O2的洗礼。

近期文章

  • Linux系统的安全基石:深入理解可插拔认证模块(PAM) 2026年7月27日
  • vsftpd 完全指南:从核心原理到Docker容器化部署 2026年7月27日
  • 互联网的”导航”安全卫士:深入解读DNSSEC 2026年7月27日
  • Ubuntu DNS 配置完全指南 2026年7月27日
  • 在 Ubuntu 中使用 Certbot 的操作指南 2026年7月27日

文章分类

  • C/C++开发 (13)
  • Docker容器 (3)
  • Linux工具包 (10)
  • Linux服务配置 (33)
  • Linux系统 (10)
  • OpenWrt路由 (2)
  • Shell脚本 (3)
  • 安防技术 (4)
  • 数据安全 (30)
  • 网络协议 (17)
  • 计算机理论 (22)
联系我们:📍 地址:中国·广东省深圳市   |   ✉️ 邮箱:support@tanglinux.com   |   💬 QQ:870866607
版权所有:老丹的足迹粤ICP备2026061170号-1       公安备案图标 粤公网安备44030002013274号