Appearance
网络基础
Linux 网络排错离不开几个核心概念:IP 地址、子网掩码、网关、DNS、端口和 TCP 连接。这些概念决定后面所有网络配置和诊断命令的用法。
一、IP 地址
IP 地址是主机在网络中的地址标识。Linux 上一个网卡可以绑定一个或多个 IP 地址,服务监听时可以选择只监听某个特定的 IP,也可以监听所有地址。
IPv4 地址是 32 位,通常写成点分十进制:192.168.1.10。
按使用范围分为公有地址和私有地址。私有地址只能在局域网或内网中使用,不能直接在公网上路由。
私有地址范围:
| 网段 | 范围 |
|---|---|
10.0.0.0/8 | 10.0.0.0 — 10.255.255.255 |
172.16.0.0/12 | 172.16.0.0 — 172.31.255.255 |
192.168.0.0/16 | 192.168.0.0 — 192.168.255.255 |
服务器内网通信通常都在这些网段内。几个特殊地址:
| 地址 | 含义 |
|---|---|
127.0.0.1 | 本机回环地址(localhost),只能本机访问 |
0.0.0.0 | 监听时表示"本机所有 IPv4 地址" |
::1 | IPv6 的回环地址 |
服务如果只监听 127.0.0.1:8080,同机 curl 没问题,但外部机器无法访问——即使防火墙全放也不行。排查"服务启动了但外部访问不了"时,第一眼就看监听地址是不是 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.1—192.168.1.254 - 广播地址:
192.168.1.255
常见 CIDR 对照:
| CIDR | 子网掩码 | 可用主机数 |
|---|---|---|
/24 | 255.255.255.0 | 254 |
/25 | 255.255.255.128 | 126 |
/26 | 255.255.255.192 | 62 |
/16 | 255.255.0.0 | 65534 |
两台机器是否属于同一网段,不是看 IP 地址是否相近,而是看 IP 和掩码一起计算出的网络地址是否相同。同一个 IP 配上不同的掩码,归属的网段可能完全不同。
| IP | 掩码 | 网段 |
|---|---|---|
192.168.1.200 | /24 | 192.168.1.0/24 |
192.168.1.200 | /25 | 192.168.1.128/25 |
云主机上修改网卡配置时,掩码填错会导致"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),都从 eth0 发给下一跳 192.168.1.1。
第二行:192.168.1.0/24 这个直连网段的流量,直接从 eth0 出去,源地址为 192.168.1.10。
路由匹配遵循"最长前缀优先"原则:去往 10.10.1.2 的包,如果路由表中同时有 10.0.0.0/8 和 10.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 里写死了一个旧地址。排查域名解析异常时,/etc/hosts 和 nsswitch.conf 要一起看。
解析域名:
bash
getent hosts example.com # 走系统 NSS,模拟真实解析路径
dig example.com # 直接查 DNS,绕过 hosts 和缓存
dig @8.8.8.8 example.com # 指定 DNS 服务器查询getent hosts 的解析路径更接近应用程序实际使用的路径——包括 /etc/hosts、DNS、LDAP 等,取决于 nsswitch 配置。
五、端口
端口是传输层(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 看本机监听,telnet 或 nc 从远端测试,分层查。
监听地址和端口的组合也很关键:
| 监听方式 | 可访问范围 |
|---|---|
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 | 网卡是否存在、是否有 IP | ip addr |
| 2 | 路由是否正常 | ip route |
| 3 | DNS 能否解析 | getent hosts <domain> |
| 4 | 本机端口是否监听 | ss -lntp |
| 5 | TCP 能否连通 | curl -v、nc -zv |
| 6 | 应用是否正常响应 | 查看应用日志和返回内容 |
这个从下往上的顺序,通常比一上来就抓包更快定位问题。
七、TCP 三次握手
TCP 在传输数据之前需要建立连接,这个过程叫三次握手。它本质上是一个双方互相确认收发能力的过程。
| 步骤 | 方向 | 标志 | 含义 |
|---|---|---|---|
| 1 | 客户端 → 服务端 | SYN | "我想和你建立连接" |
| 2 | 服务端 → 客户端 | SYN-ACK | "收到,我也准备好了" |
| 3 | 客户端 → 服务端 | ACK | "收到你的确认" |
如果服务端端口没有监听,客户端发起 SYN 后服务端会回复 RST(复位),客户端收到 "Connection refused"。如果中间网络或防火墙丢弃了 SYN 包,客户端持续重发 SYN 但收不到任何回应,最终超时。
bash
curl -v http://10.0.0.1:80/Connection refused 和 Connection timed out 是两个方向完全不同的信号:前者说明已经到达目标机器,但目标端口没有监听;后者说明网络层面的问题(路由不可达、防火墙丢弃、目标机器不存在等)。
UDP 没有三次握手,所以判断"UDP 端口通不通"没有 TCP 那么直观。DNS(53/UDP)、NTP 这类服务排查时经常需要检查应用层是否给出了响应,或直接抓包看 UDP 包有没有返回。