DNS污染和DNS劫持怎么排查
DNS污染和DNS劫持怎么排查
线上遇到“域名打不开”,很多人第一反应是服务器挂了、网站程序挂了、机房线路炸了。实际排查里,DNS这一层经常被低估。尤其是业务有海外节点、回国访问、游戏登录服、API域名、支付回调域名时,DNS异常会表现得很像网络故障,但抓细一点会发现,TCP还没开始,域名解析结果已经不对了。
DNS污染和DNS劫持看起来都叫“解析异常”,但排查方向不一样。污染更多是解析链路里返回了伪造结果,常见表现是不同地区、不同运营商查到奇怪IP,或者查到保留地址、国外无关IP。劫持更偏向递归DNS、运营商、路由器、终端代理软件把查询结果改掉,常见表现是跳广告页、跳运营商提示页、解析到某个固定IP。
先把现象拆开,不要一上来就换DNS
实际使用中发现,很多排查卡住,是因为一开始没有确认“异常发生在哪个环节”。浏览器打不开,不等于DNS错了;DNS解析正常,也不代表访问链路没问题。比较稳的方式是按访问路径拆:本地DNS解析、递归DNS返回、权威DNS记录、TCP连接、TLS握手、HTTP响应。
最简单的观察方式是用三个命令交叉看:nslookup、dig、curl。比如:
dig example.com
dig @8.8.8.8 example.com
dig @1.1.1.1 example.com
dig @114.114.114.114 example.com
curl -v https://example.com
如果不同公共DNS返回完全不同的A记录,先别急着判断污染。有些业务本来就用了CDN、GeoDNS、智能解析,不同DNS拿到不同IP很正常。关键看返回的IP是不是你的服务商、CDN厂商、BGP Anycast节点范围内的地址。如果解析到了完全陌生的IDC、保留地址、运营商提示页IP,就要继续往DNS异常方向查。
DNS污染和DNS劫持的表现差异
现场排障时可以用表现来缩小范围。下面这类对比不需要死记,主要是为了避免把所有DNS问题都归到一个筐里。
DNS污染:同一个域名在某些网络下解析到错误IP,换递归DNS不一定解决,尤其是UDP 53查询容易被干扰;返回结果可能很随机,TTL可能异常,多个公共DNS查询结果都可能被影响。
DNS劫持:更常见于本地网络、运营商DNS、路由器、办公网出口、安全软件。表现通常更“稳定”,比如每次都解析到同一个广告IP,或者HTTP被重定向到提示页面。换成可信DoH、DoT,或者换网络后恢复正常。
这里补充一点,DNS污染不一定只发生在跨境访问场景,国内链路中也可能遇到异常注入、缓存污染、递归DNS缓存脏数据。只是跨境域名、海外业务、敏感路径上更容易被放大。
第一步:确认权威DNS是否正常
排DNS问题时,权威DNS是基准线。权威DNS记录都错了,后面查什么公共DNS都没有意义。
可以先查NS记录:
dig NS example.com +short
然后直接问权威DNS:
dig @ns1.example-dns.com example.com A
dig @ns1.example-dns.com www.example.com CNAME
如果权威DNS返回的A记录就是错误IP,那不是污染,也不是劫持,是DNS配置问题。常见原因包括:解析控制台误改、CNAME链路改错、CDN域名解绑、DNS服务商套餐过期、域名被暂停解析、DNSSEC配置失败。
如果权威DNS返回正确,但本地递归DNS返回错误,再往递归链路查。
第二步:对比不同递归DNS的返回
同一个测试点上,建议至少查本地DNS、运营商DNS、公共DNS、DoH解析结果。不要只看一个结果。
常用命令可以这样跑:
dig example.com
dig @223.5.5.5 example.com
dig @119.29.29.29 example.com
dig @8.8.8.8 example.com
dig @1.1.1.1 example.com
如果本地DNS和运营商DNS异常,公共DNS正常,偏向本地DNS缓存污染或运营商DNS劫持。如果公共DNS也查到异常,但权威DNS正常,要注意查询包是否在路上被注入,尤其是UDP 53。
多说一句,dig默认走UDP。DNS响应比较大、开启DNSSEC、记录链比较长时,可能触发TCP回退。可以手动对比UDP和TCP:
dig example.com
dig +tcp example.com
如果UDP返回异常,TCP返回正常,这种情况在DNS污染排查里很有参考价值。因为UDP无连接,容易被伪造响应抢答;TCP DNS需要建立连接,伪造成本高很多。
第三步:看TTL和返回IP,不要只看“能不能解析”
DNS异常排查里,TTL很容易被忽略。正常业务的TTL一般有规律,比如60秒、300秒、600秒、3600秒。污染或劫持返回的记录,TTL有时会很奇怪,比如固定成1秒、0秒、86400秒,或者每次查询都不同。
可以连续查几次:
dig example.com +nocmd +noall +answer
sleep 2
dig example.com +nocmd +noall +answer
如果IP和TTL跳得很离谱,需要结合业务解析策略判断。CDN和Anycast本来就会调度,但不会无规则地把用户调到完全无关的地址段。
判断IP归属可以用 whois、ipinfo、bgp.he.net、ipip.net 等工具。重点看ASN、运营商、国家地区、机房归属。比如你的源站在美国CN2 GIA线路,解析却到了某个东欧小运营商IP,这基本不是正常调度。
第四步:绕过本地DNS缓存和系统缓存
本地缓存也会制造假象。Windows、macOS、Linux、浏览器、应用SDK都有可能缓存DNS。尤其是Java服务、Go服务、Node.js服务,缓存策略不一致,排查时不要只看命令行。
Windows可以清理:
ipconfig /flushdns
macOS常见命令:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
Linux要看用的是 systemd-resolved、nscd、dnsmasq 还是业务容器里的本地DNS。比如 systemd-resolved:
sudo resolvectl flush-caches
容器环境里还要看 /etc/resolv.conf。有些Kubernetes集群里,Pod走CoreDNS,再由CoreDNS转发到上游DNS。这个链路里任何一层缓存脏了,业务日志看到的都是“解析错了”。
第五步:抓包,看有没有抢答
如果怀疑DNS污染,抓包比猜有用。抓UDP 53查询,看响应包从哪里来、响应时间是否异常、是否出现多个响应。
Linux上可以这样抓:
tcpdump -i eth0 -nn udp port 53
然后发起查询:
dig @8.8.8.8 example.com
正常情况下,一个查询对应一个响应,响应源IP应该是你查询的DNS服务器。如果你问的是8.8.8.8,但很快收到一个“看起来像8.8.8.8”的响应,紧接着又收到真正的响应,且两个结果不同,就要警惕中间链路伪造响应。
这里有个细节:伪造响应通常会抢先到达,因为它不需要真的去递归查询。真正DNS响应慢几十毫秒甚至上百毫秒,应用通常采用先到的结果,于是错误IP进入缓存。
第六步:用DoH或DoT做对照测试
DoH走HTTPS,DoT走TLS,比明文UDP 53更难被中间设备篡改。它不是万能药,但很适合做对照实验。
用curl测试DoH:
curl -H 'accept: application/dns-json' 'https://dns.google/resolve?name=example.com&type=A'
或者:
curl -H 'accept: application/dns-json' 'https://cloudflare-dns.com/dns-query?name=example.com&type=A'
如果DoH返回正确,UDP 53返回错误,基本可以把问题锁定在明文DNS查询链路上。后续处理可以考虑客户端启用DoH、服务端程序指定可信解析器、办公网出口改DNS策略、或者让业务使用更稳定的CDN和权威DNS服务。
第七步:区分DNS问题和HTTP劫持
有些故障看起来像DNS劫持,其实是HTTP劫持。典型表现是DNS解析IP正常,但访问http://域名时被插广告、跳转提示页。HTTPS正常,HTTP异常。
排查方式很直接:
dig example.com
curl -I http://example.com
curl -I https://example.com
curl --resolve example.com:443:源站IP https://example.com -v
如果DNS正常,HTTPS正常,HTTP被重定向,多半不是DNS层问题,而是HTTP明文流量被中间设备改了。处理方式是强制HTTPS、开启HSTS、减少HTTP入口,CDN侧配置301跳转。游戏客户端、移动App接口尽量不要留明文HTTP接口,排障成本很高。
第八步:海外业务要额外看线路和解析策略
海外服务器访问国内用户,DNS问题经常和线路问题搅在一起。比如用户说“解析错了”,实际是解析到了美国IP没错,但电信晚高峰丢包30%,于是页面打不开。也有反过来的情况,线路很好,DNS被污染导致用户根本没连到正确服务器。
这类场景建议把监控分成两类:DNS解析监控和网络质量监控。DNS监控看各省、各运营商解析结果是否落在预期IP段;网络质量监控看ICMP、TCP 443、HTTP状态码、TLS握手耗时。
如果业务需要海外节点又要国内访问稳定,选服务器时不能只看CPU和内存。线路类型要看清楚,是普通国际线路、CN2、CN2 GIA、BGP优化,还是韩国、日本、香港回国优化。比如游戏登录服、跨境企业站、API中转,DNS正常只是入口正确,后面还得靠线路质量兜住延迟和丢包。
如果你也在找这种海外精品线路、高防服务器或回国优化节点,可以看看129云。像美国精品网-D型适合需要三网精品线路的业务,8C、8G DDR4 ECC、120G SSD、125Mbps峰值带宽,适合企业站、接口服务、轻量游戏业务;宁波高防-特惠带100Gbps防御,更偏向被DDoS打过、需要国内高防入口的场景;韩国-G型有傲盾防火墙和回国优化线路,适合对延迟敏感的亚洲业务。需要确认线路、带宽、防御策略,可以直接打客服热线400-9177118问清楚节点情况。
权威DNS配置也要排,不少问题是自己配出来的
实际排障中,DNS异常并不总是外部污染或劫持。权威DNS配置不合理,也会让用户看起来像“被劫持”。
CNAME链路太长
有些域名是 www.example.com CNAME 到 cdn.example.net,再CNAME到 vendor.cdn.net,最后才解析A记录。链路太长时,某些递归DNS解析失败概率会上升,排查也更费劲。建议把关键业务域名的CNAME链路控制住,尤其是登录、支付、API这类入口。
TTL设置不匹配业务节奏
需要快速切换的业务,TTL设成3600秒甚至86400秒,故障切换时会很被动。TTL设得太低,比如1秒、5秒,也会增加递归查询压力,还可能触发部分DNS服务商或递归DNS的限制。常见业务入口用60秒到300秒较多,稳定静态业务可以放到600秒或更高。
多线路解析规则互相覆盖
智能解析里经常出现“默认线路”和“运营商线路”冲突。比如给电信配置了A记录,联通没配,移动走默认;后面改默认记录时,把移动用户调到了错误IP。排查时要按运营商分别查,不要只在办公室网络测一次。
可以用不同DNS源测试:
dig @202.96.128.86 example.com
dig @219.141.136.10 example.com
dig @221.131.143.69 example.com
这些地址只是举例,实际要结合地区和运营商找递归DNS。更稳的是用多地拨测平台,直接看全国各省解析结果。
移动端和客户端业务的DNS排查更麻烦
网站还能用浏览器、curl、dig排,App和游戏客户端就麻烦一些。很多SDK内置HTTPDNS,或者客户端自己缓存IP,甚至还有备用域名、备用IP、配置中心下发域名。用户反馈“域名解析错”,服务端看不到过程。
建议客户端日志至少记录这些字段:当前网络类型、运营商、递归DNS、域名、解析IP、解析耗时、连接IP、TCP耗时、TLS耗时、HTTP状态码。不要只记录“请求失败”。没有这些字段,后端排障只能靠猜。
如果用了HTTPDNS,也要注意容灾。HTTPDNS服务不可用时,客户端要能回退系统DNS;解析结果要带TTL,不要永久缓存;多IP返回时要支持失败切换。游戏业务里登录服域名尤其关键,登录入口挂了,后面区服再稳定也没用。
服务器侧怎么证明自己没问题
有时客户或业务方会说“你们服务器访问不了”,这时候要用证据拆开。服务器侧可以提供这些信息:
源站IP当前可连通:从多地执行 ping、mtr、tcping 443。
服务端口正常:ss -lntp 查看监听,curl 127.0.0.1 或 curl 源站IP验证服务。
证书正常:openssl s_client -connect example.com:443 -servername example.com。
权威DNS正确:直接查询权威NS返回预期A记录。
异常用户解析结果:让用户执行 nslookup example.com,并截图DNS服务器地址和返回IP。
如果用户解析到错误IP,而源站和权威DNS都正常,基本就能把问题从服务器故障里摘出来。后面再看用户网络、运营商DNS、本地路由器、办公网安全设备。
办公网和家用路由器也会劫持DNS
办公网里常见安全网关、上网行为管理、透明代理、DNS审计设备。有些设备会强制把所有UDP 53转发到内网DNS,即使你手动指定8.8.8.8,也会被拦下来。表现就是dig命令看起来问了8.8.8.8,实际响应不是它给的。
可以用抓包看响应源,也可以测试非标准端口或DoH。如果DoH正常,UDP 53异常,办公网设备嫌疑很大。
家用路由器也不能忽略。路由器被改DNS、运营商光猫下发DNS异常、某些“加速插件”接管DNS,都见过。让用户换手机热点测试,是最快的隔离办法。热点正常、宽带异常,就别继续查服务器了。
遇到污染或劫持后的处理方式
如果确认是本地或运营商DNS劫持,短期可以让用户切换可信DNS,或者启用DoH。面向公网用户的网站,不能指望每个用户都会改DNS,业务侧要尽量减少被影响面。
关键域名建议接入稳定的权威DNS服务,开启多地监控。被污染概率高的域名,可以准备备用域名,但备用域名不要和主域名放在同一个容易出问题的解析链路里。App和客户端可以接入HTTPDNS,但要设计好回退机制。
如果是跨境业务,域名解析和线路要一起看。DNS只负责把用户带到入口,入口线路差还是会失败。高防场景还要考虑清洗中心和回源线路,别只看防御峰值。100Gbps防御能扛住一类攻击,但如果回源绕路、解析策略乱,用户体验还是会抖。
如果确认是权威DNS记录被错误缓存,降低TTL不一定马上生效,因为错误记录已经在递归DNS里。可以联系DNS服务商刷新缓存,或者临时切换域名入口。CDN场景下还要同步检查CNAME是否仍绑定在厂商侧,很多“解析正常但访问403”的问题,是CDN配置被删了。
排查时常见误判
只在一台电脑上测
一台电脑只能代表一个网络环境。DNS问题强依赖地区、运营商、递归DNS和本地缓存。至少要用本机、手机热点、云服务器、多地拨测交叉验证。
看到IP不同就判定被污染
CDN、BGP Anycast、智能DNS都会返回不同IP。判断关键不是“是否一致”,而是“是否符合调度预期”。如果都在CDN厂商地址池里,状态码正常,延迟合理,那就是正常调度。
把所有跳转都当DNS劫持
DNS劫持改变解析结果,HTTP劫持改变明文内容或响应。HTTPS证书校验正常时,中间设备很难直接改内容。HTTP被插广告,HTTPS正常,排查方向要换到明文链路。
忽略IPv6
现在不少网络会优先走IPv6。A记录正常不代表AAAA记录正常。遇到部分用户打不开,要查:
dig example.com A
dig example.com AAAA
curl -4 -v https://example.com
curl -6 -v https://example.com
如果IPv6解析到了不可达地址,浏览器可能先尝试IPv6再回退IPv4,用户看到的就是打开慢或偶发失败。
一个现场排查流程可以这样走
用户反馈域名打不开后,先让用户提供本地解析结果、当前网络、运营商、地区、失败截图。不要只要一句“打不开”。
本地执行 dig 和 curl,看解析IP、HTTP状态码、TLS证书是否正常。与此同时,用手机热点测同一个域名,判断是否只发生在某个网络。
直接查权威DNS,确认记录没有配错。再查多个公共DNS,对比UDP和TCP结果。UDP错、TCP对,继续抓包看是否有抢答。
如果DNS都正常,继续查TCP连通性、MTR路由、端口监听、证书SNI、CDN回源。如果DNS异常,查TTL、IP归属、递归DNS来源、本地缓存、办公网出口设备。
需要给业务方输出结论时,最好附上命令结果。比如:权威DNS返回1.1.1.1,本地运营商DNS返回2.2.2.2,DoH返回1.1.1.1,tcpdump发现UDP 53存在两个响应包,先到包返回2.2.2.2。这样的证据比“疑似污染”有用得多。
命令结果里重点看什么
dig输出里看 SERVER 字段,确认你问的是哪个DNS。很多人以为自己问了公共DNS,其实系统还是走本地路由器。
看 ANSWER SECTION,确认A、AAAA、CNAME链路。CNAME每跳都要看,不要只看最后A记录。
看 Query time,异常快的错误响应有时是抢答。比如跨境问8.8.8.8,正常可能几十毫秒,错误包1毫秒回来,就不太正常。
看 TTL,判断是不是缓存结果,以及TTL是否符合权威DNS设置。
看返回IP的ASN和归属。如果解析结果进入了预期CDN、云厂商、IDC地址池,再继续查网络和服务;如果完全不相干,DNS链路优先级更高。
什么时候该换域名,什么时候该换解析
如果只是某个递归DNS缓存脏了,等TTL过期或联系刷新缓存就行,不需要大动干戈。
如果域名长期在多个网络下被污染,业务又对可用性敏感,准备备用域名是现实做法。备用域名要提前预热证书、CDN、WAF、CORS、App白名单,不要等故障发生再临时加。
如果权威DNS服务稳定性差、解析生效慢、线路规则混乱,就该换权威DNS服务。换之前降低NS记录TTL,迁移后观察至少24到48小时,因为部分递归DNS对NS缓存不完全按预期刷新。
如果是海外业务被国内访问质量拖住,换DNS解决不了丢包和绕路。要看服务器线路、BGP策略、回国优化质量、高防清洗路径。域名入口、线路、源站、防御是连在一起的,任何一层乱,用户看到的都是“打不开”。