先说明一句:这类标题在技术社区里很常见,但真正有价值的从来不是“怎么实施劫持”,而是“劫持到底怎么发生、怎么被我发现、怎么把它挡住”。这篇文章我完全站在防御者的角度来写,把自己过去处理过的DNS劫持事件拆开讲清楚。无论你是企业网管、站点运维,还是普通用户,看完之后都应该能独立完成一次DNS安全排查,并且知道该在哪些环节把洞补上。
1. DNS劫持的本质:为什么域名解析会成为攻击目标
1.1 一次“网页打不开”背后的完整解析链路
先捋一遍DNS解析的正常流程,因为不搞清楚正常长什么样,就没办法判断什么是异常。
你在浏览器输入一个域名,操作系统首先查本地 hosts 文件,然后查本地DNS缓存,接着把请求发给配置的递归DNS服务器(比如运营商给的114.114.114.114或8.8.8.8)。递归服务器帮你一层层查询,最终拿到这个域名对应的IP,返回给浏览器,浏览器再向这个IP发起HTTP请求。
整个链路看起来简单,但它涉及的节点非常多:终端的hosts文件、终端DNS缓存、网络出口的路由器、运营商递归DNS、权威DNS服务器、以及中间传输链路。任何一个节点被篡改,用户拿到的都可能是一个错误的IP。
我遇到过一台服务器,健康检查一切正常,但用户反馈时好时坏。后来抓包才发现,终端解析出来的IP根本不是服务器真实IP,而是某个CDN节点IP。这就是典型的解析链路被动了手脚——某个中间环节把域名指向了错误位置,流量被引到了别处。
1.2 劫持可能发生的四个关键位置
DNS劫持本质上不是一种单一攻击手法,它是一类“对解析过程任意环节做手脚”的攻击统称。按发生位置分类,更容易理解它的全貌:
本地hosts文件篡改。 这是最古老也最直接的方式。hosts文件优先级最高,只要在里面加一条记录,域名解析就会被强行指向指定IP。早期的网吧、局域网环境里,通过修改hosts来屏蔽或引流是常规操作。
终端DNS配置篡改。 攻击者通过木马或恶意脚本,把系统网卡里的DNS服务器地址改成自己控制的服务器。这样终端所有域名解析请求都会经过攻击者,他就能按需返回伪造IP。
路由器DNS设置篡改。 家用路由器管理密码弱是重灾区。攻破路由器后,把LAN侧下发的DNS改成恶意地址,整条网线下所有设备全部中招,而且终端上几乎看不出异常。
链路或递归服务器劫持。 运营商层面或公共WiFi环境下的劫持多发生在这里。公共WiFi的网关直接拦截DNS请求,返回伪造响应,或者运营商在某些网络节点对特定域名做内容替换。这类劫持对用户完全透明,用户体验往往只是“打开了奇怪的页面”。
1.3 理解攻击者的动机,才能知道该防什么
做防御的一定要搞明白攻击者想得到什么,不然防护方向很容易跑偏。
第一类动机是流量变现。把热门网站劫持到广告页,或者插入推广脚本,这是最常见的黑产模式。典型特征是页面里多了不存在的浮层、跳转链接,或者部分资源加载变慢。
第二类动机是钓鱼欺诈。把银行、电商、邮箱域名解析到高仿的钓鱼站点,用户输入账号密码直接进攻击者的数据库。这类劫持目标明确,通常带有时间窗口,因为钓鱼站点很快会被发现和封禁。
第三类动机是中间人窃听。攻击者把HTTPS请求降级为HTTP,或者通过伪造证书截取流量,窃取表单里的敏感数据。这类攻击技术门槛更高,但一旦得手,损失也最大。
理解这个动机链条之后,你会发现一个事实:防御的重点不只在“防止被劫持”,还包括“被劫持之后能快速发现”。很多企业就是少了后者,才让劫持持续了很长时间。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 常见劫持场景识别:从本地到链路的异常特征
2.1 不是所有“弹广告”都是DNS劫持
很多朋友把浏览器弹广告、首页被改、搜索跳转这些问题一律归为DNS劫持,这个判断其实不够准确。
浏览器层面的广告弹窗,很多是安装了恶意浏览器插件或者被捆绑安装了推广软件;首页被改,通常是快捷方式被加了启动参数;搜索跳转,可能是浏览器被植入了恶意扩展。这些问题属于终端污染,和DNS劫持的修复方式完全不同。
判断是不是DNS劫持,有一个更可靠的思路:换网络环境验证。同一台设备,在办公室网络、手机热点、家里宽带三种环境下分别解析同一个域名。如果办公室和家里都有问题,而手机热点正常,那问题大概率在终端本身;如果只有某个网络环境下异常,那问题就集中在对应的网络链路上。
2.2 排查过程中最常用的几个命令
我建议把下面这几个命令练熟,它们可以覆盖90%以上的排查场景。
nslookup domain.com:查询域名解析结果,能看到当前配置的DNS服务器和返回的IP。nslookup domain.com 8.8.8.8:指定DNS服务器查询,用来对比不同解析器返回的结果是否一致。ipconfig /all(Windows)或nmcli dev show(Linux):查看网卡实际配置的DNS地址。ipconfig /displaydns:查看本地DNS缓存,有时候能发现缓存的异常记录。tracert或pathping:追踪到目标IP的路由路径,能发现流量是否被引到了异常节点。
排查的标准动作是先跑 ipconfig /all 确认终端DNS设置,再分别用默认DNS和公共DNS查询目标域名,对比结果。如果两个解析结果不一致,基本可以确定劫持发生在链路或解析器层面。
2.3 运营商级劫持和路由器劫持的特征差异
这两种场景经常被混为一谈,但实际特征差别很大。
运营商级劫持的典型特征:解析结果是真实IP或CDN节点,但在HTTP层面被插入了一段广告脚本,或者是特定资源请求被重定向。这是因为很多运营商劫持走的是“HTTP注入”路线,不是修改DNS解析结果。你会看到页面功能正常,但多了一些莫名其妙的代码。这类劫持换DNS服务器通常无效,因为流量还是会经过运营商网关。
路由器级劫持的典型特征:整个局域网内所有设备解析同一个域名都会得到同一个错误IP,而且用公共DNS再查一遍,结果是正确的。这时候登录路由器后台,查看WAN口和LAN口的DNS设置,基本就能实锤。很多家用路由器的DNS选项藏在“高级设置”里,要仔细翻。
这里有个经验:遇到可疑解析结果时,不要急着下结论,先做一次“多DNS对比”和“多网络对比”,这两个动作能帮你快速缩小范围。
3. 一次DNS劫持事件的完整排查链路
3.1 一个真实案例:某公司办公网整段“被搬家”
去年处理过一个案例,某公司办公网突然无法访问自家的SaaS管理系统,页面提示证书错误,但手机热点访问完全正常。客户一开始以为是网络故障,重启了路由器和交换机,问题依旧。
我到现场之后没有急着看配置,先做了三件事:第一,在一台测试机上用 nslookup 查询目标域名,记录默认DNS返回的IP;第二,用 nslookup 指定公共DNS再查一次;第三,单独用一台未联网的笔记本电脑,通过手机热点访问目标域名,记录正确IP。
结果很明确:办公网内解析出的IP和公共DNS解析出的IP完全不一样,而手机热点解析出的IP与公共DNS一致。办公网内的解析结果被污染了,问题从“网络故障”变成“解析链路异常”。
3.2 分层排查:终端、网关、递归解析分别是哪一环
排查DNS问题有一个方法我非常推荐——分层排除法,从上到下依次确认。
第一层确认终端配置。检查当前网卡DNS设置是不是被改成了未知地址,看看hosts文件里有没有异常条目。如果DNS是自动获取的,就要进入第二层。
第二层确认网关配置。登录路由器后台,查看DHCP服务下发的DNS是什么。如果路由器本身配置了固定的DNS地址,而该地址不是运营商提供的官方地址,这里就很可能就是问题源头。很多路由器被攻破后,攻击者会保留上网功能,但把DNS偷偷替换成自己控制的地址。
第三层确认解析结果。在终端上用公共DNS直接查询目标域名,如果结果正确而默认DNS结果错误,说明递归解析环节或链路环节有问题。这时候可以再换一台设备,同样做一层层验证,确认影响范围是单点还是全网。
回到这个案例,我们登录路由器后台后发现,DHCP下发的DNS地址被改成了一个不认识的IP,而WAN口的DNS设置变成了某个偏僻域名。进一步查看系统日志,发现路由器管理界面在几天前有过多次异常登录尝试。攻击路径基本清晰:路由器管理后台被爆破,DNS设置被篡改,办公网内所有终端都被分配了恶意DNS。
3.3 从发现到恢复:应急处置的五个关键步骤
确认根因后,恢复工作并不复杂,但顺序很重要。
第一步,修改路由器管理密码,关闭远程管理功能,如果支持,把管理界面绑定内网IP访问。不堵住这个口子,清了配置也会被再次入侵。
第二步,把DHCP下发的DNS改回运营商公共DNS,同时将备用DNS设置为其他可信公共DNS,形成冗余。
第三步,清除受影响终端的DNS缓存。Windows执行 ipconfig /flushdns,macOS执行 sudo dscacheutil -flushcache,Linux执行 systemd-resolve --flush-caches。不改缓存的话,部分终端还会继续访问错误的IP。
第四步,核查路由器固件版本,更新到官方最新版。很多路由器被攻破是因为旧版固件存在已知漏洞,更新固件的优先级甚至高于修改密码。
第五步,排查攻击者是否在内网留下后门。检查路由器上是否配置了端口转发、DMS、NAT规则等异常条目,查看是否有未知设备连接了WiFi,必要时直接重置路由器并重新配置。
整个过程大约持续了一个下午。恢复后我们又在办公网内做了24小时解析监控,确认没有再次出现异常。
4. 防护体系搭建:终端、网络、服务器三个维度
4.1 终端侧:本地DNS配置与安全基线
终端侧的政策,我不建议太激进,太激进了执行不下去,但三个底线必须守住。
第一,hosts文件权限收紧。Windows下hosts文件的默认权限允许管理员写入,这其实够用了。问题是很多运维为了方便,把Users组的写入权限也打开了,这就给了普通进程可乘之机。检查一下hosts文件的安全属性,确保只有Administrators和SYSTEM有写入权限。
第二,DHCP获取DNS为主,静态DNS为备。普通终端用自动获取就行,只要网关侧的DNS配置正确,终端就不容易出问题。特殊设备需要固定DNS的话,优先选两个不同运营商的公共DNS,避免DNS服务商单点故障。
第三,安装EDR终端防护软件。这个问题经常被忽略。很多木马会调用系统API修改DNS配置和hosts文件,纯靠人工检查根本发现不了。终端防护软件能在进程层面拦截这类高危行为——试图修改网络配置、写入hosts文件、添加计划任务,任何一项都足够触发告警。
这里有一个小技巧:定期用脚本对比hosts文件的哈希值,并和上一次备份做比对。简单的批处理或PowerShell脚本就能做到,发现有变化就报警。别看这个办法土,但它能抓住绝大多数自动化的hosts篡改。
4.2 网络侧:路由器与内网DNS的加固清单
路由器是内网安全的闸门,但又是很多人最不上心的设备。我见过不少企业,服务器做了很重的安全建设,结果办公室的无线路由器用的是默认密码,管理界面暴露在公网。这种防护根本扛不住任何一次扫描。
路由器加固可以按下面的清单执行:
- 修改管理密码,不要用admin/admin这类默认组合,密码至少12位并包含三类字符
- 关闭WAN侧管理功能,管理界面只允许LAN侧访问
- 开启固件自动更新,或者每月手动检查一次官方固件版本
- 关闭不必要的远程管理协议,比如Telnet、SNMP,如果必须开启,限制来源IP
- 在DHCP设置中,把首选DNS和备用DNS都配置为可信公共DNS,不要留空让路由器自动获取运营商DNS
- 开启日志功能,并定期检查登录记录和配置变更记录
- 如果公司有自建DNS服务器,路由器DHCP应指向内网DNS服务器,同时保留一个公共DNS作为兜底
内网有自建DNS服务器的场景,还要额外注意:DNS服务器本身要开启递归限制,避免被利用做放大攻击;对管理接口做IP白名单限制;定期审查区域传送(zone transfer)配置,防止区域数据被剥离。
4.3 服务器侧:DNSSEC与解析监控
如果你的业务有自己托管的域名,网站安全就不能只看服务器本身,还要关注域名解析的权威环节。这里推荐做三件事。
第一,启用DNSSEC。DNSSEC通过数字签名保证解析结果的真实性和完整性。简单说,它让递归服务器能够验证收到的解析响应确实来自权威服务器,且内容未被篡改。现在主流域名注册商和DNS服务商都支持一键开启DNSSEC,操作门槛已经很低。开启之后,即使攻击者尝试伪造解析响应,递归服务器也会因为签名校验失败而拒绝采纳。
第二,解析结果多节点监控。不要只从一台机器监控域名解析,从不同地域、不同运营商分别查询,能更早发现地域性劫持。目前有不少云监控服务提供面向全球节点的DNS查询能力,可以免费或低成本使用。
第三,关注证书透明度日志。如果攻击者想劫持你的域名做钓鱼,他通常需要申请一个看起来相似的证书,或者通过某些渠道拿到伪造证书。证书透明度日志(Certificate Transparency)会记录所有公开签发的证书,定期搜索你的域名,就能发现有没有被冒名申请。这个步骤很多人不知道,其实比很多防护措施都实用。
5. 实战中的常见误区和经验补充
5.1 误区一:换了公共DNS就等于安全了
这是我在排查中遇到最多的误解。很多人觉得用了127.0.0.1或8.8.8.8就高枕无忧,但实际上劫持发生在多个层面,更换递归DNS只是解决了“递归服务器被污染”的问题,链路层的HTTP注入、路由器层的DNS篡改依然存在。
如果你用的是运营商网络,流量必然经过运营商网关,运营商如果想做HTTP注入,无论你配置哪个DNS都会生效。换句话说,换DNS能解决递归解析环节的劫持,但解决不了链路层的干扰。
真正的解决思路是:能用HTTPS的尽量全站HTTPS,从协议层防止内容被注入;对解析结果的校验要靠DNSSEC,从机制上保证返回值的可信度。DNS本身只是“找到路”,路是否安全要靠其他机制来保证。
5.2 误区二:加了HTTPS就能完全防劫持
HTTPS确实能防止内容被篡改和窃听,但它防不了DNS指向本身。举个例子,攻击者把www.example.com解析到了一个恶意服务器的IP,恶意服务器如果拿不到你域名的私钥,确实没法伪造有效证书,浏览器会报证书错误。
问题是,有多少用户会在看到证书错误时停下来?很多人的第一反应是“网络有问题”,然后选择“继续访问”或“添加例外”。尤其是企业内部系统,用户对证书告警的敏感性更低。
更危险的是,攻击者可以先通过HTTP降级让用户访问http版本,如果站点的HTTP版本没有任何安全机制,内容就会完全暴露。所以正确做法是:全站HTTPS加HSTS(HTTP Strict Transport Security),让浏览器强制走HTTPS,并且把HSTS的max-age设置足够长,这样即使解析被劫持,浏览器也会拒绝HTTPS连接而不是静默降级。
5.3 几个值得长期坚持的运维习惯
最后分享几个我在实际工作中确认有效的习惯,不一定能立刻看到效果,但长期坚持一定有价值。
第一个习惯是记录“正常值”。花点时间把业务系统的正确解析结果记录下来,包括每个域名对应的预期IP、预期CDN节点、预期的证书签发机构。有这份基准数据,排查异常时就不用瞎猜。
第二个习惯是定期做解析审计。每个月抽出一个小时,用脚本批量查询核心域名,把结果和基准数据对比,输出差异清单。这个动作能帮你发现很多早期问题,包括服务商切换、DNS记录被误删,甚至被劫持。
第三个习惯是维护好DNS的变更记录。DNS记录不是“配好就不管”的东西,很多劫持事件其实是内部误操作引起的,比如某位同事在控制台把A记录指向了另一台机器。给DNS变更加审批流程,保留完整的变更历史,排查的时候能省很多时间。
第四个习惯是备份路由器配置。在路由器配置稳定之后,导出一份配置文件,恢复出厂设置后能快速回滚。很多中小企业碰到路由器配置丢失或异常,都是临时靠印象重新配置,完全是在裸奔。
说到这儿,顺手做个总结:DNS劫持本质上是一场关于“你信任什么”的攻防。你信任的递归服务器可能不可靠,你信任的网关可能已被攻破,你信任的解析结果可能是伪造的。防御的核心思路就是尽量减少单点信任——DNSSEC提供验证,HTTPS保证内容,多DNS备份保证可用性,分层排查保证可发现。这三层叠起来,绝大多数劫持都翻不起水花。我自己在实际排查中最深的一点体会是:收到告警之后别着急改配置,先把终端、网关、递归解析三层都确认一遍,用数据定位问题,而不是凭感觉操作。这套方法我用了很久,每次都靠谱。
