尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

IP、DNS、TCP、NAT:一次外网访问故障背后的网络基础全解

IP、DNS、TCP、NAT:一次外网访问故障背后的网络基础全解 家里的NAS装了半个月内网访问一直好好的朋友说“用手机流量打不开”我第一反应是“路由器端口映射没配好”结果折腾了两天最后发现不是映射的问题而是我对“IP、网关、DNS、TCP”这些最基础的网络概念的理解全都停在了“好像知道”的程度——知道IP是门牌号但不知道子网掩码到底是干嘛的知道DNS能把域名翻译成IP但不知道本地DNS缓存和TTL能坑人到什么程度知道TCP有三次握手但从没想过“为什么是三次而不是两次”。这篇文章我就把这次“补课”的过程完整整理出来不按教科书顺序讲而是按“一台新服务器从插上网线到被外网访问到”的链路来讲。每个概念都有对应的实操命令和真实故障场景适合半路出家的开发者、自己折腾NAS或服务器的新手、以及面试前想把网络基础捋清楚的人。1. 设备“入网”的三种身份凭证IP地址、子网掩码与默认网关新机器插上网线、连上Wi-Fi你首先会发现它拿到了一个类似192.168.1.100的地址。很多人觉得“能拿到IP就能上网了”其实这里藏着三个身份凭证IP地址、子网掩码、默认网关缺一个设备就只是“在线”而不是“在网”。1.1 IP地址和子网掩码门牌号之外的“片区判定”IP地址像门牌号但只靠门牌号你没法知道“对方在不在同一个小区”。IPv4地址是32位的写成192.168.1.100这种点分十进制只是为了给人看。真正决定“这个地址属于哪个网络”的是子网掩码。拿最常见的192.168.1.100/24来说/24表示前24位是网络号后8位是主机号。换算成子网掩码就是255.255.255.0。网络号是192.168.1.0主机号是100广播地址是192.168.1.255。为什么一个网段里可用设备数是254而不是256因为网络地址末尾 .0和广播地址末尾 .255都不能分配给设备。这个逻辑搞懂了你看到/24就秒懂这个网段能放多少设备不用死记。Linux下查看这些信息用ip addr和ip routeWindows用ipconfig。我自己的开发机上跑ip addr输出大致长这样2: eth0: BROADCAST,MULTICAST,UP,LOWER_UP mtu 1500 qdisc pfifo_fast state UP inet 192.168.1.100/24 brd 192.168.1.255 scope global eth0这个192.168.1.100/24就同时告诉你IP和子网掩码。brd后面的地址就是广播地址。1.2 默认网关唯一一条“走出去”的路有了IP和掩码设备可以判断目标地址在不在同一网段。如果目标在网段内直接通过ARP找到对方的MAC地址就能通信不需要网关。但如果目标在别的网段设备会把数据包交给默认网关——一条0.0.0.0/0的默认路由意思是“除了直连网段之外的所有目标都从这里走”。我见过一个特别典型的故障有人手动配置IP时把网关写错成192.168.1.254但路由器实际是192.168.1.1结果就是“能ping通同网段设备但上不了网”。这时候执行ip route看一下默认路由指向哪里立刻就能发现问题。网关不生效时很多人的第一反应是换线、换路由器其实只要把网关改对就行。1.3 公网IP、私网IP与 DHCP 的坑家用路由器里的设备基本都是私网IPRFC1918规定了三个私有网段10.0.0.0/8、172.16.0.0/12、192.168.0.0/16。这些地址在公网上不可路由必须经过NAT才能访问外网。设备启动时会通过DHCP自动向路由器申请IP。这里有个坑如果DHCP失败设备会给自己分配一个169.254.x.x的链路本地地址。在Windows上看到IP是169.254开头基本可以断定“没有拿到DHCP分配”这时候检查网线、路由器DHCP服务比重新配置IP地址更合理。我朋友那次打不开网站后来发现路由器重启后DHCP分配了新的内网IP而端口映射里写的还是旧IP这就是典型的“身份凭证变了规则还没跟上”。2. 从域名到IP的翻译旅程DNS解析链路与常见故障配置好IP、网关设备能上网了但我们在浏览器里输入的是www.example.com这种域名不是IP。把域名翻译成IP的体系就是DNS。这一步是“打不开网站”问题里藏得最深的一环因为域名解析失败和服务器故障的表现可能完全一样。2.1 DNS解析的完整顺序当你在浏览器输入一个域名时查找顺序是浏览器缓存 → 操作系统hosts文件 → 本地DNS缓存 → 向配置的DNS服务器发起查询。其中hosts文件是一个容易被忽略的坑。Windows和Linux都有hosts文件如果你曾经为了测试把某个域名写进去之后忘了删那DNS解析就会一直指向那个旧IP而不是真实地址并且任何DNS缓存刷新命令都管不到它。我自己就因为这个原因把“域名解析问题”排查了半个小时最后发现是hosts里躺着一行两年前写的映射。真正向DNS服务器发起查询时链路是这样的你的设备问递归DNS服务器比如你配置的223.5.5.5递归DNS再依次去问根服务器、.com顶级域服务器、该域名的权威服务器最终拿到A记录或AAAA记录返回给你。这个过程用户无感知但理解它有两个意义一是知道为什么“刚改完DNS记录浏览器却还在访问旧服务器”——因为中间每一级都可能缓存旧记录生效时间由TTL生存时间决定二是明白递归DNS服务器本身可能缓存了错误结果换一个公共DNS往往能绕过这个缓存。2.2 实操命令与DNS常见故障Linux下查DNS用digWindows用nslookup。以dig example.com为例你关心的是这段;; ANSWER SECTION: example.com. 3600 IN A 93.184.216.343600就是TTL单位是秒表示这个记录可以被缓存1小时。如果出现status: SERVFAIL通常说明权威服务器出问题或递归服务器配置异常如果返回IP和你预期不符检查是不是本地缓存了旧记录Windows执行ipconfig /flushdns清一下。实践中还有一个很不显眼的坑IPv6的AAAA记录查询超时。域名既有A记录也有AAAA记录时有些操作系统会优先尝试IPv6连接如果当前网络没有IPv6路由就会一直等到超时才fallback回IPv4表现为“网页转圈很久才打开甚至报错”。这时候用dig AAAA example.com看一眼是否有AAAA记录以及本地有没有拿到IPv6地址就能定位。公共DNS的选择方面国内可用的223.5.5.5阿里、114.114.114.114114DNS、8.8.8.8Google各有特点。我的建议是首选前两个解析延迟低。换DNS之后dig的结果如果不再异常就说明问题出在之前配置的DNS服务器或它的缓存上。3. TCP/IP分层不是用来背的数据包在真实访问中的完整旅程拿到服务器的IP之后浏览器要发起HTTP请求数据通过TCP/IP协议栈一层层封装最终变成电信号或无线信号传到服务器。很多人背过OSI七层模型但我建议先重点理解四层模型应用层、传输层、网络层、链路层。这不是为了应付考试而是为了“分层排查”——哪一层出问题现象完全不同。3.1 四层模型的职责划分层级核心职责常见协议活生生的例子应用层定义数据格式与语义HTTP/HTTPS、DNS、FTP浏览器拼一个GET请求传输层端到端可靠传输、端口区分TCP/UDP给请求加上端口号、保证顺序网络层寻址、路由选择IP、ICMP决定数据包从哪条路走链路层物理传输、局域网寻址以太网、Wi-Fi在网线上发送二进制数据用快递打比方应用层是你写的收件内容传输层是快递单号和服务等级普通件/加急件网络层是分拣中心根据城市名决定路线链路层是快递员骑着车把你家门口的路跑完。如果你用curl -v访问一个HTTPS网站看到的输出其实就对应层层协议在对话先是DNS解析然后是TCP连接接着是TLS握手最后才是HTTP请求和响应。每一层都像链条的一个环节断在哪一环后面的环节就不可能正常。3.2 三次握手为什么是三次以及端口与连接状态TCP三次握手是SYN、SYN-ACK、ACK三步。为什么不是两次核心原因是防止“历史迷路的连接请求”把连接建立起来。假设客户端发出了一个SYN因为网络拥塞超时客户端以为丢了重发SYN。然后第一个迟到的SYN又到了服务端如果只靠两次握手服务端收到这个迟到的SYN就会返回SYN-ACK并建立连接但客户端其实已经发起新连接了两边状态就不一致。三次握手让客户端在收到服务端的SYN-ACK时能判断“这个确认对应的是我哪一次SYN”如果是旧的就发RST把连接拆掉。所以第二次握手不仅是确认更是给客户端一个“确认你是哪次连接”的机会。握手完成后TCP连接才真正开始传数据。这里有一个非常实用的查看命令ss -tlnpLinux或netstat -anWindows/Linux可以看到本机监听的端口。端口的概念很简单IP是楼地址端口是房间号。HTTP默认80HTTPS默认443SSH默认22DNS是53。你用ss -tlnp | grep 443看到有监听说明服务进程在跑看到TIME_WAIT状态堆积通常是短连接频繁关闭导致的和对端服务是否正常没有直接关系。抓包看握手是最直观的。一条命令就可以sudo tcpdump -i any tcp port 443 -c 20然后用另一个终端执行curl https://example.com你会在抓包里看到清晰的SYN、SYN-ACK、ACK序列以及后续TLS的ClientHello、ServerHello。我建议每个想弄懂TCP的人都实际抓一次包因为“看过”和“见过”完全是两种理解深度。到了HTTPS这一步传输层之上还有TLS握手客户端发ClientHello服务端回ServerHello和证书双方协商出会话密钥之后所有HTTP内容都加密传输。这也是为什么HTTPS默认走443端口因为TLS会话是在TCP连接建立之后、HTTP请求发送之前完成的。4. 数据包如何“走出家门”路由、端口映射与NAT前面的链路已经把数据包封装好、准备发出去了但一个关键问题还没解决从你家里发出的数据包怎么知道经路由器的哪个口出去、到达公网之后又怎么回来这就涉及路由和NAT。4.1 路由表与最长前缀匹配每个设备、路由器都有一张路由表决定“目标IP的数据包往哪个接口发”。家用路由器的核心路由规则通常是default via 192.168.1.1 dev eth0这一行default就是默认路由对应0.0.0.0/0。收到目的IP为8.8.8.8的数据包时路由表里没有更具体的匹配项就会匹配这条默认路由发给网关。多路由条目场景下的选择原则是“最长前缀匹配”——谁的掩码更长、匹配的位数更多就选谁。比如路由器可以做策略路由让某个网段走特定出口。理解了最长前缀匹配你就不会惊讶“为什么同时有两条路由时某些流量走A、某些流量走B”。用tracerouteLinux或tracertWindows可以直观看到数据包逐跳经过的路径。原理是利用IP头里的TTL字段每经过一个路由器TTL减1减到0时路由器丢弃包并返回ICMP超时。测试时从TTL1开始递增就会逐个记录每一跳的地址。我拿它排查过“访问某服务器特别慢”的问题发现慢的不是服务器而是中间某个运营商节点丢包严重。4.2 NAT、端口映射与安全组家用路由器拿到的公网IP通常只有一个但家里可能有手机、电脑、NAS好几台设备同时上网。路由器靠NAT网络地址转换解决这个矛盾更准确的说是NAPT它不仅改IP还改端口。举个例子你电脑192.168.1.50:52340访问公网服务器1.2.3.4:443数据包经过家用路由器时源IP被改写为路由器的公网IP202.x.x.x源端口也被改成一个随机端口54321。路由器在内存里记一条映射192.168.1.50:52340 ↔ 202.x.x.x:54321。服务器回包时目的地址是202.x.x.x:54321路由器查映射表把目的改写回192.168.1.50:52340数据包才能回到你电脑。理解了NAT这张映射表再回头看“外网访问内网服务器”就顺了外网用户访问你家的公网IP的某个端口路由器根本不知道这个端口对应哪台内网设备。所以需要在路由器上配置端口映射也叫端口转发/DNAT比如把公网IP的8080端口转发到内网192.168.1.100的80端口。这样外网访问http://公网IP:8080时路由器改写目的IP和端口把请求交给你家里的Nginx。云服务器场景下的“安全组”和家用路由器不太一样。安全组是云平台在虚拟网络层做的一层过滤规则你买了一台ECS公网端口默认全闭必须在安全组规则里放行443或8080否则就算服务器内启动服务也访问不到。家用场景则要检查路由器端口映射和设备防火墙。我见过有人在云服务器上配好了Nginx端口也监听了就是忘了加安全组规则结果外网“连接被拒绝”这个顺序初学者特别容易踩。NAT这里还有一个更深层的坑它只对TCP/UDP这类有端口的协议友好。如果你以后做P2P联机或自建游戏服务器会碰到“为什么服务器明明开着对方就是连不上”的问题那是因为NAT阻碍了直接入站连接必须借助STUN/TURN这类NAT穿透方案。做项目时提前知道这个限制会少走很多弯路。5. 一次真实的断网排查用分层思维逐层定位根因概念讲了一堆最终都要落实到排障。这里复盘一次我帮朋友排查“网站突然打不开”的完整过程你会看到上面所有概念是怎么被串起来的。5.1 排查命令链每一层失败代表什么故障现象是外网用户访问https://xxx.example.com报超时朋友在内网用同一域名访问正常。我的排查顺序是本机协议栈是否正常ping 127.0.0.1。如果这一步都不通说明本机TCP/IP协议栈有问题但这概率极低。本机到网关是否通ping 192.168.1.1。失败说明链路层或DHCP有问题比如网线没插好、Wi-Fi信号差、网卡被禁用。本机到公网是否通ping 223.5.5.5。失败说明默认网关或路由/NAT有问题也可能是运营商线路断了。域名解析是否正确dig xxx.example.com。看到返回的公网IP和预期一致说明DNS正常如果不一致查hosts、查本地DNS缓存、查TTL。端口是否可达nc -vz xxx.example.com 443或telnet xxx.example.com 443。这一步测试的是TCP连接能不能建立也就是路由NAT端口映射安全组服务进程是否都通畅。如果是Connection timed out多半是路由路径上丢包或防火墙丢弃如果是Connection refused说明目标主机上服务没监听或防火墙主动拒绝。排查命令验证目标典型失败含义ping 127.0.0.1本机协议栈网卡/协议栈异常ping 192.168.1.1到网关的链路网线/Wi-Fi/DHCP问题ping 223.5.5.5出公网路由与NAT默认网关/运营商线路问题dig或nslookupDNS解析hosts、DNS缓存、TTL问题nc -vz 域名 443端到端连通性NAT/端口映射/安全组/服务进程5.2 这次断网的根因动态IP与端口映射的“失配”按上面的链路排查最后发现ping外网IP通了dig解析出的IP也正确但nc测试443端口超时。问题出在端口映射这一层。原来朋友家路由器重启过一次重启后动态公网IP变了而他在路由器上配的“端口转发”规则写的是旧的公网IP地址映射有些路由器在拨号IP变化后会保留DDNS更新但端口转发规则可能依赖旧的接口绑定再加上DDNS的缓存还没更新到最新公网IP外网用户访问的其实还是旧IP。修复方法也很直接重新检查路由器WAN口获取的当前公网IP确认DDNS记录用的是域名→最新公网IP然后把端口转发规则里的“内网目标IP”改成DHCP为服务器分配的当前内网地址。这个案例最值得反思的点是问题根源其实非常基础——IP会变、DHCP分配会变、DNS记录有TTL、NAT规则必须和IP匹配。任何一个环节失配表现都是“网站打不开”但用分层排查法20分钟内就能定位到具体是哪一层。整套走完我自己最大的体会是网络基础概念一定不要孤立地背它是一条“数据走哪个门、怎么找路、怎么翻译、怎么映射”的完整链路。建议你手头找一台闲置的电脑或树莓派配一个Nginx然后故意做几个破坏动作——改错网关、改错DNS、关掉安全组端口、停掉Nginx——再按上面这套命令逐层排查。折腾完这四五个故障你对网络的理解会比看十遍教程都深刻。
返回列表