news 2026/10/2 14:59:52

Windows 11 原生 DoH 与自定义 DoH 服务配置指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Windows 11 原生 DoH 与自定义 DoH 服务配置指南

很多人第一次听说 Windows 11 自带 DoH(DNS over HTTPS)都是在一个很尴尬的场景里:网页打开速度还行,但首页偶尔会跳到莫名其妙的推广页,或者某个域名解析出来的 IP 一会儿在这、一会儿在那,换个网络环境就完全正常。查了一圈路由器、换了浏览器、清了缓存,最后发现根子出在 DNS 查询这一段是明文的——从你的电脑到 DNS 服务器之间,那条路径上谁都能看一眼、甚至改一笔。Windows 11 从 22H2 开始把 DoH 客户端做进了系统,不需要装任何第三方软件,在设置里填个模板地址就能让域名解析走 HTTPS 加密通道。这篇文章就把"启用原生 DoH"和"配置自定义 DoH 服务"这两件事从头讲到尾:版本门槛怎么确认、界面和命令行两条路怎么走、模板地址的格式规则、自建服务要注意什么、配完不生效该按什么顺序排查。不管你只是想给家里电脑加一层隐私保护,还是要在内网里统一解析策略,都能照着往下做。

1. 为什么Windows 11的DoH值得折腾

1.1 明文DNS在什么场景下会咬你一口

传统 DNS 走的是 UDP 53 端口,报文是明文。这件事在十几年前算不上什么大问题,但放到今天的环境里,它至少会带来三类具体麻烦。

第一类是解析结果被中途改写。你请求www.some-site.com,正常情况下应该拿到站点自己的 IP,但链路上某些环节出于各种目的,会把这个应答替换成另一个 IP——最常见的就是把请求引到一个带广告或者带推广内容的落地页。表现形式往往很迷惑:同一个网址,手机流量下正常,家里宽带下就跳广告,重启路由器好一阵,过段时间又来。

第二类是查询内容本身被旁观。DNS 查询里包含了你要访问的域名,而域名列表本身就是一份相当精确的行为画像。明文状态下,链路上任何一个能看包的位置,都能拼出你这一天访问了哪些站点、什么时候访问的。

第三类是解析链路的完整性无法验证。UDP 无连接、无校验应答来源、无重传保障,中间设备完全可以抢先伪造一个应答塞回来,客户端通常也没法分辨真假。

DoH 要解决的就是这三件事:把 DNS 请求塞进标准的 HTTPS 通道(TCP 443,TLS 加密),查询内容对外不可见,应答来源通过证书链校验,中途改包的难度直接上了一个数量级。注意,DoH 不改变"你在访问什么"这件事本身——你访问的站点该有的可见性还是有,它保护的仅仅是从你机器到解析服务器这一段。

1.2 系统原生DoH与浏览器DoH、第三方客户端的分工

这里有个很多人搞混的点。现在 Chrome、Edge、Firefox 都内置了"安全 DNS"(Secure DNS),也是 DoH,但那只是浏览器自己的解析行为。它的作用范围仅限浏览器内部发起的请求,系统层面的解析——比如ping、nslookup、桌面软件、游戏客户端、系统更新——照旧走明文。

第三方 DoH 客户端(各种把 53 端口劫持到本地的工具)覆盖面更广,但代价是装驱动或者常驻后台进程,还得自己处理证书和端口占用,出了故障排查起来更绕。

Windows 11 原生的 DoH 客户端(Dnscache 服务里实现的)处在中间位置:它工作在系统解析层,所有走系统 DNS 缓存的请求都覆盖到了,同时不需要额外安装任何软件,配置项直接落在网络适配器的 DNS 设置里。它的限制也很明确——只支持 RFC 8484 标准的 DoH,不支持 DNS over TLS(853 端口那个),也不支持自定义端口,模板 URL 必须是标准的 HTTPS 地址;另外它是"按 DNS 服务器 IP 绑定"的,不是按域名绑定。

所以合理的分工是:系统级 DoH 管全局兜底,浏览器自带的 Secure DNS 可以关掉(避免两套策略打架),第三方客户端留给确实需要按域名分流、按应用分流的场景。

1.3 判断自己是不是目标用户

不是所有人都有必要开这个开关,我把常见情况和判断依据列一下,你可以对号入座。

使用场景是否建议开原生 DoH原因
家庭宽带、经常遇到跳转推广页强烈建议直接消除解析被改写的可能性
移动办公、频繁切换 Wi-Fi 和热点建议统一解析策略,避免不同网络下结果不一致
公司内网、有域控或内部域名谨慎内网域名会解析失败,需要额外分流方案
使用家长控制或上网行为管理不建议会与现有管理策略冲突
玩对延迟敏感的在线游戏视情况首次查询有 TLS 握手开销,需要实测
只是想让浏览器更干净没必要浏览器自带 Secure DNS 就够了

再补一句:DoH 只加密你到解析服务器这一段,它不会改变你访问站点的其他可见性,也不解决带宽、丢包这类问题。把它当成"给 DNS 加个信封"来看待,预期就不会跑偏。

2. 动手之前的版本核对与链路摸底

2.1 版本门槛:22H2是分水岭

原生的 DoH 图形界面是在 Windows 11 22H2(内部版本 22621)之后才完整落地的。在更早的版本上,注册表项和 PowerShell 命令可能存在,但设置界面里看不到"加密的 DNS"这个下拉框,配置起来会有各种别扭的情况。

按Win + R输入winver回车,看弹出的版本号。22621 及以上(包括 23H2、24H2 这些后续版本)都可以放心按本文操作。如果你看到的是 22000 开头,也就是最初的 21H2,界面支持不完整,建议走第 4 章的命令行方式,或者干脆先做一次系统更新。

另外要确认的一点是:原生 DoH 依赖DNS Client(服务名Dnscache)这个服务。很多"系统优化"类软件会把它禁掉以减少内存占用。运行services.msc,找到 "DNS Client",启动类型应该是"自动",状态是"正在运行"。如果它被禁用了,后面所有配置都是白做。

2.2 三条命令摸清当前解析链路

不要上来就改配置。先摸底,知道自己现在用的什么 DNS、走的哪个网卡,后面出问题才有对比基准。用管理员身份打开 PowerShell(或者 Windows Terminal 的管理员标签页),依次敲:

# 看所有网卡的 DNS 服务器地址 Get-DnsClientServerAddress -AddressFamily IPv4 | Format-Table InterfaceIndex, InterfaceAlias, ServerAddresses # 看当前已经配置了哪些 DoH 模板 Get-DnsClientDohServerAddress # 看当前系统实际用的是哪个网卡在通信 Get-NetRoute -DestinationPrefix "0.0.0.0/0" | Select-Object ifIndex, NextHop, RouteMetric

第一条命令的输出告诉你每个网卡当前用的 DNS 是什么。如果ServerAddresses里显示的是路由器地址(常见的是192.168.1.1、192.168.31.1这类),说明你的 DNS 是路由器转发的,而路由器上游用的是运营商下发的 DNS。这种情况下直接在电脑上配 DoH 是最省事的,不用动路由器。

第二条命令刚开箱的机器一般是空输出,或者只列出几条系统内置的知名服务器条目。第三条命令用来确认哪个网卡是主出口——如果ifIndex对应的网卡不是你正在配的那个,配置再对也不会生效,这是多网卡机器上最容易踩的坑之一。

提示:家里有虚拟化软件的(VMware、Hyper-V、Docker Desktop、WSL2)会额外生成一堆虚拟网卡,它们的InterfaceIndex从 10 往上走。改 DNS 的时候一定用InterfaceAlias名字来指定,别用序号,因为序号在重装驱动或者新建虚拟网卡之后会变。

2.3 多网卡、IPv6与虚拟网卡的干扰

多网卡环境下的行为是这样的:Windows 按路由表的"接口跃点数"(InterfaceMetric)来决定用哪条路径出网,DNS 查询也会优先用那条路径对应的网卡配置。问题是这个优先级有时候并不符合直觉——比如你插着网线又连着 Wi-Fi,理论上以太网优先,但实际跑的可能还是 Wi-Fi,因为无线网卡的跃点数被调过。

检查方式:

Get-NetIPInterface -AddressFamily IPv4 | Sort-Object InterfaceMetric | Format-Table InterfaceAlias, InterfaceMetric, ConnectionState

跃点数越小优先级越高。如果你想让以太网优先,可以把 Wi-Fi 的跃点数手动调大:

Set-NetIPInterface -InterfaceAlias "WLAN" -InterfaceMetric 60

关于 IPv6:很多人的电脑同时拿到了 IPv4 和 IPv6 的 DNS 地址。Windows 原生 DoH 对 IPv6 的 DNS 服务器同样支持,但你要给 IPv6 地址也配上对应的模板,否则 IPv6 那条解析路径还是明文的。做法是在配 IPv4 模板的同时,把2606:4700:4700::1111这类 IPv6 地址也加一份模板。如果你不想处理这个复杂度,一个更干净的做法是在网卡属性里把 IPv6 暂时取消勾选——但注意,如果你所在的网络 IPv6 是主路径,这么做会让上网体验变差,先测再动。

虚拟网卡的处理原则是"不要动它们"。VMware 生成的VMware Network Adapter VMnet1/VMnet8、Hyper-V 的vEthernet、Docker 的vEthernet (Default Switch),这些网卡上的 DNS 保持默认即可,它们只服务于虚拟网络内部的通信。在这些网卡上配 DoH 不但没意义,还可能让容器里的域名解析出问题。

3. 用设置界面把原生DoH打开

3.1 找到"加密的DNS"入口的两种路径

图形界面这条路适合只配一台机器、不想记命令的人。入口有两个,效果一样。

路径一:设置→网络和 Internet→ 点进当前正在用的连接(以太网或WLAN) → 找到DNS 服务器分配那一行 → 点右边的编辑。

路径二:设置→网络和 Internet→高级网络设置→ 找到对应网卡 → 点开 → 同样能看到 DNS 服务器分配。

点进编辑之后,会弹出一个下拉菜单,选项有自动 (DHCP)和手动。选手动,然后把IPv4那个开关打开,下面会展开三段内容:首选 DNS、备用 DNS,以及每一条 DNS 后面跟着的一个下拉框——这个下拉框就是"DNS over HTTPS 加密"的控制项。

默认情况下这个下拉框是灰的或者显示关闭。要让它变可选,前提是你填的 DNS 地址是一个已知的、或者你已经注册过模板的 IP 地址。如果你填了1.1.1.1,系统内置的知名服务器列表里就有它,下拉框会直接变成可用状态,里面有三项:关闭、仅加密、首选加密但允许未加密。

  • 关闭:就是普通的明文 DNS。
  • 仅加密:只走 DoH,DoH 不通就直接失败,不会退回明文。
  • 首选加密但允许未加密:先试 DoH,不行再退回明文,容错性更好。

我个人的建议是:家里固定网络选仅加密,笔记本这种到处跑、经常连陌生 Wi-Fi 的选首选加密但允许未加密。理由很直接——仅加密在 DoH 服务器临时不可达的时候会直接导致"能连上 Wi-Fi 但打不开网页",这种故障现象特别容易被误判成路由器问题。

3.2 手动模板模式下的填写规则

上面那个下拉框里还有个打开(手动模板)的选项(不同版本的中文措辞可能是"手动模板"或"自定义模板")。选它会多出来一个文本框,让你填 DoH 模板 URL。

这个文本框有三条硬性规则,违反任何一条都会静默失效——不报错,但也不生效。

第一,模板必须是完整的 HTTPS URL,且路径要精确。标准形式是https://<主机名>/dns-query。填成https://cloudflare-dns.com或者cloudflare-dns.com/dns-query都不认。有些服务商的路径不是/dns-query,比如 NextDNS 是https://dns.nextdns.io/<你的配置ID>,这种就必须按服务商给的原文填,一个字符都不能改。

第二,DNS 服务器地址必须是 IP,不能是域名。这是最反直觉的一条。很多人习惯在 DNS 里填dns.google这种主机名,Windows 的普通 DNS 查询其实也支持填域名(系统会先解析这个域名),但 DoH 模板的匹配是按 IP 做的——模板 URL 里的主机名和 DNS 服务器字段里的 IP 必须构成一对,如果服务器字段填的是域名,这个配对就建立不起来,DoH 不会启用。

第三,同一个 IP 只能绑一个模板。如果你之前通过命令行给1.1.1.1注册过一个模板,现在在界面上又填一个不同的,界面上看起来改了,但底层可能是旧的那条在生效。改模板的正确姿势是先删旧的再加新的,后面第 4 章会给命令。

填完之后点保存。到这一步,界面上的事就做完了。

3.3 保存之后怎么确认真的生效

点完保存别急着关窗口,跑一遍验证。

# 清掉旧缓存,避免看到历史结果 Clear-DnsClientCache # 确认网卡上的 DNS 地址已经改成你填的 Get-DnsClientServerAddress -InterfaceAlias "以太网" -AddressFamily IPv4 # 确认 DoH 模板已经注册进去 Get-DnsClientDohServerAddress | Format-Table ServerAddress, DohTemplate, AllowFallbackToUdp, AutoUpgrade

第三条命令的输出是关键。它应该列出你刚配的那对"IP + 模板"。如果这里是空的,说明界面上的保存没有真正写到底层——最常见的原因是那个 IP 已经被别的模板占用了,或者 DNS 服务器字段实际存的是域名。

做完这一步,最好再用一个实际查询验证一下解析本身是否正常:

Resolve-DnsName www.example.com -Type A

能返回 A 记录,说明解析链路是通的。至于流量到底有没有走加密通道,第 7 章会讲怎么用抓包证明。

4. 命令行与脚本化的DoH配置

4.1 PowerShell 命令的完整参数解释

图形界面一次只能配一台机器、一块网卡,而且换台电脑就得重新点一遍。真要做得利索,还是得上命令。

Windows 提供了一个专门管 DoH 模板的命令集:

Add-DnsClientDohServerAddress ` -ServerAddress "1.1.1.1" ` -DohTemplate "https://cloudflare-dns.com/dns-query" ` -AllowFallbackToUdp $false ` -AutoUpgrade $true

四个参数逐个说清楚,因为它们直接决定了行为差异。

-ServerAddress:DNS 服务器的 IPv4 或 IPv6 地址。这个字段是主键,一个地址对应一条记录。填域名会直接报错,这一点比界面友好,界面会静默接受但后面不生效。

-DohTemplate:模板 URL,规则跟界面那一节完全一致。

-AllowFallbackToUdp:DoH 失败时是否退回 UDP 53。设成$false就是"要么加密,要么失败",隐私性最强但网络容错最差。设成$true时会先尝试 DoH,超时后自动降级。注意默认值不是$false,如果你在意隐私,必须显式写出来。

-AutoUpgrade:这个参数容易被忽略,但它很关键。设成$true表示"当系统解析到的 DNS 服务器正好是这个地址时,自动升级成 DoH"。设成$false的话,只有在你明确把网卡 DNS 指向这个地址、并且模板匹配上时才生效。日常场景用$true更省事。

配套的还有查看、修改、删除:

# 查看全部已注册的 DoH 模板 Get-DnsClientDohServerAddress # 只改模板,不动其他属性 Set-DnsClientDohServerAddress -ServerAddress "1.1.1.1" -DohTemplate "https://new-template.example/dns-query" # 删除某条模板 Remove-DnsClientDohServerAddress -ServerAddress "1.1.1.1"

然后是给网卡设 DNS 本身。这两步是分开的——注册模板不会自动改网卡的 DNS,改 DNS 也不会自动帮你注册模板,很多人配完发现没生效就是因为只做了其中一步。

Set-DnsClientServerAddress -InterfaceAlias "以太网" -ServerAddresses ("1.1.1.1", "1.0.0.1")

-ServerAddresses接收数组,可以一次给主备两个。顺序就是优先级顺序。

4.2 netsh 与 PowerShell 的取舍

netsh也能干这件事,而且在批处理脚本里更方便:

netsh dns add encryption server=1.1.1.1 dohtemplate=https://cloudflare-dns.com/dns-query autoupgrade=yes udpfallback=no netsh dns show encryption netsh dns set encryption server=1.1.1.1 udpfallback=yes netsh dns delete encryption server=1.1.1.1 rem 设置网卡 DNS netsh interface ip set dns name="以太网" static 1.1.1.1 primary netsh interface ip add dns name="以太网" 1.0.0.1 index=2 netsh interface ip set dns name="以太网" dhcp

两者本质是同一套底层接口,写出来的注册表项完全一样。选择依据我看两条:

一是脚本环境。如果目标机器上只有 cmd 或者要写.bat,用netsh;如果可以用 PowerShell 脚本,Add-DnsClientDohServerAddress的报错信息更明确,参数校验更严格,排错更省时间。

二是可读性。netsh的参数是key=value形式,写长了容易看花眼;PowerShell 的命名参数带类型提示,团队里交接脚本的时候后者更友好。

有一个细节要提醒:netsh dns add encryption这条命令在旧版本 Windows 上不存在,会报"找不到下列命令"。所以如果你的脚本要兼容 Win10,得先做版本判断,别直接把它塞进通用的初始化脚本里。

4.3 把整套配置固化成一键恢复脚本

重装系统或者换了新电脑之后,重新点一遍设置挺烦的。写个脚本存网盘或者 Git 仓库里,一条命令恢复。

#Requires -RunAsAdministrator $ErrorActionPreference = "Stop" $AdapterAlias = "以太网" $PrimaryDns = "1.1.1.1" $BackupDns = "1.0.0.1" $DoHTemplate = "https://cloudflare-dns.com/dns-query" function Remove-ExistingDoh($addr) { $existing = Get-DnsClientDohServerAddress -ServerAddress $addr -ErrorAction SilentlyContinue if ($existing) { Remove-DnsClientDohServerAddress -ServerAddress $addr -Confirm:$false Write-Host "已移除旧模板: $addr" } } foreach ($ip in @($PrimaryDns, $BackupDns)) { Remove-ExistingDoh $ip Add-DnsClientDohServerAddress ` -ServerAddress $ip ` -DohTemplate $DoHTemplate ` -AllowFallbackToUdp $false ` -AutoUpgrade $true Write-Host "已注册模板: $ip" } Set-DnsClientServerAddress -InterfaceAlias $AdapterAlias -ServerAddresses @($PrimaryDns, $BackupDns) Clear-DnsClientCache Get-DnsClientDohServerAddress | Format-Table ServerAddress, DohTemplate -AutoSize Get-DnsClientServerAddress -InterfaceAlias $AdapterAlias -AddressFamily IPv4

这个脚本里有个我加了很久才想到的处理:先删后加。因为Add-DnsClientDohServerAddress在地址已存在时会直接报错,而很多人在调试过程中会把同一个 IP 注册好几次,脚本一跑就中断。加上"先判断存在性、存在就删"的逻辑之后,这个脚本可以反复执行,是幂等的。

另外脚本开头用了#Requires -RunAsAdministrator,运行时会自动检查管理员权限,省得跑到一半因为权限不够报一堆莫名其妙的错。Set-DnsClientServerAddress这个名字要注意,很多人会手滑写成Set-DNSClientServerAddress——PowerShell 是大小写不敏感的,这个倒不影响;但网卡别名写错会直接报"找不到"。

5. 自定义DoH服务的选型与参数取舍

5.1 公共DoH服务的地址模板与特性对比

不想自建的话,直接拿公共服务的模板用是最省事的。下面这张表是几家常被用到的,地址模板都是官方公布的标准形式。

服务DNS 服务器 IPDoH 模板主要特点
Cloudflare1.1.1.1 / 1.0.0.1https://cloudflare-dns.com/dns-query节点多、延迟普遍低,不记录日志
Google Public DNS8.8.8.8 / 8.8.4.4https://dns.google/dns-query稳定性和解析准确度高,全球覆盖好
Quad99.9.9.9 / 149.112.112.112https://dns.quad9.net/dns-query内置恶意域名拦截
AdGuard DNS94.140.14.14 / 94.140.15.15https://dns.adguard-dns.com/dns-query带广告和跟踪器过滤
OpenDNS208.67.222.222 / 208.67.220.220https://doh.opendns.com/dns-query分类过滤功能成熟
NextDNS按配置给出https://dns.nextdns.io/你的配置ID可自定义过滤策略与统计
阿里公共 DNS223.5.5.5 / 223.6.6.6https://dns.alidns.com/dns-query国内节点延迟低
DNSPod / 腾讯1.12.12.12 / 120.53.53.53https://doh.pub/dns-query国内节点延迟低

选的时候不要只看"哪个名声大",我一般按这个顺序试:先测延迟,再看过滤需求,最后看隐私策略。

测延迟的办法很土但有效:

1..5 | ForEach-Object { Measure-Command { Resolve-DnsName www.example.com -Server 1.1.1.1 -Type A } | Select-Object -ExpandProperty TotalMilliseconds }

注意这里加了-Server参数是故意的:它测的是"到这台服务器的裸解析延迟",不含 DoH 握手。真实体验里第一次查询会多出一个 TLS 握手的时间,之后的查询走复用连接就比较快了。所以不要因为第一次是几十毫秒就否定一个服务,多跑几次看稳定值。

如果你对广告过滤有需求,AdGuard 或者自带拦截的解析服务会省掉浏览器插件的一部分工作,但要注意它们会返回0.0.0.0或者NXDOMAIN来拦截域名,某些应用遇到这种情况会有奇怪的报错,心里要有数。

5.2 自建DoH服务的关键约束

自己搭一个 DoH 服务,好处是解析日志完全自己掌握、可以内网私有域名、可以按需做过滤策略。但 Windows 原生客户端对服务端有几条硬约束,自建的时候必须先满足,否则怎么配都不会生效。

约束一:必须是标准 RFC 8484 接口。请求方法是 GET 或 POST,路径通常约定为/dns-query,请求体用application/dns-message格式的 DNS 二进制报文。如果你自己写个 HTTP 接口返回 JSON,Windows 是不认的。

约束二:证书必须被系统信任。这是自建场景下最大的门槛。Windows 原生 DoH 严格校验证书链,自签证书默认会被拒。解决办法有两条:一是用可信 CA 签发的证书(域名可公网访问的前提下,自动化申请和续期是常规做法);二是把自建 CA 的根证书导入到"受信任的根证书颁发机构"存储里,客户端机器都要导一遍。第二条在家庭实验环境里可行,在多台设备的场景下就比较累。

约束三:不能是自定义端口。必须是 443。如果你本地 443 端口已经被占用了(比如跑着 Web 服务),得先解决端口冲突,或者换个思路用反向代理把不同域名的流量分出来。

约束四:主机名和证书的 CN/SAN 必须一致。你填的模板里用的主机名,证书里必须包含,否则握手就挂。

自建的话,最省事的方案是 AdGuard Home。它的加密设置里直接有 DNS-over-HTTPS 开关,填上证书路径,监听 443,默认路径就是/dns-query,装完基本就能用。配置稍微讲究一点的会用 CoreDNS 配合 HTTPS 插件,或者用 dnsdist 在前面做协议转换,后面接一个普通的 UDP DNS 上游。这两种方案的配置项多,但灵活度也高,适合已经有一台常开设备、且愿意折腾的场景。

还有一个铲子级的细节:自建 DoH 服务的机器本身也要有稳定的解析上游。如果你的自建服务上游用的是明文 DNS,那加密只覆盖了"你到自建服务"这一段,"自建服务到上游"这一段还是明文的。要端到端加密,自建服务自己的上游也得是 DoH 或者别的加密方式。

5.3 延迟、可用性和日志的三个权衡

选 DNS 服务本质上是在三个维度上做取舍,没有全赢的方案。

延迟主要由物理距离和节点质量决定。就近的节点通常延迟最低,但"就近"不只是地理距离,还跟网络互联质量有关。我的一般做法是同时配主备两个不同服务商,主用延迟低的,备用稳定性好的,这样单点故障不至于断网。

可用性看的是"服务不可达时你的系统会怎样"。这里-AllowFallbackToUdp这个参数的作用就体现出来了。设成$false的时候,DoH 服务器挂了你就上不了网,直到你手动改回明文 DNS。设成$true的时候,系统会在超时后自动退回明文,代价是那一瞬间的查询是明文的。我自己的配置习惯是:台式机固定网络用$false,笔记本用$true。因为笔记本在外面连陌生网络的时候,最怕的就是"看起来连着网但什么都打不开"这种故障,现场排查成本太高。

日志这一项最容易被忽略。不同的解析服务对查询日志的处理差异很大,有的明确表示不长期留存,有的会做匿名化统计,有的会为了安全拦截而记录一部分。企业环境里这一项甚至是选型的首要条件。我的建议是:涉及工作数据的环境,优先选策略公开透明的服务;纯个人环境,选延迟合适的就行。

6. 配完不生效的排查清单

配置完不生效是最常见的抱怨,而绝大多数情况都落在下面这几种里。我按"从最可能到最不可能"的顺序排。

6.1 选项灰色、下拉里没有"加密"字样

现象:DNS 设置面板里,DNS 地址后面那个下拉框是灰的,点不动。

原因排序:

  1. 系统版本低于 22H2。回到winver确认一下,这个是最常见的原因。
  2. 填的 DNS 地址不在"知名服务器"列表里,而且没有注册过模板。界面只会自动为内置列表里的地址(比如1.1.1.1、8.8.8.8)提供下拉选项,其他地址必须先通过命令注册模板,界面才知道它支持 DoH。
  3. 你选的是 IPv6 那一栏,而 IPv6 的 DNS 地址没有对应模板。
  4. Dnscache服务被停用了。

排查顺序就是照这四条走,从下往上排除,一般到第二条就能定位。

6.2 配置成功但抓包仍是明文53

现象:Get-DnsClientDohServerAddress有输出,网卡 DNS 也改了,但抓包看还是 UDP 53 的流量。

这种情况我遇到过三次,原因各不相同:

第一次是网卡 DNS 实际是 DHCP 下发的。界面改了、命令也跑了,但网卡配置里 DHCP 优先级更高,过一会儿就被覆盖回去了。验证办法是改完之后等十几秒再跑一次Get-DnsClientServerAddress,看地址有没有变回去。如果是这个问题,需要在网卡属性里把 IPv4 的"自动获得 DNS 服务器地址"改掉——Set-DnsClientServerAddress本身就会做这件事,但如果这块网卡同时被别的管理策略(组策略、MDM、第三方网络管理软件)管着,策略可能会把它拉回去。

第二次是模板写错了路径。我当时填的是https://dns.example.com,少了/dns-query。命令没有报错,但那个模板从来没被用过。判断办法是把模板 URL 直接在浏览器里打开——如果返回的是一个 DNS 报错而不是正常的服务响应,说明路径不对。

第三次是 DNS 服务器字段填的是域名。前面提过,DoH 模板的匹配是按 IP 做的,服务器填域名就配不上。改成 IP 立刻就好了。这条坑特别隐蔽,因为普通解析用域名是能工作的,只是加密不生效。

6.3 内网域名解析集体失败

现象:外网访问正常,但\\nas这种主机名访问不了,公司内网的oa.xxx.local打不开,打印机找不到。

原因很直白:你的内网域名是内网 DNS 服务器解析的,而现在所有查询都被发到了公网的 DoH 服务,它当然不知道你内网的记录。

这个问题没有一键解法,只有分层方案。可行度从高到低:

方案一:内网也提供 DoH。如果你有权限在内网部署一个 DoH 服务(AdGuard Home 或者自建的),把它作为主 DNS,内网域名由它转发给内网 DNS,公网域名由它走 DoH 上游。这是最干净的方案,因为对客户端来说只有一个 DNS 配置。

方案二:使用解析服务的"私有域名"功能。一些商业解析服务支持把特定域名的查询转发到你指定的内网 DNS 服务器,配置在服务商那边做。适合有没有条件自建但能改解析策略的场景。

方案三:按网络切换配置脚本。写两个脚本,一个"公司模式"(用内网 DNS,不开 DoH),一个"家庭模式"(用公共 DoH)。到地方跑对应的那个。听起来笨,但胜在可靠,也不需要额外权限。

方案四:加一条 hosts 记录。只适用于极少数固定不变的内网设备,比如 NAS 的 IP。C:\Windows\System32\drivers\etc\hosts里加一行,优先级高于 DNS 查询。设备数量少的时候这招最快。

注意:不要试图用"主 DNS 填公网 DoH、备用 DNS 填内网"这种方式来兼顾两边。Windows 的 DNS 客户端在收到 NXDOMAIN 或者 SERVFAIL 时的行为并不总是按你预期切到备用,很多时候会直接返回失败。DNS 主备不是"负载均衡",别指望它做分流。

6.4 切换网络后回到解放前

现象:在家配好了,到公司 Wi-Fi 下发现又是明文。

原因是你只配了家里那块网卡的 DNS。每块网卡(每个网络配置文件)的 DNS 设置是独立的,笔记本在不同环境下实际用的是不同网卡。解决办法就是把配置脚本改成按网卡别名批量执行:

$targets = @("以太网", "WLAN") foreach ($alias in $targets) { $exists = Get-NetAdapter -Name $alias -ErrorAction SilentlyContinue if ($exists) { Set-DnsClientServerAddress -InterfaceAlias $alias -ServerAddresses @("1.1.1.1", "1.0.0.1") Write-Host "已配置 $alias" } }

还有一种更隐蔽的情况:某些网络工具或者虚拟化组件在启动时会重写网卡的 DNS 配置。如果你确认自己没改过,但配置就是会莫名其妙回滚,可以用Get-DnsClientServerAddress定时采样对比,找出是哪个时间点被改的,再反推是哪个程序干的。

7. 长期使用中的实测验证与维护

7.1 用pktmon证明流量确实走了443

配完心里没底的时候,最好的办法是自己抓包看一眼。Windows 有内置的pktmon,不用装 Wireshark。

rem 清掉旧过滤器 pktmon filter remove rem 只抓 DNS 相关的两个方向 pktmon filter add DNS53 -p 53 pktmon filter add DNS443 -p 443 rem 开始实时抓包 pktmon start --etw -m real-time

开着这个窗口,另外开一个终端跑几次解析:

Clear-DnsClientCache Resolve-DnsName www.example.com -Type A Resolve-DnsName www.example.org -Type A

然后回到抓包窗口按Ctrl+C停掉,再用pktmon stop结束会话。观察结果:

  • 如果 53 端口上还有 UDP 报文在跑,说明明文解析仍然存在,配置没完全生效。
  • 如果只在 443 端口上看到跑到你配的那个 DNS 服务器 IP 的 TCP/TLS 流量,那就是走加密通道了。

这个验证方法比什么"在线测速网站"都靠谱,因为它是从你自己机器上直接看到的证据,不依赖第三方判断。

另一个辅助手段是看系统 DNS 缓存里记录的条目:

Get-DnsClientCache | Format-Table Entry, Data, TimeToLive -AutoSize

缓存里有记录说明解析成功,但注意它不区分加密还是明文,所以只能作为"解析是否正常"的参考,不能用来证明加密。

7.2 与浏览器安全DNS、系统缓存的关系

这两者的关系有点绕,我把它说清楚。

Chrome 和 Edge 的"安全 DNS"是浏览器内部的解析器,当它开启时,浏览器发起的请求可能不走系统 DNS,而是自己直连它配置的 DoH 服务器。这就造成一个现象:系统级抓包看是加密的,浏览器那一份也是加密的,但走的是两个不同的服务商,日志被分散到两处,策略也不统一。

我的做法是:系统级开了 DoH,就把浏览器的 Secure DNS 关掉(Chrome 里是设置→隐私和安全→安全→使用安全 DNS关闭;Edge 在类似位置)。这样所有解析都收敛到系统这一层,策略统一,排错也只看一个地方。

Firefox 的情况稍有不同,它有独立的 DoH 开关和"网络设置"里的 DNS 选项,同样建议关闭,让它走系统解析。

另外提一个缓存相关的细节:系统 DNS 缓存(可以通过Get-DnsClientCache查看)和浏览器自己的 DNS 缓存是两套。有时候你改了 DNS 配置,但浏览器里表现还是老样子,就是因为浏览器自己的缓存没清。这时候除了Clear-DnsClientCache,还要在浏览器里访问chrome://net-internals/#dns点一次清除。

7.3 我自己的长期维护习惯

用了两年多原生 DoH,我总结下来几个习惯性的做法,分享出来。

第一,配置改完必须跑一遍三条命令。Get-DnsClientDohServerAddress、Get-DnsClientServerAddress、Resolve-DnsName,三秒钟的事,但能挡掉八成"以为配好了其实没有"的情况。

第二,把配置脚本和验证脚本放在一起。我的脚本文件里是"配置段 + 验证段"两截,跑完配置自动跑验证并打印结果,这样一眼就能看出对不对,不用来回切命令。

第三,留一个"紧急恢复"脚本。内容是Set-DnsClientServerAddress -InterfaceAlias "以太网" -ServerAddresses @("223.5.5.5","119.29.29.29"),把 DNS 改回明文公共 DNS,同时Remove-DnsClientDohServerAddress清掉模板。这个脚本我存在 U 盘和手机备忘录里各一份。原因是有一次我把AllowFallbackToUdp设成了$false,结果选的 DoH 服务临时抖动,直接导致笔记本连上 Wi-Fi 却打不开任何网页,现场只有手机,翻了半天才想起来问题在哪。从那以后我就养成了留后手的习惯。

第四,主备 DNS 选不同服务商。主用延迟低的,备用用另一个厂商的,两家同时挂的概率极低。而且因为有了备用,AllowFallbackToUdp就可以放心设成$false,隐私性和可用性都拿到了。

第五,定期看一眼注册表里到底存了什么。原生 DoH 的模板最终落在HKLM\SYSTEM\CurrentControlSet\Services\Dnscache\Parameters\DohWellKnownServers下面,按 IP 分键。偶尔打开看一眼,能发现一些通过界面看不出来的残留条目——比如你删了网卡的 DNS 配置,但模板还在,这种情况下如果哪天又把 DNS 指回了那个 IP,旧的模板会被静默启用,跟你以为的配置不一样。清理的时候记得把这两边都清干净。

关于版本更新这件事也顺带说一句:Windows 的后续更新会往内置的知名 DoH 服务器列表里加新条目,所以某些以前必须手动注册模板的地址,升级之后可能直接就能在界面上选了。反过来说,偶尔也会出现内置条目的模板地址发生变化的情况,升级之后如果发现原来好用的配置突然不生效,第一件事就是重新跑一遍Get-DnsClientDohServerAddress,看看模板有没有被系统改写。

最后再补一个我踩过的坑:某些"网络优化"类软件会把Dnscache服务的启动类型改成"手动"来节省内存,重启之后服务不启动,DoH 配置看起来还在但完全不工作。如果你装了这类软件,建议定期检查这个服务的启动类型是不是还是"自动"。这个比改 DNS 配置更值得留意,因为它影响的是整个解析层,不只是 DoH 这一个功能。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/2 14:59:49

ReentrantReadWriteLock从原理到实战:锁降级、饥饿与坑位全解析

写这系列教程的时候&#xff0c;我一直想找一种"看起来简单、用起来顺手、但深挖全是坑"的Java并发工具来细讲。ReentrantReadWriteLock恰好就是这样的存在&#xff1a;很多初级开发第一次看到它&#xff0c;觉得不就是把锁分成了读和写两种吗&#xff1f;等真正在项…

作者头像 李华
网站建设 2026/10/2 14:59:28

AI Native架构设计实战:从分层蓝图到落地避坑指南

最近在做一个从零开始的AI客服和决策辅助系统&#xff0c;团队里反复出现同一个问题&#xff1a;技术方案到底怎么画&#xff1f;是先把模型接进来&#xff0c;还是先把数据理清楚&#xff1f;哪些模块该做成微服务&#xff0c;哪些根本不用拆&#xff1f;这些问题凑在一起&…

作者头像 李华
网站建设 2026/10/2 14:59:26

SpringBoot整合3D可视化:从零构建元宇宙整车生产线管理系统

1. 课题拆解&#xff1a;这个题目到底在做什么带毕业设计这么多年&#xff0c;SpringBoot 管理系统的组合见得实在太多了&#xff0c;什么图书管理、宿舍管理、教务管理&#xff0c;基本都是一个套路换一层皮。但“基于SpringBoot的元宇宙平台的整车生产线管理系统”这个课题&…

作者头像 李华
网站建设 2026/10/2 14:58:51

dsPIC33EP+DRV8818步进驱动板开发实战与经验分享

最近给一台小型机器人关节测试台做驱动板&#xff0c;电机端选的是双极步进电机&#xff0c;控制器用了 Microchip 的 dsPIC33EP512MU810&#xff0c;功率级交给 TI 的 DRV8818PWPR。整套系统从打样到跑通大概用了一个多星期&#xff0c;中间踩了几个比较典型的坑&#xff0c;过…

作者头像 李华
网站建设 2026/10/2 14:57:53

VirtualBox 装 Win11 虚拟机:TPM 2.0、增强功能与避坑

1. 先搞明白&#xff1a;为什么要在 VirtualBox 里装 Win11我平时干活的主力机是 Linux&#xff0c;但手头总有一些绕不开的 Windows 场景&#xff1a;帮朋友验证一个只在 Win11 上出问题的软件、跑某个银行客户端、测试一份文档在 Edge 下的排版、或者干脆想看看某个新版本系统…

作者头像 李华
网站建设 2026/10/2 14:57:28

液流电池储能系统Simulink仿真建模:从等效电路到充放电特性分析

开篇先交代背景&#xff1a;做储能系统开发&#xff0c;仿真这一关迟早要过。我刚接触液流电池那会儿&#xff0c;想快速验证一套基础的储能管理逻辑&#xff0c;结果发现市面上资料大多停在“原理图公式”层面&#xff0c;真正能把Simulink模型一步步搭起来、跑出充放电曲线的…

作者头像 李华