news 2026/11/5 5:03:16

Linux网络排查实战:IP地址、子网掩码、路由与端口的底层逻辑

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux网络排查实战:IP地址、子网掩码、路由与端口的底层逻辑

1. 从 ifconfig 说起:再聊概念前先把地址看清

刚接触 Linux 网络的时候,我最常被问到的一个问题是:"我执行ifconfig看到的这些乱七八糟的信息,到底哪个是 IP 地址?"

这个问题看似基础,但实际上暴露了一个很普遍的现状——很多新手把 Linux 网络当成了背概念题,背了 OSI 七层模型,背了 TCP 三次握手,但真正坐到一台服务器前面,面对一堆网卡信息,脑子里其实是空的。我自己当年也是这样,所以这篇我不打算按教材的顺序讲,而是从"你敲命令之后屏幕上会出现什么"出发,把网络基础概念一个个串起来。

先看一个典型的ifconfig输出:

eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.1.100 netmask 255.255.255.0 broadcast 192.168.1.255 ether 08:00:27:4e:2a:1b txqueuelen 1000 (Ethernet) RX packets 12842 bytes 13983720 (13.3 MiB) TX packets 9621 bytes 1012334 (1012.3 KiB)

这里最关键的三样东西是inet(IPv4 地址)、netmask(子网掩码)和后面的ether(MAC 地址)。ether是网卡的物理地址,出厂时烧录在硬件里,通常不会变,它解决的是"在同一个局域网里,数据帧到底要交给哪块网卡"的问题。inet是可变的逻辑地址,它解决的是"这台机器在整个网络里叫什么名字"的问题。

很多人会混淆 MAC 地址 和 IP 地址的区别,这里打个比方:MAC 地址像一个人的身份证号,一辈子基本不变,用于确认"你是谁";IP 地址像你当前的住址,搬家就换,用于确认"你现在在哪"。

同一时刻你可能有多个网卡——比如企业服务器上常见的双网卡配置,eth0连内网,eth1连外网,甚至还有docker0、tailscale0这样的虚拟网卡。ifconfig会把这些全部列出来,每块网卡都有自己的 IP、掩码和 MAC。弄清楚你到底在看哪块网卡,是排查网络问题的第一步。

这里还要提醒一点:现在很多新装的 Linux 发行版默认没有ifconfig,因为它已经被 iproute2 的ip命令取代。你完全可以把ifconfig换成ip addr show,效果类似。

$ ip addr show eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 08:00:27:4e:2a:1b brd ff:ff:ff:ff:ff:ff inet 192.168.1.100/24 brd 192.168.1.255 scope global dynamic eth0

注意看192.168.1.100/24这个写法,它把 IP 地址和子网信息合并成了一种简写——这就是我们下一节要讲的核心内容。

2. IP 地址不是一串数字:子网掩码与 CIDR 才是真正的地图

2.1 为什么不能只看 IP 本身

两年前我帮一个同事排查问题,他跟我抱怨:"我两台服务器都配了 192.168.1.10 和 192.168.1.11,同一个交换机下面,为什么 ping 不通?"

我让他把两台的掩码都发我,结果一台是255.255.255.0,另一台是255.255.255.128。问题就出在这。第二台服务器的网段其实是192.168.1.0/25,它的广播地址是192.168.1.127,而192.168.1.11这个 IP 落在192.168.1.128/25这个半段里,两台机器虽然在同一个交换机上,却认为自己在不同的网络里,自然谁也不理谁。

这个例子说明:只看 IP,不看子网掩码,你根本无法判断两台机器是否"直接可达"。

2.2 子网掩码的本质是"分组规则"

子网掩码(Netmask)用二进制表示时,前面是连续的 1,后面是连续的 0。255.255.255.0换算成二进制就是:

11111111 11111111 11111111 00000000

当我们需要判断两个 IP 是否在同一个子网时,把 IP 和掩码做"与"运算,得到的结果就是网络号(Network ID)。如果两个 IP 的网络号一致,说明它们在一个二层域里,数据包可以直接通过交换机转发,不需要走网关。

常见的三档掩码:

子网掩码CIDR 写法可用的主机 IP 数量适用场景
255.255.255.0/24254 台家庭局域网、小型办公网
255.255.0.0/1665534 台BGP 数据中心内部、中大型私网
255.255.255.128/25126 台把一个 C 段切两半

CIDR(无类别域间路由)就是把"IP + 斜杠 + 前缀长度"写成192.168.1.0/24的形式。/24表示网络部分占 24 个二进制位,主机部分还剩 8 位,也就是 2 的 8 次方减 2(去掉网络号和广播地址),共 254 个可用地址。

这条计算规则我建议每个人都手推一遍,不要依赖在线工具。比如10.10.20.0/22,22 位网络位意味着主机位有 10 位,可用地址就是 1022 个;网络号怎么算?20的二进制是00010100,把它和11111100做与运算,得到00010100,说明还是 20,整个网段范围是10.10.20.0到10.10.23.255。

2.3 为什么要专门讲广播地址

/24网段的广播地址是192.168.1.255。广播地址是发给该网段内所有主机的特殊地址,常见的使用场景包括 DHCP 的地址发现、ARP 请求、NetBIOS 名称解析。如果你的防火墙日志里密集出现发往xxx.xxx.xxx.255的数据包,这通常不是攻击,而是某些老旧设备的广播协议在运作。

在配置网络时,你需要确保 Linux 系统计算出的广播地址与实际网络一致。手动配置静态 IP 时如果写错了 broadcast,会出现"能 ping 通自己,但局域网里别人找不到你"的怪现象。用ip addr配置时一般不需要手动指定 broadcast,系统会自动根据掩码算出来,但如果你是改配置文件,还是要关注一下。

3. 端口是服务的门牌号:TCP 与 UDP 的取舍逻辑

3.1 一台服务器上为什么可以同时跑几十个服务

如果 IP 只是"房子的地址",那端口就是"房间的门牌号"。一台只有 IP 的服务器,如果只能提供一个服务,那也太浪费了。所以 TCP/UDP 协议在 IP 之上加了一层端口号(0~65535),用于区分这台机器上的不同服务进程。

拿我手上的一台云服务器举例,同一时间它上面跑着 Nginx(80/443)、SSH(22)、数据库(3306)和监控 agent(9100),每个进程监听不同的端口。客户端想连数据库,就往服务器的 IP 加 3306 这个端口地址发起连接,Nginx 的进程不会抢到这个流量,因为内核在分发数据包时,会根据目标端口找到对应的套接字。

查看端口监听状态,常用的命令是:

$ ss -tlnp State Local Address:Port Process LISTEN 0.0.0.0:22 sshd LISTEN 0.0.0.0:80 nginx: master LISTEN 127.0.0.1:3306 mysqld

注意127.0.0.1:3306和0.0.0.0:3306是两回事。前者表示只有本机能访问数据库,后者表示所有网卡上的流量都能进来。我见过太多人把数据库端口暴露在0.0.0.0上,然后被全网扫端口的人爆破,这就是监听地址没搞明白的代价。

3.2 TCP 的可靠是"确认"出来的

TCP 是面向连接的协议,它的可靠不是靠网络保证的,而是靠确认机制。核心逻辑可以总结为:发送方发一个包,接收方回一个确认(ACK),发出去没收到 ACK 就重传。

在连接建立阶段,它要经过经典的"三次握手":

  1. 客户端发 SYN(同步报文),告诉服务端:我要连接你了。
  2. 服务端回 SYN+ACK,表示:收到你的请求,我也准备好了。
  3. 客户端回 ACK,表示:确认。

为什么必须是三次而不是两次?因为 TCP 要避免"失效的连接请求突然又到达服务器"这种情况。假如只有两次握手,服务端收到 SYN 就会建立连接,分配资源;此时如果这个 SYN 是一个网络重发的旧包,服务端就会白白浪费资源。三次握手让服务端确认"客户端确实收到了我的应答",再进入连接状态,更稳妥。

3.3 UDP 的"快"靠的是放弃包袱

UDP 没有握手、没有保序、没有重传,它就是一个"尽力而为"的协议。数据包发出去,对方收不收得到,UDP 不管,也不重传。

做 音视频流媒体 传输的同学应该深有体会:直播场景下偶尔丢几帧画面,远比"为了补一帧旧画面而让整个视频卡顿等待"体验好。语音通话里如果丢包重传,你听到的可能是乱序的、重复的声音,更难受。

所以选型的基本原则是:需要可靠、有序、面向事物的传输(比如发邮件、看网页、传文件)用 TCP;对实时性要求高、可以容忍少量丢失的(直播、语音、游戏同步)用 UDP,或者在 UDP 之上自己实现可靠传输。

3.4 与端口相关的几个坑

配置防火墙时, -A INPUT 规则写的如果是--dport 80,那这个规则只对 TCP 生效还是对 TCP/UDP 都生效?答案是取决于你前面有没有写-p tcp。如果没写协议,--dport会同时匹配 TCP 和 UDP。很多新人在配 ufw 或 firewalld 时没注意协议字段,放行了 TCP 的 53 端口,DNS 查询用的是 UDP,结果域名还是解析不了,就是这个细节。

另外检查连通性时,ping用的是 ICMP 协议,不涉及端口。所以"ping 得通"只能说明主机在线、网络路径通,不能说明你的 Web 服务正常。想测端口是否开放,可以用nc -vz <ip> <port>或telnet <ip> <port>。

4. 路由表与网关:数据包跨设备出门的完整路径

4.1 数据包不是乱跑的,每一步都要查表

当你的机器要把数据包发给另一个地址时,内核会先查看本机的路由表,决定这个包走哪块网卡、要不要交给网关。这是 Linux 网络里最容易被忽略,但又是最核心的概念之一。

查看路由表:

$ ip route show default via 192.168.1.1 dev eth0 proto static 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.100

第一条default是默认路由,等价于老的route -n输出中的0.0.0.0那一行,意思是:没有更具体的路由匹配时,一律发给网关192.168.1.1。第二条是直连路由,说明凡是目的地址在192.168.1.0/24这个网段的,直接通过eth0的链路层寻址就能送到,不需要再往上走。

这里有一个很多初学者的误区:以为"网关"是一个服务或一个进程。其实网关就是一台路由器(或具备转发能力的主机),它的作用是把数据包从一个网段转发到另一个网段。对局域网里的机器来说,默认网关通常就是家用路由器、核心交换机或防火墙的内网接口。

4.2 静态路由什么时候需要手动加

大多数情况下,机器只有一张网卡、一个默认网关,什么都不用配。但一旦出现多网卡、多网段的场景,就需要手动干预了。

举个例子。某台机器上插了两块网卡:

  • eth0连接办公网192.168.10.0/24,网关是192.168.10.1
  • eth1连接研发网10.2.0.0/16,网关是10.2.0.254

系统默认只有一条路由,如果你的默认路由指向192.168.10.1,那发往10.2.0.0/16的包也会先尝试走办公网关,被网关拒绝后直接丢弃。解决方法是加一条静态路由:

$ ip route add 10.2.0.0/16 via 10.2.0.254 dev eth1

这样内核在查路由表时,会先匹配更精确的10.2.0.0/16,而不是走 default。路由匹配的原则是最长前缀匹配——谁的掩码越长、范围越具体,就优先用谁。

4.3 双网卡的隐藏问题:回程路由不对称

这是一个进阶但非常经典的问题。假设你的服务器有两个网卡,分别接了公网和内网。你从内网客户端发起连接,源地址是内网 IP,服务器收到请求后从内网网卡回应,没问题。但如果服务器的默认路由是走公网网卡,它向"内网客户端"回包时,就会查路由表,发现匹配的是 default,于是把回包从公网网卡发出去,结果内网客户端收到的包源地址变成了公网 IP,连接直接断掉。

这就是常说的"路由不对称"或"源地址策略路由"问题。解决办法通常是用 ip rule 配合策略路由,让内网源地址的流量强制走内网路由表。这个知识点在日常排障中并不罕见,如果你配了双网卡但仍然出现"能收到请求、回包却石沉大海"的情况,八成就是它。

4.4 从路由表视角看"通了但没有完全通"

我遇到过不止一次这样的求助:A 机器能 ping 通 B 机器的 IP,但 A 机器访问 B 机器上的 Nginx 页面就是不响应。

一步步拆:

  • IP 层通了,说明三层可达,路由没问题。
  • 端口不通,说明要么 B 机器的防火墙把端口挡了,要么 Nginx 根本没监听在预期的 IP 上。
  • 如果 Nginx 监听的是127.0.0.1:80,那 B 机器外部网卡上的流量压根不会进到 Nginx,这叫"服务绑定地址错误"。

这时候不要闷头去翻配置,先跑三条命令定位:

ss -tlnp # 看服务到底监听了什么地址 curl -I http://<ip>:<port> # 在本地或远程测一次 HTTP iptables -L -n # 看防火墙规则是否放行

5. 实战排查链路:从 ping 到 ss 一步步定位问题

5.1 一次 DNS 配置错误引发的"上网慢"排障全记录

我记得有一次帮某个实验室调一台 Ubuntu 服务器,现象是:机器能 ping 通网关、能 ping 通内网 IP,但访问外网时,浏览器或者curl要卡很久才出结果,一旦出结果,后面速度又是正常的。

我第一反应是 DNS 解析慢。执行:

$ cat /etc/resolv.conf nameserver 192.168.1.1 nameserver 8.8.8.8

看起来配置正常,但用dig测试解析耗时:

$ dig @192.168.1.1 www.example.com ;; Query time: 5214 msec

5 秒多,明显不正常。我换一个 DNS 再测:

$ dig @8.8.8.8 www.example.com ;; Query time: 58 msec

问题定位到 DNS 服务器本身响应慢。再查/etc/systemd/resolved.conf才发现,这台机器被配置成把请求先发送到某个不稳定的上游 DNS,而那个 DNS 在某些时段丢包严重,导致每次解析都要等超时兜底。把resolv.conf改成只用内网可靠的 DNS 后,一切恢复正常。

这个案例说明:拿到一个网络问题,要先分清是链路层、IP 层、传输层还是应用层的问题。DNS 属于应用层的解析服务,它的故障表现经常是"能 ping 通,但应用访问卡顿"。

5.2 ping 的 TTL 怎么看

ping不仅是一个"通不通"的探测工具,它的输出里藏着路由跳数的信息。

$ ping 192.168.1.1 64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.234 ms

TTL(Time To Live)是 IP 包每经过一个路由器就减 1 的计数器,减到 0 就会被丢弃,目的是防止数据包在环路里无限转发。Linux 默认初始 TTL 是 64,如果返回的包 TTL 是 64,说明对端就是一台直连的 Linux 机器(没经过路由转发);如果 TTL 是 128,说明对端很可能是 Windows;如果 TTL 是 50 左右,那大概率经过了跨运营商或多个路由节点的转发,可以结合traceroute画链路。

注意:不同系统的初始 TTL 不一样,所以不能只靠 TTL 猜操作系统,只能做参考。

5.3 我常用的排查命令清单

# 查看网卡与 IP 配置 ip addr # 查看路由 ip route # 测试三层连通性 ping -c 4 <target> # 查看路径上的每一跳 traceroute -n <target> # 查看端口监听 ss -tlnp # 测试 TCP 端口是否可达 nc -vz <target> <port> # 查看当前连接状态 ss -tan | grep ESTAB | wc -l # 抓包看细节 tcpdump -i eth0 host <target> and port 80 -n

很多新手一上来就tcpdump,这不是不对,但你要先知道问题大概在哪个层,再决定要不要抓包。如果路由表都错了,抓包只是浪费时间。整体的思路应该是"自上而下"或者"自下而上"逐层排除:先看 IP 通不通,再看端口通不通,最后才看应用层的内容。

5.4 一个典型的"本地通、远程不通"问题

某次帮一个开发者看他的服务,本机curl localhost:8080完全正常,但从另外一台机器访问他的 IP:8080 就是超时。

步骤:

# 1. 确认服务监听地址 ss -tlnp | grep 8080 # 如果显示 127.0.0.1:8080,说明服务只监听回环地址

果然,他的服务默认只监听了127.0.0.1,外部流量根本进不来。把启动参数或配置里的 bind 地址改成0.0.0.0后,再从外部访问就通了。

这类问题非常常见,而且很多人会误以为是防火墙的锅。其实只要服务监听在 loopback 上,防火墙放行与否根本不重要,流量压根没到防火墙那一步。先看监听地址,再看防火墙,顺序不能反。

6. 几个值得拿笔记下来的实操经验

6.1 配置文件改完,一定要让它生效

手动改/etc/network/interfaces或 NetworkManager 的配置后,不同发行版的生效方式不一样。有的用systemctl restart networking,有的用nmcli connection reload,还有的干脆重启机器最省事。

我个人的习惯是:如果只是改 DNS,直接改/etc/resolv.conf并用resolvectl刷新;如果是改 IP、掩码、网关这样的核心配置,宁可把影响窗口留出来,systemctl restart NetworkManager一次到位,然后立刻用ip addr验证配置有没有真的生效。

这里有个细节:很多云服务器的镜像里/etc/resolv.conf是符号链接,指向 systemd-resolved 生成的文件,你直接用 vim 去改可能保存不了,或者重启后被覆盖。正确做法是修改/etc/systemd/resolved.conf,或者把 DNS 配置写到网卡配置文件的DHCP覆盖项里。

6.2 MTU 引发的"大多数页面正常、个别页面打不开"

MTU(最大传输单元)是链路层对单个帧大小的限制,以太网默认 1500。如果链路中有隧道(比如某种封装网络或 PPPoE 拨号),有效载荷会被额外占用一部分空间,此时 MTU 也需要相应调小。

我遇到过这样的场景:内网访问某台账务系统时,大部分页面正常,但涉及上传大文件或下载某些特定资源的页面就是卡死。用ping -s 1472测试发现,超过 1400 字节的包在中间某个环节被丢弃了。最后把出口设备的 MTU 从 1500 调到 1400,问题消失。

遇到"个别大包不通、小包正常"的诡异故障时,第一反应就应该是 MTU。试探的方法是:

# -M do 表示不分片,-s 指定 ICMP 载荷大小 ping -M do -s 1472 <target>

如果-s 1472能通而-s 1473不通,说明这条链路的 MTU 就是 1500 左右,问题大概率出现在某个隧道的开销上。

6.3 别急着用 iptables 挡,先搞清楚连接状态

我在课上见过不少学生,想要"只允许别人访问我服务器的 80 端口",于是写一条 INPUT 策略,把所有 SYN 包都挡了,结果自己远程 SSH 也断了。原因是没搞清楚:服务器的回包(属于 ESTABLISHED 状态的连接)也要被放行。

标准的做法是:

iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A INPUT -p tcp --dport 80 -j ACCEPT iptables -A INPUT -j DROP

第一条让所有已有连接的回包进来,第二条放行新的 80 端口的连接,第三条才是默认拒绝。顺序不能乱,ESTABLISHED规则必须放在DROP规则前面,否则回包会被挡在门外。

6.4 用"最小复现"的方式验证网络配置

配完网络之后,不要急着把所有服务都拉起来。先做一个最小验证:

  1. ip addr确认 IP 和掩码无误。
  2. ping同网段的另一台机器,确认二层和三层的连通。
  3. ping网关,确认默认路由能走通。
  4. dig一个域名,确认 DNS 链路正常。
  5. 最后再启动你的业务服务,用ss确认端口在监听,从另一台机器实际访问一次。

这套流程看起来多,但每次最多两分钟。很多人跳过前面三个,直接一步跳到"启动服务",结果一旦失败,根本无法判断是哪一层出了问题,反而浪费更多时间。

6.5 抓包是最后的显微镜,不是第一放大镜

最后聊聊抓包。tcpdump在你长期排查不明问题时是神器,但不建议新手一上来就用,因为干扰信息太多。我之前遇到过一哥们,抓包抓了两个小时,日志导出好几兆,结果发现自己一直在看 ARP 广播包和 SSH 的心跳包,完全跑偏。

真要抓,先明确你想验证什么:

# 只抓目标主机、指定端口、不解析域名 tcpdump -i eth0 host 192.168.1.10 and port 8080 -n # 保存到文件慢慢分析 tcpdump -i eth0 -w capture.pcap host 192.168.1.10

抓包前先想清楚:我要看的是 TCP 握手、重传,还是应用层的 HTTP 请求内容?只要带着问题去抓,效率会高很多。

这些路我基本都走过一遍。从刚开始看着ifconfig发呆,到后面能从一堆ss输出里快速定位问题,最大的体会就是:Linux 网络基础概念不是背出来的,是"查路由 → 看监听 → 测连通"这条链路反复练出来的。遇到问题的时候,按层往下拆,思路一清晰,命令都是顺手的事。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/5 5:03:16

C++解释器模式三种变体:从lambda组合子到模板元编程的工程实践

1. 为什么我在C里舍弃了教科书式的解释器模式教科书中讲解解释器模式&#xff0c;一般会画这样一张类图&#xff1a;一个抽象Expression基类&#xff0c;下面挂上NumberExpression、AddExpression、SubtractExpression这些子类&#xff0c;每个子类实现一个Evaluate方法&#x…

作者头像 李华
网站建设 2026/10/28 15:34:38

幼儿园管理系统计算机毕设 SpringBoot+Vue 项目

&#x1f496;&#x1f496;作者&#xff1a;计算机毕业设计小明哥 &#x1f499;&#x1f499;个人简介&#xff1a;曾长期从事计算机专业培训教学&#xff0c;本人也热爱上课教学&#xff0c;语言擅长Java、微信小程序、Python、Golang、安卓Android等&#xff0c;开发项目包…

作者头像 李华
网站建设 2026/11/4 9:59:01

智元精灵G2工博会“上岗”,胜任多类工业作业

第二十六届中国国际工业博览会10月12日在国家会展中心&#xff08;上海&#xff09;开幕。智元创新&#xff08;上海&#xff09;科技股份有限公司&#xff08;以下简称“智元”&#xff09;以“工业部署态”为主线&#xff0c;展示精密制造、柔性装配、汽车零部件上料与仓储物…

作者头像 李华
网站建设 2026/10/23 6:55:05

顺序表详解:从数组存储到动态扩容的数据结构基础

1. 顺序表到底是什么&#xff1a;先把这个基础概念吃透1.1 从“数据怎么存放”说起如果你刚开始学数据结构&#xff0c;第一个真正需要动手写的代码通常就是顺序表。别看它基础&#xff0c;几乎所有后续内容——栈、队列、哈希表甚至数据库的底层存储——都会遇到顺序存储的影子…

作者头像 李华
网站建设 2026/10/30 13:24:47

中长期资金加速入市,指数化投资浪潮中如何配置中证A500?

2026年以来&#xff0c;A股市场的资金结构正在经历一场深刻变化。保险资金权益投资比例上限提升、社保基金与养老金持续增配、公募基金指数产品规模快速扩容&#xff0c;三重力量叠加&#xff0c;推动市场投资者结构向机构化、长期化方向加速演进。海外成熟市场的经验表明&…

作者头像 李华
网站建设 2026/10/23 11:21:07

分布式架构评审实战:六维审视与风险清零机制

1. 为什么分布式架构评审不能走过场分布式架构评审这事儿&#xff0c;看着是研发流程里的一环&#xff0c;实则是用最少成本买最大安全感的地方。很多团队都走过这样的弯路&#xff1a;方案评审会开了两小时&#xff0c;PPT讲得头头是道&#xff0c;参会人都点头了&#xff0c;…

作者头像 李华