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

发布时间:2026/10/2 15:00:07
Windows 11 原生 DoH 与自定义 DoH 服务配置指南 很多人第一次听说 Windows 11 自带 DoHDNS 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 443TLS 加密查询内容对外不可见应答来源通过证书链校验中途改包的难度直接上了一个数量级。注意DoH 不改变你在访问什么这件事本身——你访问的站点该有的可见性还是有它保护的仅仅是从你机器到解析服务器这一段。1.2 系统原生DoH与浏览器DoH、第三方客户端的分工这里有个很多人搞混的点。现在 Chrome、Edge、Firefox 都内置了安全 DNSSecure DNS也是 DoH但那只是浏览器自己的解析行为。它的作用范围仅限浏览器内部发起的请求系统层面的解析——比如ping、nslookup、桌面软件、游戏客户端、系统更新——照旧走明文。第三方 DoH 客户端各种把 53 端口劫持到本地的工具覆盖面更广但代价是装驱动或者常驻后台进程还得自己处理证书和端口占用出了故障排查起来更绕。Windows 11 原生的 DoH 客户端Dnscache 服务里实现的处在中间位置它工作在系统解析层所有走系统 DNS 缓存的请求都覆盖到了同时不需要额外安装任何软件配置项直接落在网络适配器的 DNS 设置里。它的限制也很明确——只支持 RFC 8484 标准的 DoH不支持 DNS over TLS853 端口那个也不支持自定义端口模板 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。仅加密只走 DoHDoH 不通就直接失败不会退回明文。首选加密但允许未加密先试 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四个参数逐个说清楚因为它们直接决定了行为差异。-ServerAddressDNS 服务器的 IPv4 或 IPv6 地址。这个字段是主键一个地址对应一条记录。填域名会直接报错这一点比界面友好界面会静默接受但后面不生效。-DohTemplate模板 URL规则跟界面那一节完全一致。-AllowFallbackToUdpDoH 失败时是否退回 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 server1.1.1.1 dohtemplatehttps://cloudflare-dns.com/dns-query autoupgradeyes udpfallbackno netsh dns show encryption netsh dns set encryption server1.1.1.1 udpfallbackyes netsh dns delete encryption server1.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 index2 netsh interface ip set dns name以太网 dhcp两者本质是同一套底层接口写出来的注册表项完全一样。选择依据我看两条一是脚本环境。如果目标机器上只有 cmd 或者要写.bat用netsh如果可以用 PowerShell 脚本Add-DnsClientDohServerAddress的报错信息更明确参数校验更严格排错更省时间。二是可读性。netsh的参数是keyvalue形式写长了容易看花眼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 接口返回 JSONWindows 是不认的。约束二证书必须被系统信任。这是自建场景下最大的门槛。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 地址后面那个下拉框是灰的点不动。原因排序系统版本低于 22H2。回到winver确认一下这个是最常见的原因。填的 DNS 地址不在知名服务器列表里而且没有注册过模板。界面只会自动为内置列表里的地址比如1.1.1.1、8.8.8.8提供下拉选项其他地址必须先通过命令注册模板界面才知道它支持 DoH。你选的是 IPv6 那一栏而 IPv6 的 DNS 地址没有对应模板。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然后回到抓包窗口按CtrlC停掉再用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 这一个功能。