免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

特殊域名与DNS解析故障排查:从劫持污染到自建DNS实战

特殊域名与DNS解析故障排查:从劫持污染到自建DNS实战 做运维这些年我越来越确定一件事DNS 是网络世界里最容易出幺蛾子的环节而“特殊域名”则是 DNS 问题里最让人头疼的那一类。所谓特殊域名不是指某个具体网站而是指那些在常规 DNS 解析链路上表现异常、或者必须单独对待的域名。这类域名可能来自企业内网、可能来自 CDN 回源配置、也可能是某个恶意程序正在偷偷查询的 C2 地址。不管哪一种只要 DNS 处理得不对小到网页打不开大到整个内网解析瘫痪都有可能发生。这篇文章不是教科书式的 DNS 原理科普而是我把日常工作中处理过的特殊域名场景做了一个汇总从保留域名的坑到 DNS 劫持和污染的识别再到自建 DNS 做域名级分流、CDN 回源时的 530 Origin DNS Error最后补充几个和 DNS 报文、DNS 隧道相关的冷门细节。适合正在搭 DNS 服务器、排查域名解析异常、或者想对家里和公司的 DNS 做精细化控制的人。1. 先捋清楚到底什么才算“特殊域名”1.1 协议里定死的保留域名互联网体系里有一批域名是“文档约定”性质它们永远不该被真实解析到某个服务器。RFC 2606 定义了 .example、.invalid、.localhost、.test 这几个保留后缀RFC 6761 又进一步明确了 .test、.localhost 等特殊用途域名的行为。比如 localhost 永远指向 127.0.0.1IPv6 是 ::1任何公网 DNS 都不应该返回关于它的真实记录。你如果把 localhost 当成普通域名交给公网 DNS 去查大概率会被返回 NXDOMAIN这不是故障而是约定如此。真正坑的是 .local。这个后缀专给 mDNS多播 DNS使用苹果设备的 AirDrop、打印机自动发现都在靠它。问题在于很多企业网络管理员不知道这条约定把内网主机名也干脆起成 xxx.local然后让 DHCP 下发普通 DNS。结果就是设备之间能 ping 通 IP但想通过主机名访问时DNS 解析永远失败因为 .local 根本不走普通 DNS 通道只有 mDNS 才会响应。第一次遇到这种问题的人十有八九不会往这里想。.internal、.home.arpa 这类后缀虽然不在最老一批 RFC 里但也是社区默认的私有域名规则RFC 8375 专门把 home.arpa 定义为家庭网络专用。很多公司习惯用 ad.company.com、mail.company.com 这种“真域名子域”做内部解析风险在于一旦这家公司以后真的注册并公开了这个子域外部 DNS 解析出来的 IP 可能是别人的服务器而内网解析到的是公司内网 IP内外网解析结果不一致轻则访问混乱重则引发安全事故。我的建议很简单内部解析统一用 .internal 或 .home.arpa不要拿公网域名的子域当内网域名用。1.2 业务视角必须单独掐名单的域名从业务管理角度看特殊域名通常分成三类。第一类是内网必须解析的短主机名或内部域名比如 gitlab.internal、nas.home.arpa、打印机主机名这些必须由内部 DNS 服务器提供解析公网 DNS 根本不知道它们的存在。第二类是明确“禁止解析”的域名企业合规要求会要求屏蔽钓鱼网站、恶意下载站、矿池域名DNS 层面直接黑掉是最见效的手段。第三类是“需要指定解析结果”的域名最常见的是开发和测试阶段把线上域名临时指向测试服务器或者公司对外服务通过 DNS 调度到不同机房。这三类域名的共同特点是无法用“统一走运营商 DNS”解决必须落在专门的解析策略里。如果没有统一规划就会出现开发人员访问到线上环境、测试域名被公网解析到真实业务这类事故。我见过不止一个团队为了省事直接在 /etc/hosts 里写死几条记录结果换台电脑就抓瞎最后还得回来搭一套正经的内部 DNS。1.3 安全视角被攻击者盯上的域名安全视角下的特殊域名更值得警惕。恶意程序在 C2 通信时会频繁查询一些随机子域名的域名矿池挖矿木马也喜欢通过 DNS 探测矿池地址。这一类域名的典型特征是域名不固定、TTL 很短、子域名随机化严重。举个例子一个正常的业务域名子域名基本都是固定的 api、www、mail而恶意域名可能会把一串十六进制字符串当作子域名每次查询都不一样。从防御角度说DNS 是除了防火墙之外最值得做“名单管理”的地方。一个域名如果被判定为恶意直接在 DNS 层返回 0.0.0.0 或 NXDOMAIN终端上的恶意程序就会失去“电话号码”无法找到真正的 C2 服务器。下面是几类特殊域名和对应的处理策略大家可以对照自己的场景。域名类型典型示例建议处理策略协议保留域名.test、.localhost、.local、.internal不上公网内网 DNS 单独建区管理内网系统域名gitlab.internal、nas.home.arpa自建 DNS 解析到内网 IP恶意/矿池域名随机子域.c2domain.com黑洞/阻断解析返回 0.0.0.0 或 NXDOMAIN需要分流的域名github.com、githubusercontent.com自建 DNS 按域名指定上游证书相关域名与 CNAME 不一致的历史域名保证解析结果与证书 SAN 保持一致2. 特殊域名最容易踩的坑劫持、污染与解析错乱2.1 劫持和污染是怎么发生的DNS 劫持这件事很多老运维都见怪不怪了。当你使用运营商默认 DNS 时查询一个不存在的域名运营商服务器可能不返回 NXDOMAIN而是给你一个广告页面 IP这就是典型的劫持。更隐蔽的是污染针对特定域名返回伪造的应答让你访问 A 站却跳转到 B 站或者返回一堆不属于目标站点的 IP。为什么特殊域名尤其容易被盯上因为越冷门的域名用户越少出了问题越不容易被发现。企业内网如果用了某个没备案的公网域名或者某个老域名已经下线但还有人在用运营商 DNS 里很可能残留脏数据。这时候解析结果五花八门有的节点返回正确 IP有的节点返回错误 IP排查起来特别费劲。一个很实用的判断技巧是用 nslookup 解析同一个域名分别指定运营商默认 DNS 和公共 DNS比如 223.5.5.5如果两个结果不一样而且你用默认 DNS 访问时页面跳转异常那大概率就是被劫持了。2.2 排查手法先对比再下结论排查 DNS 解析异常我从来不迷信单一来源。常见命令组合如下nslookup example.com 223.5.5.5 dig 119.29.29.29 example.com short dig example.com trace第一条用来快速验证公共 DNS 的解析结果第二条可以拿到最精简的 A 记录第三条能看到完整解析链路根服务器、顶级域服务器、权威服务器分别返回了什么。如果 trace 的结果在某一层和预期不符问题就定位在这一层。另外还要看 TTL。正常域名 TTL 可能是 600 秒或者 3600 秒如果某个域名每次查询 TTL 都不一样且变化幅度很大说明上游可能存在缓存投毒或者有人做了动态应答。再配合浏览器侧的现象比如访问 HTTPS 站点时地址栏出现证书错误、时间没问题但证书链显示不可信这时候就不只是 DNS 的问题了还要排查中间链路。2.3 缓解手段把查询通道升级成加密通道针对劫持和污染现在最成熟的缓解手段是 DoHDNS over HTTPS和 DoTDNS over TLS。DoH 把 DNS 查询伪装成普通 HTTPS 请求走 443 端口中间很难被识别和篡改DoT 用 853 端口专门承载加密 DNS 流量更纯粹但更容易被感知。对普通用户来说浏览器或系统设置里直接开启 DoH 是成本最低的方案对企业网络可以在网关或自建 DNS 服务器上统一把上游查询切成 DoT/DoH这样终端不需要任何改动。有一个误区要澄清加密 DNS 只是把“查询过程”加密了不解决“对方站点本身不可达”和“证书不匹配”这类问题。很多人以为换了 DoH 就能访问所有网站这是不对的。DNS 解决的是“找到正确的服务器地址”至于这条网络路径通不通、目标服务器会不会拒绝连接那是路由和服务端的事。2.4 公共 DNS 怎么选别盲目追求国外服务器网上关于“dns 设置哪个最好最快”“dns 114 和 8 哪个好”的讨论从来没有停止过。我直接给一张常用公共 DNS 的对比表大家根据自己的网络环境选。服务商首选地址备用地址特点阿里 DNS223.5.5.5223.6.6.6国内节点多国内访问普遍稳定腾讯 DNSPod119.29.29.29119.28.28.28延迟低适合游戏/下载场景114 DNS114.114.114.114114.114.115.115老牌稳定性尚可广告过滤一般Google DNS8.8.8.88.8.4.4全球均衡但国内链路质量不稳定Cloudflare1.1.1.11.0.0.1支持 DNSSEC/DoH/DoT海外节点强“西安移动宽带用哪个 DNS 快”这类问题真的没有统一答案。本地运营商 DNS 解析本地内容最快但可能有劫持公共 DNS 稳定但可能出现跨地域调度。我的习惯是先用 ping 或者专门的 DNS 测速工具测量延迟再分别解析几个常用站点看返回的 IP 是否离自己近最后实际访问一遍对比首屏速度。核心原则只有三条延迟低、解析结果干净、不丢记录。不要从网上复制一组 DNS 就立刻改尤其是国外 DNS链路不好时反而更慢。3. 自建 DNS对特殊域名做策略性解析的正确姿势3.1 为什么要自建 DNS公共 DNS 功能太“公平”了它对所有域名一视同仁不会为你内网的 gitlab.internal 做解析也不会帮你把某个恶意域名禁掉。自建 DNS 的核心价值就两个字可控。你可以指定哪些域名走哪个上游、哪些域名直接拒绝、哪些域名返回你自定义的 IP相当于给网络装了一个“域名级的路由器”。自建 DNS 的架构并不复杂一台服务器接收内网客户端的查询请求先去本地缓存和自定义区域里找答案找不到再按规则转发给上游 DNS。适合的场景包括内网有几十台机器需要统一解析、有域名指定解析需求、被运营商劫持搞得不胜其烦。如果只是个人电脑想防劫持直接开 DoH 就行不需要自建但如果家里和公司有多台设备搭一台轻量的 DNS 服务器收益会大得多。3.2 方案选型dnsmasq、CoreDNS、Windows Server DNS自建 DNS 的工具有很多常见的有这几个dnsmasq最轻量配置简单适合家用和小型办公网络内存占用极小。CoreDNS插件化架构灵活性强适合 K8s 和微服务环境。Windows Server DNS适合企业 AD 域环境图形化管理可以做“区域黑洞”。AdGuard Home / MosDNS偏个人使用自带广告过滤和特殊域名管理结合的体验很好。我个人的经验是如果你只是想把内网域名解析、禁止访问某些域名、给特定域名指定上游dnsmasq 一台小机器就够用了如果你已经在跑 Kubernetes或者要用 etcd 做服务发现直接上 CoreDNS如果公司有域控Windows Server DNS 是最省心的选择。华三、锐捷这类路由器自带 DNS 代理功能本质上也是一个小型 DNS 服务适合不想单独部署服务器的场景但功能普遍比较弱复杂策略做不了。3.3 禁止解析指定域名怎么配企业屏蔽恶意域名的需求很常见。以 dnsmasq 为例配置几行就能实现# 将指定域名解析到 0.0.0.0客户端连接直接失败 address/bad.example.com/0.0.0.0 # 将该域名视为本地域名不再向上游转发 local/bad.example.com/第一行让该域名永远返回 0.0.0.0相当于给域名挖了个黑洞第二行告诉 dnsmasq“这是本地域名别去上游查”两个组合起来针对该域名的查询会直接在本机终结不会泄漏给上游。注意如果只写 local 不写 address除非你有对应的 hosts 记录否则客户端收到的结果是 NXDOMAIN这也能达到屏蔽效果。Windows Server DNS 的做法更简单粗暴在 DNS 管理器里为要屏蔽的域名创建一个“主要区域”区域里不添加任何主机记录。这样一来外部查询来到这台 DNS 时服务器会直接回答“名称不存在”。这就是常说的“区域黑洞”。不过要记得关闭区域传送避免配合垃圾查询把区域数据泄露出去。需要提醒的是DNS 层面屏蔽只是第一道防线很多恶意软件会硬编码 IP 直连所以后面该做的 IP 防火墙封锁照样要做。3.4 按域名分流给 GitHub 这类特殊域名做加速国内开发者在访问 GitHub 时经常遇到仓库下载慢、release 资产下载失败的问题。刨开带宽因素最核心的元凶就是 DNS 解析结果不稳定——某些域名被解析到不合适的 CDN 节点或者解析出来的 IP 根本连不通。这种情况下自建 DNS 可以按域名做分流只把 github 相关域名的查询转发给你认为解析更准确的海外 DNS其他域名照常走本地运营商 DNS互不干扰。dnsmasq 的配置方式是server/github.com/1.1.1.1 server/githubusercontent.com/1.1.1.1 server/githubassets.com/1.1.1.1这样设置的原理是dnsmasq 对匹配这些后缀的域名不采用默认上游而是单独指定 1.1.1.1 作为上游解析服务器。其他域名仍然走系统默认 DNS。如果你的网络到 1.1.1.1 也不顺畅还可以换成 8.8.8.8 或者你实测下来最快的落地 DNS。CoreDNS 的写法更灵活在 Corefile 里加 zonegithub.com githubusercontent.com githubassets.com { forward . 1.1.1.1 1.0.0.1 }自建 DNS 分流之后实际效果通常很明显release 大文件下载的成功率会显著提高之前经常断流的情况基本消失。但这里还有两个细节要提醒。第一GitHub 的 CDN IP 段是会变化的尽量不要用 hosts 写死适合临时应急长期方案还是走自建 DNS 按域名动态查询第二自建 DNS 的上游最好多填几个并开启缓存这样既能避免单点故障又能减少重复查询带来的延迟。3.5 搭建时的几个坑自建 DNS 服务器最容易忽略的是防火墙规则。UDP 53 端口要放行TCP 53 端口同样要放行。很多人只放 UDP遇到大响应或截断重查时查询会卡死。另外内网客户端的 DNS 最好由 DHCP 统一下发不要每台手动改否则配置混乱出了问题很难查。日志一定要开但别开太细错误级别的日志每天可能就几十 MB调试级别的日志按 GB 增长很正常。记录下 DNS 查询日志除了排障还能用来做安全审计这在特殊域名管理里非常有用。4. 530 Origin DNS ErrorCDN 回源和特殊域名的一场误会4.1 这个错误到底来自哪一层530 Origin DNS Error 这个词很多人第一次看到都会懵。它最常见的出现场景是 CDN 回源失败。CDN 边缘节点收到用户请求后需要回源站取内容。如果源站配置的是域名而 CDN 节点在解析这个源站域名时失败就会给客户端返回 530 Origin DNS Error。也就是说这个错误本质上不是“源站挂了”而是“CDN 找不到源站”。为什么说它和特殊域名有关因为犯错的源站域名往往是“内网专用域名”“已经过期但没删记录的域名”或者“CNAME 回环的域名”。客户端浏览器访问时本地电脑的 DNS 解析是正常的用户以为一切没问题但 CDN 节点在全球各地它们用来解析源站域名的 DNS 可能和你家内网完全不是一套体系于是内网能解析、公网不能解析CDN 抓瞎了。4.2 定位步骤和实战案例遇到 530我的排查顺序是确认错误来自哪一层。看响应头里是否有 CDN 节点标识比如 Fastly 的X-Served-By、x-cache字段有的话基本可以锁定是 CDN 回源问题。多位置解析源站域名。本机执行dig 源站.example.com再分别指定公共 DNS 解析一次比如dig 1.1.1.1 源站.example.com。如果本机能解析、公共 DNS 解析失败说明源站域名只在内网可见这就是问题根源。检查源站域名本身。域名是否到期、NS 记录是否被删、A 记录是否被清空、有没有配置 CNAME 回环。所谓 CNAME 回环就是 A 域名的 CNAME 指向 BB 又 CNAME 指向 A最后谁也无法解析出真实 IP。检查源站服务器的防火墙和 WAF。即使 DNS 解析正常CDN 回源 IP 也可能被源站的防火墙拒绝这时候错误码不一定直接叫 530但现象类似。之前处理过一个客户案例网站用的是 Fastly CDN源站填的是公司内部域名内网解析一切正常但 Fastly 的海外节点解析这个域名时找不到任何记录结果全站 530。后来把源站改成真实公网域名并做好 DNS 记录问题立刻消失。整个过程其实不复杂但如果不明白“CDN 解析源站域名”这个环节很容易在后端服务器上瞎折腾半天。4.3 和本地 DNS 的隐藏雷区很多人会把 530 和“本地电脑 DNS 坏了”混淆。实际上本地 DNS 查询失败时浏览器报的是ERR_NAME_NOT_RESOLVED不是 530。530 是服务端侧的错误提示。如果自建 DNS 在解析上游域名时返回 NXDOMAINCDN 节点也就拿不到源站 IP表现就是 530。有一个很实用的排查技巧在 CDN 配置后台把源站临时从“域名”改成“IP 地址”如果业务立刻恢复正常那就可以确定问题出在源站域名解析上而不是源站服务器本身。这个招数在紧急恢复时特别好用但要记得问题解决后把源站改回域名因为长期用 IP 当源站一旦后端机器 IP 变动运维工作量会很大。5. 不同系统下改 DNS 的一组速查以及“重启还原”的陷阱5.1 Ubuntu 22.04改了 DNS 又还原怎么办Ubuntu 22.04 默认使用 systemd-resolved/etc/resolv.conf只是一个软链接指向/run/systemd/resolve/stub-resolv.conf。你直接vi /etc/resolv.conf改内容重启网络或者重启 systemd-resolved 之后就会还原。正确做法是用 netplan 或者 nmcli。如果你用的是 netplan编辑/etc/netplan/下的 yaml 文件network: ethernets: eth0: dhcp4: true nameservers: addresses: - 223.5.5.5 - 119.29.29.29 version: 2然后执行sudo netplan apply如果你用的是 NetworkManager推荐用 nmclisudo nmcli con mod 有线连接 ipv4.dns 223.5.5.5 119.29.29.29 sudo nmcli con mod 有线连接 ipv4.ignore-auto-dns yes sudo nmcli con up 有线连接查看当前 DNS 状态不要用cat /etc/resolv.conf它显示的是 stub 地址 127.0.0.53容易误导。正确命令是resolvectl status。另外要注意的是如果 NetworkManager 在/etc/NetworkManager/NetworkManager.conf里配置了dnsdefault它启动时也会覆盖 resolv.conf 内容想彻底保留自定义 DNS可以改成dnsnone。5.2 Windows 系统从 GUI 到命令行Windows 10/11 改 DNS 最直观的路径是设置 - 网络和 Internet - 高级网络设置 - 更多网络适配器选项 - 双击网卡 - 属性 - Internet 协议版本 4 (TCP/IPv4) - 使用下面的 DNS 服务器地址。把首选和备用都填上确定之后就生效了。有些老环境会遇到“电脑改了 DNS 还是没用”的现象这时候要检查 IE 的“局域网设置”。路径是控制面板 - Internet 选项 - 连接 - 局域网设置。如果勾选了“为 LAN 使用代理服务器”或者“使用自动配置脚本”系统解析结果会被代理覆盖这时候不是你 DNS 改得不对而是代理配置在捣乱。命令行方式如下netsh interface ip set dns 以太网 static 223.5.5.5 primary netsh interface ip add dns 以太网 119.29.29.29 index2 ipconfig /flushdnsipconfig /flushdns是清本地 DNS 缓存改完配置一定要执行一遍否则旧缓存还会保留一段时间。5.3 麒麟操作系统国产系统同样用 nmcli银河麒麟 V10 这类国产操作系统很多界面设计得很友好但底层网络管理也还是 NetworkManager。图形化配置的话在控制面板或者系统设置里的“网络连接”中选中网卡进入 IPv4 设置把 DNS 服务器填进去备用 DNS 可以多填一个。命令行方式几乎和 Ubuntu 一致sudo nmcli con mod 有线连接 ipv4.dns 223.5.5.5,119.29.29.29 sudo nmcli con mod 有线连接 ipv4.ignore-auto-dns yes sudo nmcli con up 有线连接改完以后部分版本需要重启 NetworkManager 或者断网重连才能生效。另外有些麒麟版本会把连接配置写在/etc/NetworkManager/system-connections/下的文件里如果 nmcli 命令不生效可以直接编辑这个配置文件里的[ipv4]段把dns参数补上。5.4 路由器 DNS 代理为什么你的电脑改了也没用华三路由器和锐捷路由器都有一个“DNS 代理”功能。开启之后局域网中所有客户端的 DNS 请求都会被路由器代为处理客户端上无论怎么手动设置 DNS最终查询的其实还是路由器配置的上游服务器。这说明白之后就能理解为什么很多人电脑上填了 8.8.8.8实际解析结果却和之前一模一样。处理方式有两种一是把路由器 WAN 口的 DNS 改为自己想要的公共 DNS比如 223.5.5.5二是在 DHCP 设置里自定义下发 DNS 地址前提是先把 DNS 代理关掉。光猫桥接、路由器拨号的场景下还要确认运营商光猫没有开启 DNS 重定向不然你在路由器上改了 DNS光猫又给你劫持回去。这个问题在家庭网络里极其常见排查顺序永远是“客户端 - 交换机/路由器 - 光猫 - 运营商”。5.5 公共 DNS 优选一条命令测延迟最后给一个选 DNS 的土办法。备好几个候选地址然后逐个测延迟for dns in 223.5.5.5 119.29.29.29 114.114.114.114 8.8.8.8 1.1.1.1; do echo $dns ping -c 3 $dns | tail -1 done延迟低不代表解析结果一定好还要实际访问一遍常用站点看看体验。比如你在西安用移动宽带本地运营商的 DNS 解析本地内容最快但可能夹带劫持公共 DNS 干净稳定但解析某些域名时可能分配到异地节点。我的个人经验是优先选延迟 10ms 以内、同时支持 DoH 的公共 DNS国内外各备一两个作为自建 DNS 的上游组合使用效果往往最好。6. 进阶视角DNS 报文、隧道识别与日常自查6.1 用 tcpdump 看 DNS 报文里的目标 IP想确认本机发出的 DNS 查询到底发给了谁以及应答是不是来自预期服务器可以用 tcpdump 直接抓包sudo tcpdump -i eth0 -nn port 53 -v输出大概是这样的10.0.0.5.53123
返回列表