ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

特殊域名解析实战:从自建DNS到劫持排查全指南

特殊域名解析实战:从自建DNS到劫持排查全指南 搞网络的人都清楚DNS这东西平时安安静静待在系统角落里一旦出问题全公司都在喊“网断了”。普通域名还好搞顶多解析慢一点换个公共DNS基本能解决。但只要你碰上“特殊域名”画风立马就不一样了要么反复解析超时要么返回一个完全对不上的IP要么这个域名在公网DNS里压根就查不到。前阵子我帮朋友排查一个内网系统的问题从下午折腾到晚上九点多最后发现根因居然是一台旧路由器把某个特殊域名的解析结果给劫持成了广告IP——这种案例真不是个例。这篇文章我打算从一个长期在运维和网络一线摸爬滚打的角度把“特殊域名”这件事彻底讲透包括它到底特殊在哪、自建DNS怎么做、服务器和路由器上怎么配DNS、公共DNS怎么优选、各类高频坑点怎么排查。如果你家里有NAS和自建服务想把GitHub这类访问不稳定的域名做调优或者你是企业网络管理员需要搭建内部DNS、管理内网域名、屏蔽指定域名又或者你被“DNS又解析错了”折腾过想真正搞懂底层逻辑——这篇文章都值得你花十五分钟看完。1. 特殊域名到底“特殊”在哪先从解析逻辑说起1.1 一次完整的DNS解析是怎么走完的很多朋友遇到DNS问题就慌其实只要把解析链路画出来定位思路就清晰一大半。一次普通查询大概是这样的应用发起域名解析请求系统先翻本地hosts文件没命中就看本地DNS缓存缓存也没有就把请求丢给网卡上配置的DNS服务器通常是递归解析服务器。这台递归服务器如果自身没缓存会去问根域名服务器根服务器告诉它“你得去找顶级域服务器”顶级域服务器再指路到权威服务器最后权威服务器返回该域名对应的IP。整个过程就像查一个层层转接的电话最终拿到号码才能拨出去。DNS最常见的比喻是“电话簿”我想补充一个更贴切的版本对特殊域名来说这本电话簿可能被人改过、可能缺页、也可能压根用的是另一本电话簿。你打不通电话不一定是你拨号方式错了而是电话簿本身出了问题。理解这一点排查思路就不会跑偏。1.2 特殊域名的四种典型形态我在实际工作中发现“特殊域名”这个概念很宽泛但归纳起来基本逃不出下面四种形态。第一种是公网上存在、但解析结果被污染或劫持的域名。表现是你在不同设备上nslookup同一个域名拿到的IP居然不一样甚至返回一个明显不对的IP访问时弹出各种广告页面。第二种是公网上不存在、只有内网才有的私有域名比如企业内部的erp.internal、打印机用的print.local这类。公共DNS查这些域名永远是NXDOMAIN只有内部DNS才能解析。第三种是同一个域名在不同网络环境下需要返回不同结果的场景也就是常说的Split DNS分流解析典型例子是内网访问的CRM系统走内网IP外网访问同一域名走公网IP。第四种是需要你主动干预解析结果、让域名“强制”指向某个特定IP的域名比如希望通过绕过默认链路的方式优化访问速度的场景。1.3 域名解析异常背后的三大根因把特殊域名的异常案例刨到底根因就三类。第一类是上游权威服务器出问题比如某域名的NS记录指向的服务器挂了或者源站DNS配置有误导致递归查询拿不到权威答案第二类是本地配置被覆盖或写错比如Linux服务器改了/etc/resolv.conf之后重启被系统重置或者hosts文件里残留了过期IP第三类是中间链路有人捣鬼路由器被篡改、运营商Local DNS做域名抢答、甚至局域网内的ARP欺骗都会导致解析结果被改写成恶意IP。排查时我会按“从下往上、从外往内”的顺序来先看本机hosts和配置再看本地DNS服务器有没有异常最后才怀疑链路上的拦截这样不会一上来就被带偏。2. 自建DNS处理特殊域名从配置到优化一次讲透2.1 为什么特殊域名场景需要自建DNS公共DNS服务器是为大众场景设计的它不会知道你内网有个域名叫files.lan更不会知道你想把某个海外域名的解析结果定向到一个离你更近的节点。所以一旦涉及到特殊域名靠自己搭一台DNS服务器往往是最彻底的解法。自建DNS的好处有三个一是可以自定义解析规则对指定域名返回指定IP二是可以做缓存加速减少重复查询带来的延迟三是能精确控制屏蔽策略哪些域名不允许解析由你说了算。这里我要特别说明一下“自建DNS加速访问”这件事。很多人以为自建DNS是什么激进的黑科技其实它做的只是把公共DNS给你选的“电话簿结果”换成你自己挑选的更优节点。就好比你要给远方一个朋友打电话默认电话簿给了你一个号码但你知道他还有另一个更快接通的号码你把它存进自己的通讯录而已。这种优化不改变你对任何服务的访问权限只改变路由选择的效率安全边界上没有越界。2.2 最轻量的干预方案先用hosts把手动解析跑起来如果你只是想让两三个特殊域名稳定指向指定IP没必要立刻上完整的DNS服务器直接改hosts文件就行。Windows系统hosts文件在C:\Windows\System32\drivers\etc\hostsLinux和macOS在/etc/hosts。格式很简单一行一条“IP 域名”的对应关系比如我把某个服务固定指向内网服务器的IP就写192.168.1.100 gitlab.internal改完立刻生效不需要重启系统Windows下如果没生效执行ipconfig /flushdns刷一下DNS缓存即可。这个方法虽然粗暴但非常可靠因为系统查询hosts的优先级永远高于网络DNS。它的缺点也很明显只能管本机如果你有几十台机器都要做同样的特殊映射一台台改hosts会想哭。2.3 轻量自建DNS服务器dnsmasq实战涉及整网段的特殊域名策略时我推荐用dnsmasq。它本来是做DNS缓存和DHCP的小工具配置简单、资源占用极低跑在一台树莓派或者老旧的x86小主机上都毫无压力。在Debian/Ubuntu系上安装就是一行命令apt install dnsmasq -ydnsmasq的配置文件默认在/etc/dnsmasq.conf我习惯在/etc/dnsmasq.d/下新建独立配置文件来管理特殊域名规则清晰也不容易搞乱。下面是我的常用配置片段# 上游DNS server223.5.5.5 server119.29.29.29 # 缓存条目数 cache-size10000 # 把某个特殊域名固定解析到内网机器 address/gitlab.internal/192.168.1.100 # 把某个公网域名强制解析到指定IP以实际解析结果为准 address/github.com/140.82.112.3注意这里的server223.5.5.5等参数指定了上游递归服务器。dnsmasq会把自己当成局域网内其他设备的DNS入口收到查询后如果命中自定义规则就返回自定义结果否则就向上游转发并缓存。配置完需要重启服务生效systemctl restart dnsmasq然后在这台机器的局域网内把其他设备的DNS服务器指向dnsmasq所在机器的IP整网的“特殊域名”策略就生效了。我用这套方案给家里NAS和几台开发机做了一个统一的解析服务稳定跑了两年多没出过幺蛾子。2.4 特殊域名实战给GitHub这类访问不稳定的域名提速GitHub是我遇到过的“特殊域名”里最典型的案例。它的访问不稳定很多时候并不是网络被刻意限速而是默认解析到的IP节点距离你太远或者根本没连通性。优化思路就是手动挑选一个在你本地网络环境下连通性好的IP然后通过DNS把它固定下来。先说明一点GitHub的IP地址是会变的我这里给出的只是一个思路实际IP必须以你本地的真实解析结果、配合连通性测试来确定。具体操作分三步第一步用公共DNS查询目标域名的多个解析结果比如在命令行执行dig short github.com拿到一批IP后第二步用ping或tcping测试这些IP的延迟和丢包率。第三步选一个延迟最低、丢包为0的IP写进dnsmasq或hosts里。我本地实测过经过筛选后git clone大仓库的速度能提升好几倍效果非常直观。这套方法的本质是“在合法合规的前提下优化网络路径选择”并不是绕过任何访问控制。做网络优化的人应该明白选择最优路径是每个工程师的权利但这套方法只解决“路径选择”问题不改变服务的可访问性边界。3. 服务器与网络设备的DNS配置实操3.1 Linux下修改DNS的“正确姿势”别被重启坑了“Linux修改DNS后重启网络配置又还原了”这个坑我敢说十个运维里至少有八个踩过。原因很简单大多数现代Linux发行版都引入了NetworkManager或systemd-resolved来管理系统网络配置你直接编辑/etc/resolv.conf的改动会被这些系统组件在重启网络服务时重新覆盖。用一句话总结就是你改的是结果系统管的是源头源头一刷新结果就没意义了。在Ubuntu 18.04及以上版本正确做法是通过systemd-resolved来管理。编辑/etc/systemd/resolved.conf[Resolve] DNS223.5.5.5 119.29.29.29 FallbackDNS114.114.114.114保存后执行systemctl restart systemd-resolved即可。如果是用NetworkManager管理的网络连接更推荐用nmcli操作比如给当前活跃连接设置DNSnmcli con mod Wired connection 1 ipv4.dns 223.5.5.5 119.29.29.29 nmcli con up Wired connection 1Ubuntu 22.04里查看当前DNS系统状态可以用resolvectl status它会把每个网卡当前生效的DNS服务器列得清清楚楚排查时很好用。3.2 Windows Server 2019搭建DNS服务器从角色安装到禁止解析在Windows Server 2019上搭建DNS服务器操作上比Linux要直观很多。打开“服务器管理器”点“添加角色和功能”一路下一步到“服务器角色”勾选“DNS服务器”然后按提示完成安装。安装完成后在“工具”菜单里能找到DNS管理器。要解析内部特殊域名需要新建正向查找区域。右键“正向查找区域”选择“新建区域”区域类型选“主要区域”区域名称填你要管理的域名比如internal.corp。建好区域后在里面新建主机记录A记录把内网机器的IP和主机名对应起来。比如我给gitlab.internal.corp建了一条指向192.168.1.100的A记录纯图形化操作鼠标点几下就完成非常顺手。Windows DNS服务器还支持DNS策略可以按域名做允许/拒绝解析这在特殊域名的管理上特别实用。比如我想让内网用户无法解析某个指定域名可以在PowerShell里执行Add-DnsServerQueryResolutionPolicy -Name BlockBadDomain -Action DENY -FQDN eq, badsite.example.com执行之后这台DNS服务器对badsite.example.com的查询会直接被拒绝内网设备通过它解析时拿不到任何有效地址。3.3 路由器上的DNS代理与转发配置企业网环境里很多网络管理员不希望每台终端直接对接公网DNS而是让路由器统一做DNS代理。华三H3C路由器上配置DNS代理的思路是开启DNS proxy并指定上游DNS服务器。进入系统视图大致命令如下dns proxy enable dns server 223.5.5.5配置完成后内网终端的DNS指向路由器接口地址即可路由器收到DNS请求会代为转发给223.5.5.5并缓存结果。这样做的好处是统一管控内网设备的DNS策略全在路由器上收敛也方便后续做域名过滤。锐捷Ruijie路由器的设置更偏向web界面操作登录管理后台后找到“网络”或“DHCP”设置在DNS相关字段里填入希望下发给客户端的DNS服务器地址即可。需要注意路由器下发的DNS会通过DHCP自动分配给所有终端所以填写的DNS必须是稳定、可用的否则整网都会受影响。3.4 麒麟操作系统如何设置备用DNS现在国产操作系统在政企环境用得越来越多麒麟Kylin系统作为代表性的Linux发行版设置DNS的思路和Ubuntu这类Debian系相似。图形界面下在“设置-网络”中找到当前连接点开“IPv4”或“IPv6”设置把DNS服务器和备用DNS服务器分别填写就行多个DNS用英文逗号分隔系统会自动按顺序尝试。命令行下麒麟系统同样支持nmcli和systemd-resolved操作方法和第三节介绍的一致。比如nmcli con mod eth0 ipv4.dns 223.5.5.5 119.29.29.29 nmcli con up eth0单独设置备用DNS时还可以直接修改/etc/resolv.confnameserver 223.5.5.5 nameserver 119.29.29.29不过要注意如果麒麟系统使用了NetworkManager直接改resolv.conf同样有重启被覆盖的可能稳妥起见还是走nmcli或图形界面。4. DNS优选与劫持防护特殊域名场景下的保命技巧4.1 主流通用DNS横向对比到底怎么选聊到DNS优选大家最常问的就是“哪个DNS最好最快”。说实话这个问题没有标准答案因为“最好”取决于你的网络环境和需求。我把主流的公共DNS做个对比方便你按需选择。DNS服务商首选IP备选IP特点阿里DNS223.5.5.5223.6.6.6国内节点多解析快支持DoH/DoT腾讯DNS119.29.29.29119.28.28.28国内加速好抗污染能力不错114DNS114.114.114.114114.115.115.115纯净模式自带部分防钓鱼能力Google DNS8.8.8.88.8.4.4海外域名解析准确国内延迟略高Cloudflare1.1.1.11.0.0.1强调隐私保护海外解析快如果网络环境主要访问国内服务阿里和腾讯是首选延迟低、稳定性好解析国内CDN节点时基本能拿到最优结果。如果经常需要访问海外网站或特殊域名Google DNS和Cloudflare的解析准确率更高但延迟要实测才行。114DNS的纯净模式对拦截部分钓鱼站点有帮助不过对正常域名的解析速度只能说中规中矩。4.2 怎么测出“在你自己网络里最快”的DNS网络服务商之间差异很大比如“西安移动宽带该用哪个DNS快”这种问题根本不需要听别人推荐自己测一遍就有答案。我分享一个最简单的测试方法先用ping测DNS服务器的网络延迟能ping通且延迟越低代表链路越近再用nslookup或dig测同一个域名的解析耗时多测几次取平均值。Windows下可以用如下命令测解析耗时powershell Measure-Command { nslookup www.baidu.com 223.5.5.5 }Linux下更简单dig 223.5.5.5 www.baidu.com | grep Query time两条命令分别执行几次对比不同DNS服务器的Query time和返回的IP地址就能得出哪个DNS在你当前网络下既快又准。需要提醒一句解析快不等于访问快有时候DNS返回了某个CDN节点IP但这个IP到你的实际访问链路不一定是最近的需要结合curl或浏览器实际访问速度来验证。这个方法论换到任何城市、任何运营商都适用。4.3 DNS劫持的识别与防护DNS劫持是特殊域名场景里最让人恼火的问题。典型症状是输入一个正常网站域名回车后跳到了乱七八糟的广告页面或者访问某些网站时页面底部被注入大量小广告。排查思路分三层走。第一层在终端上查执行nslookup 域名看返回的IP是否正常如果IP明显不属于该网站说明解析结果有问题。第二层查本机检查hosts文件有没有被写入非法记录检查本地DNS配置是否被改成了陌生地址。第三层查链路登录路由器管理后台看DNS设置是否被篡改或者干脆在电脑上临时指定一个公共DNS如果问题消失基本可以断定是运营商Local DNS或路由器层面的劫持。防护手段上有条件的企业建议启用加密DNSDoH/DoT让DNS查询内容在传输过程中加密防中间人篡改。个人用户至少要做到两点路由器管理密码设强一点不要使用默认密码如果怀疑运营商DNS有问题把客户端DNS手动指到公共DNS别依赖自动获取。5. 高频坑点排查DNS特殊域名案例实录5.1 530 origin dns error到底是谁的问题“530 origin dns error”这个报错是我在一个接入Cloudflare CDN的客户站点上遇到的。它的含义是CDN边缘节点尝试回源时源站的DNS解析失败了导致CDN拿不到源站IP于是返回530错误。排查思路很明确——问题出在源站DNS环节而不是CDN本身。当时我按三步排查先确认源站域名本身能不能正常解析在本地和公共DNS上分别dig源站域名如果返回NXDOMAIN说明域名解析记录有问题再确认源站服务器上的权威DNS配置比如是否过期、NS记录是否正确最后确认源站IP是否有变更但DNS记录没有同步更新。那次最后定位到的问题是源站域名的一个NS记录指向了一台已下线的旧DNS服务器导致CDN递归查询时永远拿不到权威答案。修正NS记录后530错误就消失了。5.2 Linux修改DNS重启后被还原的完整解法这个问题我在3.1里提过原因这里再补充一套完整的排查命令。当发现/etc/resolv.conf被还原时先用ls -l /etc/resolv.conf查看它是不是软链接。如果是链接到/run/systemd/resolve/stub-resolv.conf说明是systemd-resolved在管理如果是普通文件或者被NetworkManager接管处理方式不同。系统被systemd-resolved管理时按3.1的方法改/etc/systemd/resolved.conf被NetworkManager管理时用nmcli修改当前连接。我遇到过一种特殊情况/etc/resolv.conf被某个第三方工具改成了只读属性导致系统更新时写入失败。这时用chattr i /etc/resolv.conf做了锁定虽然能防止被覆盖但后续手动修改时也要先解锁否则会栽同样的跟头。这种细节不坑一次根本想不到。5.3 用抓包工具看清楚DNS报文里的目标IP排查疑难DNS问题时光看nslookup的输出往往不够因为有些故障发生在报文层面。抓包是最直观的手段。Linux上我用tcpdump抓DNS流量tcpdump -i eth0 -nn port 53执行后能看到本机发出的每一个DNS查询请求和收到的响应包括请求的目标域名、请求的目的IP、响应的源IP和返回的解析结果。如果想完整保存下来给同事分析可以写文件sudo tcpdump -i eth0 -nn -s 0 -w dns.pcap port 53然后用Wireshark打开过滤条件输入dns.qry.name contains example.com就能看到所有包含指定域名的DNS查询报文。这个方法在排查“某个域名是不是被劫持”时特别有用。有一次我怀疑某台机器发出的DNS查询根本不是发给配置的DNS服务器抓包一看请求竟然发到了一个完全陌生的IP——这就是中了恶意软件它自己内置了一个DNS地址。如果不抓包光看系统设置根本发现不了。5.4 遇到可疑DNS请求识别DNS隧道的思路DNS隧道这个名词听起来很高端其实原理不复杂因为DNS报文可以承载比较短的文本数据有人就利用DNS查询和响应来封装非DNS的数据流量把DNS协议当成了一个隐蔽通道。在企业安全场景里它是一种需要警惕的异常流量特征。我对所有网络管理员有一条建议DNS隧道的识别要会利用是绝对不做也不学的。识别DNS隧道有几个典型特征查询的域名非常长比正常域名长得多请求的频率很高且大量使用TXT记录类型因为TXT记录能承载更多文本数据查询的目标域名往往是随机子域名看起来像乱码。我调研时用Wireshark抓包过滤dns.txt一眼就能看到大量携带异常数据的TXT查询这种模式在正常业务里几乎不会出现。如果你在企业网络中发现这类流量基本可以判定存在DNS隧道活动建议排查终端并通知安全团队。防御上可以在DNS服务器上限制TXT记录的查询或者在防火墙上对异常长域名做告警。5.5 禁止解析指定域名从dnsmasq到Windows DNS策略最后聊一下“DNS服务器禁止解析指定域名”的实际操作。这个需求几乎每个企业都有某些域名不想让员工访问与其在防火墙上加ACL不如直接在DNS层把它“变没”。dnsmasq环境下屏蔽一个域名的方法是在配置里加入server/blocked.example.com/#这个配置的含义是凡是以blocked.example.com结尾的域名统一交给一个无效的上游解析#号代表不走任何上游最终结果就是解析失败。另一个更彻底的做法是address/blocked.example.com/0.0.0.0直接把该域名解析到0.0.0.0客户端访问时自然失败。这两种方式的区别在于前者会让查询超时后者会立即返回无效地址实际用下来我更喜欢第二种反馈更快客户端不会傻等。Windows DNS策略的做法在3.2节已经介绍过用Add-DnsServerQueryResolutionPolicy即可适合那些已经在Windows Server上搭建了DNS服务的环境。我个人在实际操作中的体会是DNS的坑永远比你想的多但也正因为如此每次把一个问题从“玄学”变成“可解释、可复现、可解决”那种踏实感是这份工作最让人上瘾的地方。最后再分享一个小技巧不管在什么环境里做DNS调整都先备份原配置改完立刻验证验证不通过就回滚千万别在生产环境里拿着新配置硬试。这套“先备份、小步改、快验证”的习惯帮我躲过了不少半夜三点起来救火的尴尬。
返回列表