Skip to content

网络基础

Linux 网络排错,绕不开几个核心概念:IP 地址、子网掩码、网关、DNS、端口、TCP 连接。后面所有的网络配置和诊断命令,都是基于这几个概念展开的。这套基础打牢了,排查网络问题的时候才知道每一步在查什么、为什么这么查——不然就是按教程敲命令,看到输出也不知道该怎么读。

一、IP 地址

IP 地址是主机在网络里的身份标识。Linux 上一张网卡可以绑一个或多个 IP,服务监听的时候可以选择只监听某个特定 IP,也可以监听所有地址——这个选择直接影响外部能不能访问,后面会专门讲。

IPv4 地址是 32 位的,平时写成点分十进制,比如 192.168.1.10。按使用范围分公网地址和私有地址,私有地址只能在局域网或内网里用,不能直接在公网上路由。三个私有地址网段记一下:10.0.0.0/8172.16.0.0/12192.168.0.0/16——服务器内网通信基本都在这些网段里。

几个特殊地址要记住:127.0.0.1 是本机回环地址(localhost),只能本机访问自己;0.0.0.0 在服务监听时表示"本机所有 IPv4 地址";::1 是 IPv6 的回环地址。

有个特别常见的坑:服务只监听了 127.0.0.1:8080,本机 curl 127.0.0.1:8080 没问题,但外部机器死活连不上——哪怕防火墙全开了也不行,因为服务根本不接收来自其他 IP 的连接。排查"服务起来了但外部访问不了"这种问题,第一眼就看监听地址是不是 127.0.0.1,十有八九是这个原因。

二、子网掩码和 CIDR

子网掩码用来区分 IP 地址里哪部分是"网络"、哪部分是"主机"。同一个网段内的机器,网络部分相同,可以直接通信;不同网段的,得经过网关转发。这个概念理解了,后面的路由就好懂了。

CIDR(无类别域间路由)写法把掩码长度直接写在 IP 后面,比如 192.168.1.10/24——/24 表示前 24 位是网络位,剩下 8 位是主机位。192.168.1.10/24 所在的网段:网络地址是 192.168.1.0,可用主机范围 192.168.1.1192.168.1.254,广播地址 192.168.1.255(网络地址和广播地址不能分配给主机)。

常见 CIDR 对照,背一下常用的:

CIDR子网掩码可用主机数
/24255.255.255.0254
/25255.255.255.128126
/26255.255.255.19262
/16255.255.0.065534

一个容易搞错的点:两台机器是不是同一网段,不是看 IP 地址像不像,而是看 IP + 掩码一起算出来的网络地址一不一样。比如 192.168.1.200/24 属于 192.168.1.0/24 网段,但 192.168.1.200/25 属于 192.168.1.128/25 网段——同一个 IP,掩码不同,归属的网段完全不同。云主机上改网卡配置时掩码填错,就会出现"IP 看着是对的,但就是不通"这种诡异现象。

三、网关

默认网关是内网主机通往外部网络的出口。访问不在本网段的地址时,数据包就发给默认网关,由网关负责往下一跳转发

bash
ip route

输出大概长这样:

default via 192.168.1.1 dev eth0
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.10

第一行 default via 192.168.1.1 dev eth0:所有目的地不在路由表里的流量(default),都从 eth0 发给下一跳 192.168.1.1(这就是网关)。第二行是直连网段:192.168.1.0/24 这个网段的流量直接从 eth0 出去,源地址是 192.168.1.10

路由匹配遵循**"最长前缀优先"原则**——去往 10.10.1.2 的包,如果路由表里同时有 10.0.0.0/810.10.0.0/16,会匹配更具体的 /16(掩码更长 = 更精确)。理解这个原则,排查"流量走了错误的下一跳"这类问题就有方向了。

四、DNS

DNS 把人类好记的域名翻译成机器要用的 IP 地址。

bash
cat /etc/resolv.conf          # 查看当前用的 DNS 服务器

Linux 的域名解析顺序由 /etc/nsswitch.conf 里的 hosts 行控制:

bash
grep '^hosts:' /etc/nsswitch.conf

输出 hosts: files dns 表示先查 /etc/hosts 文件,再查 DNS。线上经常踩一个坑:DNS 明明改了,机器还解析到旧 IP,最后发现是 /etc/hosts 里写死了一个旧地址——因为 hosts 优先级在 DNS 前面,改了 DNS 没用。所以排查域名解析异常,/etc/hostsnsswitch.conf 要一起看。

解析域名,几个命令各有侧重:

bash
getent hosts example.com         # 走系统 NSS,模拟应用真实的解析路径
dig example.com                  # 直接查 DNS,绕过 hosts 和本地缓存
dig @8.8.8.8 example.com         # 指定用某个 DNS 服务器查

排查"应用解析到的 IP 跟预期不一样"的时候,用 getent hosts——它的解析路径跟应用一致(包括 hosts、DNS、LDAP 这些,看 nsswitch 配置)。而 dig 是直接查 DNS 的,绕过 hosts 文件,适合确认"DNS 本身返回的是什么"。

五、端口

端口是传输层(TCP/UDP)用来区分同一台机器上不同服务的编号。同一个 IP 上可以同时跑 HTTP(80)、SSH(22)、MySQL(3306),就靠端口号区分。

端口范围分几段:0-1023 是知名端口(Well-known),绑定需要 root 权限;1024-49151 是注册端口;49152-65535 是临时/私有端口,客户端发起连接时通常从这个范围随机选一个。几个常见服务端口记一下:22 是 SSH、80 是 HTTP、443 是 HTTPS、3306 是 MySQL、6379 是 Redis、5432 是 PostgreSQL。

"端口通不通"其实要分好几个层面判断,不是一个命令能搞定的:本机服务有没有监听、本机防火墙放行了没、云安全组放行了没、中间网络路由可达吗、对端防火墙拦了没。排查时分层查——ss 看本机监听情况,telnetnc 从远端测试连通性。

监听地址和端口的组合决定了可访问范围,这点跟前面 IP 那节呼应:

监听方式谁能访问
127.0.0.1:8080仅本机
0.0.0.0:8080所有网卡、所有 IP 都能访问
192.168.1.10:8080只能通过 192.168.1.10 这个 IP 访问

ss -lntp 输出里看到 127.0.0.1:8080,问题通常不在防火墙,而是服务配置本身就限制了只接收本机连接——得改服务配置,不是开防火墙能解决的。

六、OSI 模型与排障顺序

OSI 七层模型教科书里要背,但实际排障不需要严格背诵。更有用的是按层次从下往上排查的思路:

排查步骤确认什么用什么命令
1网卡在不在、有没有 IPip addr
2路由正不正常ip route
3DNS 能不能解析getent hosts <domain>
4本机端口监听了没ss -lntp
5TCP 能不能连通curl -vnc -zv
6应用有没有正常响应看应用日志和返回内容

这个从下往上的顺序,通常比一上来就抓包更快定位问题。底层断了上层肯定不通,先确认底层没问题再往上查,效率最高。

七、TCP 三次握手

TCP 传输数据之前要先建立连接,这个过程叫三次握手。它本质上是双方互相确认"我能发、你能收"的过程,三步走:

步骤方向标志在说什么
1客户端 → 服务端SYN"我想和你建立连接"
2服务端 → 客户端SYN-ACK"收到,我也准备好了"
3客户端 → 服务端ACK"收到你的确认,开始传数据"

理解三次握手,就能解释两种常见的连接失败现象。如果服务端端口没监听,客户端发 SYN 后服务端会回 RST(复位),客户端立刻收到 Connection refused——说明包到了目标机器,只是端口没服务。如果中间网络或防火墙把 SYN 包丢了,客户端持续重发 SYN 但收不到任何回应,最终 Connection timed out——说明网络层面就不通。

bash
curl -v http://10.0.0.1:80/

Connection refusedConnection timed out 是两个方向完全不同的信号,排查时一定要分清:前者是"到了对方但被拒",问题在服务端(端口没监听);后者是"根本到不了对方",问题在网络路径(路由、防火墙、对方机器不在线)。很多人把这两个混为一谈,排查方向就走错了。

UDP 没有三次握手,所以判断"UDP 端口通不通"没有 TCP 那么直观——发出去不知道对方收没收到。DNS(53/UDP)、NTP 这类 UDP 服务排查时,得看应用层有没有给出响应,或者直接抓包看 UDP 包有没有返回。