ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

IP、域名与DNS:从解析原理到配置与排查实战

2026/10/5 15:38:45 拓冰建站 浏览量
IP、域名与DNS:从解析原理到配置与排查实战 1. 三者到底是什么关系先用人话讲清楚IP、域名、DNS这三个词只要搞过网络就绕不开。我做了十来年运维被问得最多的问题往往不是那些复杂的路由协议而是这三个基础概念IP到底是不是“网址”DNS是不是“域名服务器”域名和IP哪个更重要其实把它们的定位想清楚了后面看抓包、配路由、排查网站打不开都会轻松很多。先打个比方。IP是每台设备在网络里的“门牌号”比如192.168.1.10就是你当前设备在小区里的具体位置。域名是给人记的“名字”比如example.com你不必记住那串数字只需要记住名字。DNS则是那本“小区通讯录”当你喊出example.com通讯录会帮你查出它对应的门牌号也就是93.184.216.34。网络通信最终靠的还是IP地址域名只是入口DNS是入口背后的翻译机制。这里要注意一点题目里说“域名解析DNS”容易让人理解成“DNS等于域名”。其实DNS全称是Domain Name System是一套分布式数据库不是某一台单独的主机。所谓“域名解析”就是通过这套系统把域名翻译成IP地址。你输入的域名会先经过解析拿到目标IP再去走TCP/IP协议里的连接流程。理解这个关系对谁最有用呢我觉得三类人最需要一是刚接触网络的新手容易被一堆概念绕晕二是前后端开发部署环境和调试回调域名时经常要跟DNS打交道三是运维排查“域名解析失败”“IP冲突”这类问题靠的就是理清三者的边界。下面的内容我会按实际排查思路来写尽量不堆术语。2. 一次完整访问的历程DNS 解析细节拆解2.1 第一步不是找 DNS 服务器而是查本地缓存我在培训新人的时候喜欢问一个问题你在浏览器里输入一个域名第一件事是不是去问互联网上的DNS服务器答案是否定的。浏览器会先查自己的DNS缓存然后查操作系统的DNS缓存再然后查hosts文件。只有这三层都没有结果才会上网查询。hosts文件是一份“本地手写通讯录”位置在Windows的C:\Windows\System32\drivers\etc\hostsLinux和macOS下是/etc/hosts。里面可以写域名和IP的对应关系比如127.0.0.1 localhost 192.168.56.10 dev.example.com很多开发者在本地调试时根本不需要注册域名或改公网DNS只要把虚拟机的IP和自定义域名写进hosts浏览器就把这个域名当成真实域名来访问。这也是为什么后面我会单独讲“本地加虚拟机多站点配置”因为hosts就是最轻量级的本地DNS。要注意浏览器缓存和系统缓存是可以清掉的。浏览器可以用隐身模式或者开发者工具里的“清空缓存并进行硬性重新加载”系统层在Windows下用ipconfig /flushdnsLinux下用sudo resolvectl flush-caches。但hosts文件是写死的优先级极高清缓存也清不掉排查时第一件事就是看它。2.2 本地没有缓存递归 DNS 开始分布式查询如果本地三层缓存都没有命中系统会把域名解析请求交给网络配置里指定的DNS解析器。这个解析器可能是路由器下发的可能是公共DNS也可能是公司内网DNS。它并不是全知全能的而是替你跑腿。以www.example.com为例解析器大致会这样工作先问根DNS服务器“.com这个顶级域归谁管”根服务器告诉它去问.com顶级域服务器它再问.com顶级域服务器“example.com归谁管”对方返回example.com的权威DNS服务器地址最后它去问example.com的权威DNS服务器拿到www这条主机记录对应的IP地址。这个过程里本地解析器一直在递归地替你查询而每层DNS服务器只是迭代地回答一句话。查询结果会在沿途各级缓存一段时间也就是TTL。TTL到期前你再去访问同一个域名可能直接从本地DNS缓存中拿到结果速度会快很多。这里想强调一个容易混淆的点DNS并不是一条“域名-IP”的简单关系表而是一个分级授权的分布式系统。根、顶级域、权威域各管一段。理解了这一点你就能明白为什么有些域名解析很慢为什么改了DNS记录不能立刻全球生效。2.3 常见解析记录查IP、做别名、收邮件很多人以为DNS里只有A记录其实不只。实际用到比较多的有下面这几种记录类型作用常见场景A把域名解析到IPv4地址网站、服务器的IPv4指向AAAA把域名解析到IPv6地址支持IPv6的站点CNAME把别名指向另一个域名让www指向主域名MX指定邮件服务器让别人知道你的邮件交给谁收NS指定某域名的权威DNS服务器域名的DNS托管设置PTR从IP反查域名反垃圾邮件、IP归属校验后面要讲的“域名查询IP”本质上就是查A记录或AAAA记录。比如在命令行执行dig example.com A short出来的就是服务器IPv4地址。如果你看到一条记录是CNAME说明它的最终解析还要继续追下去直到追到一个A或AAAA记录为止。3. 配置与实操从修改 DNS 到解析结果验证3.1 Ubuntu 22.04 修改 DNS 的正确姿势为什么不能直接改 resolv.conf网上很多教程会让你直接改/etc/resolv.conf但Ubuntu 22.04上这绝对是个坑。这个文件通常是个软链接指向/run/systemd/resolve/stub-resolv.conf由systemd-resolved动态生成。你手动改完重启网络或者重启系统内容又会被覆盖回去。我早期踩过一次后来再也不用这种临时改法了。如果是临时改一下当前生效的DNS可以用resolvectl命令。假设接口名是eth0想把DNS改成223.5.5.5sudo resolvectl dns eth0 223.5.5.5 sudo resolvectl status这种方式适合临时测试重启后会失效。如果要持久化就应该改netplan配置。Ubuntu 22.04的netplan文件一般在/etc/netplan/目录下文件名可能是00-installer-config.yaml或01-network-manager-all.yaml内容大致如下network: version: 2 ethernets: eth0: dhcp4: true dhcp4-overrides: use-dns: false nameservers: addresses: [223.5.5.5, 119.29.29.29]写完保存后执行sudo netplan apply。如果你希望同时从DHCP拿IP但不拿DNS那段dhcp4-overrides很关键否则DHCP下发的DNS可能会把你手工填的nameservers顶掉。如果是桌面版Ubuntu通常由NetworkManager接管网络你可以在图形界面里改也可以直接用nmclinmcli con mod Wired connection 1 ipv4.dns 223.5.5.5,119.29.29.29 nmcli con up Wired connection 1改完以后不要急着看结果先确认一下当前生效配置cat /etc/resolv.conf看看解析器是不是systemd-resolved再用resolvectl status看看接口实际用的DNS。很多情况下你觉得改了没用其实是改的地方不对。3.2 Linux 改完 DNS 重启就被还原问题不在命令我见过最多的问题就是用命令改完DNS当时是能用的但重启系统或者重启网络服务后DNS又变回原来的值甚至变成空。问题几乎都出在持久化上面。临时命令只作用于当前运行状态没有写进任何配置文件DHCP重新下发网络参数后原来的配置自然被覆盖。如果你在用systemd-resolved还可以遇到一个更隐蔽的问题明明netplan里写了新的DNS但解析结果还是旧的。这种情况我一般先做两件事sudo resolvectl flush-caches cat /etc/resolv.conf刷新缓存很重要systemd-resolved会把之前的解析结果缓存一段时间即使上游DNS已经切换了缓存里还是旧内容看起来就像没改成功。还有个细节不要在一个网卡上同时设置多个来源的DNS否则顺序会影响最终解析。比如你可能在netplan里写了一个NetworkManager又接管的同一个网卡最终生效的是谁取决于哪个服务在管理这个接口。排查时用resolvectl status看清楚接口的DNS来源比自己瞎猜高效得多。3.3 telnet IP 端口怎么看通不通三条命令足够“telnet ip 端口 命令怎么看通不通”这个问题几乎是每个运维新人都要问的。最传统的判断方法就是telnet 192.168.1.10 80如果能出现Connected to 192.168.1.10或者切换到一个空的黑窗口说明IP能到端口上也有服务在监听。如果很快提示Connection refused说明网络通但这个端口没人监听。如果一直卡着不动直到超时那多半是中间有防火墙把包丢了。不过现在的Ubuntu默认不带telnet客户端而且telnet本身也没有超时参数卡住时很烦。我更推荐用ncnc -zv -w 3 192.168.1.10 80-z表示只测试端口不发送数据-v显示详细信息-w 3是超时3秒。还有一种不需要安装任何工具的办法用bash自带的/dev/tcptimeout 3 bash -c echo /dev/tcp/192.168.1.10/80 echo port open || echo port closed这段命令的意思是向目标IP的80端口建立一个TCP连接如果成功就输出open失败就输出closed。它依赖bash特性换成sh执行可能不支持。这里的关键是分清refused和timeout前者是服务器明确拒绝后者是包被丢了两者对应的排查方向完全不同。3.4 域名查询 IP 和反向查询日常查域名对应的IP我一般优先用dig而不是ping。ping走的是ICMP协议有些服务器禁Ping域名解析出来也可能不给你回应而dig直接问DNS服务器和网站本身通不通无关更适合定位问题。dig short example.com dig www.example.com A short如果想绕过本地DNS直接指定用某个公共DNS查询dig 223.5.5.5 www.example.com A shortWindows上没有dig怎么办用nslookup习惯用哪个都行nslookup -typeA www.example.com反向查询则是从IP查域名靠的是PTR记录dig -x 93.184.216.34这里要提醒一句IP归属地查询和DNS反查是两回事。反查只能得到这条IP有没有配置对应的PTR记录而“这个IP属于哪个城市、哪个运营商”是另一套IP地理库在做的事不要把两者混在一起。4. 局域网实战IP 冲突、静态 IP 和本地域名4.1 IP 冲突排查局域网里出现“IP地址冲突”的时候最典型的症状是设备一会儿能上网一会儿不能哪怕你什么都没动。原因很简单网络里有两个设备用了同一个IP路由器或者交换机的ARP表会来回漂移一会把包送给A一会送给B。排查时我会用最直接的命令。Windows下先看ARP表arp -aLinux下用ip neigh如果看到同一个IP对应多个MAC地址而且这些MAC还在交替更新基本可以确定冲突。接着进路由器后台看在线设备列表找出这个IP对应的实际设备再手动把其中一台改成别的IP。长期解决方案是在DHCP服务器里做静态绑定让每个MAC地址固定拿到唯一的IP。这里要注意虚拟机、手机、各种智能硬件都容易造成冲突特别是从虚拟机镜像克隆出来的机器网卡MAC没变但系统之前已经缓存了旧IP重启后很可能抢IP。遇到陌生的MAC地址先不要急着封禁先查清楚是哪个设备再用。4.2 修改虚拟机 IP 地址修改虚拟机IP是开发环境里经常要做的操作也是容易翻车的一步。Linux虚拟机改IP我建议用netplan而不是直接ifconfig eth0 192.168.x.x。先ip a看清楚网卡名然后编辑netplan配置文件把dhcp4改成false并设置静态地址network: version: 2 ethernets: ens33: dhcp4: false addresses: - 192.168.56.10/24 gateway4: 192.168.56.1 nameservers: addresses: [223.5.5.5]执行sudo netplan apply后再用ip addr show ens33确认地址是否生效。Windows虚拟机就简单多了在“网络和共享中心”里的IPv4属性里直接改记得填子网掩码和默认网关。改完如果上不了网先ping网关再ping外部IP能快速判断是IP问题还是路由问题。还有一个容易忽视的点虚拟机的网络模式不同IP规则也不同。NAT模式下虚拟机和宿主机通常不在同一网段靠虚拟网卡转发Host-only模式下它和宿主机应该是同一网段但出不了外网。你要把自定义域名解析到虚拟机IP时就得保证宿主机能直接访问那个IP否则hosts写了也访问不了。4.3 本地虚拟机多端口 Nginx 多站点自定义域名开发环境里做多站点不一定非要买域名。比如虚拟机IP是192.168.56.10我想在浏览器里用dev.test和admin.test访问两个站点可以在宿主机hosts里写192.168.56.10 dev.test 192.168.56.10 admin.test然后在虚拟机的Nginx里配置虚拟主机server { listen 80; server_name dev.test; root /var/www/dev; } server { listen 80; server_name admin.test; root /var/www/admin; } server { listen 8080; server_name dev.test; root /var/www/dev-mobile; }这样http://dev.test会命中第一个站点http://admin.test命中第二个站点http://dev.test:8080命中第三个站点。要注意hosts文件里的域名最好带一个不存在的顶级域或后缀比如.test、.local避免和真实域名撞车。有人会问那网页授权回调域名呢像OAuth授权登录这种场景第三方平台会从公网DNS去解析你的回调域名它不会读你本地hosts。所以你在本地用dev.test调试没问题但真实回调场景必须在域名服务商那边把回调域名指向服务器公网IP同时做好Nginx反向代理否则平台请求到你服务器上的时候还是会失败。5. DNS 的坑和安全要不要自己搭 DNS 服务器5.1 为什么解析结果会不对缓存、TTL 和解析链路当你改了域名解析记录却发现过了一个小时还是访问到旧IP不用急着怀疑自己操作有问题。每条DNS记录都有一个TTL值比如300秒或3600秒TTL没到期前本地DNS服务器和客户端缓存都会把旧结果留着。你本地清缓存只是第一步中间的公共DNS或运营商DNS可能还缓存着旧记录只能等它自然过期。这种情况下我一般直接指定一个公共DNS来查“真实答案”dig 223.5.5.5 example.com A short如果指定DNS查到的是新IP而普通解析查到的是旧IP说明本地或中间链路有缓存。如果两种方式都查到旧IP才需要考虑域名服务商那边的解析记录是否真的改了或者记录是不是写错了。这里也延伸出一个安全问题DNS传统上使用UDP 53端口明文传输中间链路理论上可以篡改响应。现在新的做法是DoT和DoH把DNS请求加密起来但兼容性也需要自己验证。尤其是公司内网环境自建DNS往往要做一些内部域名解析这些安全性问题就要提前想清楚。5.2 内网自建 DNS为什么我建议先用 dnsmasq如果只是为了内网解析、局域网内自定义域名、缓存加速我建议先用dnsmasq而不是一上来就搭Bind9。dnsmasq配置简单、资源占用低非常适合几十台机器的小环境。一个典型配置大概是这样的port53 listen-address127.0.0.1,192.168.1.1 cache-size1000 server223.5.5.5 address/dev.local/192.168.1.20address/dev.local/192.168.1.20表示把所有以dev.local结尾的域名都解析到192.168.1.20。这样内网机器只要把DNS指到这台服务器就能直接使用自定义域名。前面说到的“本地虚拟机多站点”场景如果机器数量多靠改hosts太累就可以用dnsmasq统一管理。自建DNS有一点要特别留神服务器上如果已经跑了systemd-resolved它会默认占用53端口。你需要先把systemd-resolved的stub监听停掉或者改端口否则dnsmasq启动时会提示端口被占用。另外如果这台DNS服务器要对外提供递归查询建议做访问控制和限速否则容易成为被利用的“公共递归”。普通家庭或小团队我更推荐直接用公共DNS省心很多。5.3 DNS 问题排查速查表现象大概率原因处理方向nslookup显示无法解析本地DNS配置不对或上游DNS不可达换公共DNS检查网络链路Linux重启后DNS还原修改未持久化用netplan或nmcli做持久配置解析结果一直是旧IP缓存TTL未过期清缓存、等待TTL、指定公共DNS查询telnet端口报Connection refused目标端口没有服务监听检查服务进程、端口绑定、监听地址telnet端口一直超时防火墙丢包或路由不通依次ping网关、目标IP清理防火墙规则本地自定义域名访问不了虚拟机站点虚拟机IP变了或者hosts写错重新确认IP检查Nginx server_name这几类问题看起来五花八门但本质上都在IP、域名、DNS三角关系里打转域名靠DNS解析成IPIP靠路由到达目标到达以后还要看端口和服务是否正常。能分清是哪一层的锅排查速度会快很多。最后分享一个我一直保留的习惯遇到“网站打不开”不要先猜先用dig short确认域名解析结果再ping IP确认网络通不通最后telnet IP 端口确认服务在不在。三步下来基本能把DNS、网络、服务三层问题分开。我自己在Ubuntu上踩得最深的坑就是/etc/resolv.conf被系统覆盖所以现在不管临时测试还是长期使用都下意识选择resolvectl或netplan。希望这篇能帮你把三者的关系理顺下次再遇到解析问题心里能有一条明确的排查路线。