AI 摘要
AI
正在生成摘要...

Linux 网络故障排查实战指南:从连通性测试到抓包分析

说明: 本文为配置思路与示例整理,不代表作者已在自己的服务器上逐项验证全部命令。执行涉及公网暴露、账户权限、数据删除或服务重启的操作前,请先备份,并结合官方文档与实际环境核验。

服务器上某个服务突然访问不了?容器之间通信异常?这篇文章从最基础的连通性测试讲起,到使用 tcpdump 抓包分析,帮你系统性地掌握 Linux 网络故障排查的完整方法论。

一、网络故障排查的思维框架

遇到网络问题时,很多人第一反应是乱试一通。其实网络排查有清晰的层次结构,从下往上依次是:

TEXT
物理链路 → IP连通性 → 端口可达性 → DNS解析 → 应用层协议

记住这个分层模型,排查效率会大幅提升。下面我们逐层击破。

二、第一层:物理链路与网络接口

排查的第一步是确认网卡是否正常工作。

BASH
# 查看网卡状态和IP地址
ip addr show

# 输出示例:
# 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP>
#     inet 10.0.0.100/24 brd 10.0.0.255 scope global eth0
#     link/ether aa:bb:cc:dd:ee:ff

重点关注:

  • UP 状态表示网卡已启用
  • LOWER_UP 表示物理链路已连接(网线已插好或虚拟网络已分配)
  • inet 行显示了 IP 地址和子网掩码

如果网卡没有获取到 IP,检查 DHCP 或手动配置:

BASH
# 查看默认路由
ip route show

# 如果缺少默认路由,手动添加(临时)
ip route add default via 10.0.0.1

# 永久配置(以 Netplan 为例,Ubuntu)
sudo vim /etc/netplan/01-config.yaml

Netplan 配置示例:

YAML
network:
  version: 2
  ethernets:
    eth0:
      addresses:
        - 10.0.0.100/24
      gateway4: 10.0.0.1
      nameservers:
        addresses:
          - 8.8.8.8
          - 1.1.1.1

应用配置:

BASH
sudo netplan apply

三、第二层:IP 连通性测试

确认网卡正常后,测试 IP 层的连通性。

BASH
# 测试到目标IP是否可达
ping -c 4 8.8.8.8

# 使用特定网卡测试(多网卡场景)
ping -c 4 -I eth1 8.8.8.8

# 查看完整路由路径
traceroute 8.8.8.8

# 如果 traceroute 没有安装
sudo apt install traceroute -y
# 或
sudo yum install traceroute -y

常见场景排查:

场景1:ping 网关通但 ping 外网不通

BASH
# 检查NAT配置
sudo iptables -t nat -L -n -v

# 确保有MASQUERADE规则(网关/路由器上执行)
sudo iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE

场景2:DNS 解析问题导致"能 ping IP 但 ping 不通域名"

BASH
# 直接测试DNS解析
nslookup www.example.com
dig www.example.com

# 检查当前DNS配置
cat /etc/resolv.conf

四、第三层:端口可达性

服务启动了但连不上?很可能是端口问题。

4.1 检查本地端口监听

BASH
# 使用 ss(推荐,比 netstat 快)
ss -tlnp

# 输出示例:
# State  Recv-Q  Send-Q  Local Address:Port  Process
# LISTEN 0       128     0.0.0.0:80          users:(("nginx",pid=1234))
# LISTEN 0       128     0.0.0.0:443         users:(("nginx",pid=1234))
# LISTEN 0       128     127.0.0.1:5432      users:(("postgres",pid=5678))

参数解释:

  • -t:TCP 协议
  • -l:只显示监听状态
  • -n:不解析服务名(显示数字端口)
  • -p:显示进程信息

关键检查点: 服务是否绑定到了 0.0.0.0(所有接口)还是 127.0.0.1(仅本地)?绑定到 127.0.0.1 的服务只能从本机访问。

4.2 检查远程端口是否可达

BASH
# 使用 nc(netcat)测试端口
nc -zv 10.0.0.100 80

# 批量测试多个端口
nc -zv 10.0.0.100 22 80 443 8080

# 用 curl 测试 HTTP 服务
curl -v http://10.0.0.100:80 --connect-timeout 5

4.3 防火墙排查

BASH
# 查看 iptables 规则
sudo iptables -L -n -v

# 如果使用 firewalld(CentOS/RHEL)
sudo firewall-cmd --list-all

# 临时放行某个端口(iptables)
sudo iptables -I INPUT -p tcp --dport 8080 -j ACCEPT

# firewalld 放行端口
sudo firewall-cmd --add-port=8080/tcp --permanent
sudo firewall-cmd --reload

五、第四层:DNS 问题排查

DNS 是最常见也最容易被忽视的故障点。

BASH
# 基本 DNS 查询
dig www.example.com

# 指定DNS服务器查询
dig @8.8.8.8 www.example.com

# 只要IP结果(简洁输出)
dig +short www.example.com

# 查看完整的DNS解析链
dig +trace www.example.com

# 测试 /etc/hosts 是否生效
getent hosts www.example.com

常见 DNS 问题及解决:

BASH
# 问题1:DNS解析失败
# 原因:resolv.conf 中DNS服务器配置错误
cat /etc/resolv.conf
# 修改为可靠DNS
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf

# 问题2:systemd-resolved 占用53端口
# 如果用自建DNS(如 CoreDNS/pdns),需要停掉 systemd-resolved
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved

# 问题3:域名在本地hosts中有旧记录
grep example.com /etc/hosts

六、第五层:tcpdump 抓包分析

当以上步骤都无法定位问题时,抓包是终极手段。

6.1 基础抓包

BASH
# 抓取指定网卡的所有流量(Ctrl+C停止)
sudo tcpdump -i eth0

# 只抓HTTP相关流量(80端口)
sudo tcpdump -i eth0 port 80

# 只抓与特定主机的通信
sudo tcpdump -i eth0 host 10.0.0.200

# 组合条件:抓取访问特定IP的80端口流量
sudo tcpdump -i eth0 host 10.0.0.200 and port 80

# 保存到文件(可用Wireshark打开分析)
sudo tcpdump -i eth0 port 443 -w capture.pcap

# 限制抓包数量
sudo tcpdump -i eth0 -c 100 port 80

6.2 实战场景:排查 HTTP 请求超时

假设你的应用访问某 API 经常超时,抓包分析:

BASH
# 抓取目标域名的HTTPS流量(443端口)
sudo tcpdump -i eth0 host api.example.com and port 443 -nn -v

# 关注TCP三次握手是否成功
# 如果看到大量 SYN 但没有 SYN-ACK,说明目标端口不可达或被防火墙拦截
# 如果握手成功但后续没有数据,可能是应用层问题

6.3 抓包输出解读

BASH
# 使用 -A 参数以ASCII显示内容(适合HTTP明文请求)
sudo tcpdump -i eth0 port 80 -A | head -50

# 使用 -X 同时显示十六进制和ASCII
sudo tcpdump -i eth0 port 80 -X -c 20

常见 TCP 标志位含义:

  • S:SYN(连接请求)
  • S.:SYN-ACK(连接确认)
  • .:ACK(确认)
  • P:PSH(推送数据)
  • R:RST(重置连接 — 端口未开放时常见)
  • F:FIN(正常关闭)

七、综合排查脚本

把以上步骤整合成一个快速诊断脚本:

BASH
#!/bin/bash
# network-diagnose.sh - 快速网络诊断脚本
# 用法: ./network-diagnose.sh <目标IP或域名>

TARGET=${1:-"8.8.8.8"}
PORT=${2:-80}

echo "====== 网络诊断:$TARGET ======"

echo -e "\n[1] 网络接口状态:"
ip -br addr show | grep -v lo

echo -e "\n[2] 默认路由:"
ip route show default

echo -e "\n[3] DNS 解析:"
dig +short "$TARGET" 2>/dev/null || nslookup "$TARGET"

echo -e "\n[4] Ping 测试(3次):"
ping -c 3 -W 2 "$TARGET"

echo -e "\n[5] Traceroute(前10跳):"
traceroute -m 10 -w 2 "$TARGET" 2>/dev/null || echo "traceroute not installed"

echo -e "\n[6] 端口 $PORT 连通性:"
nc -zv -w 3 "$TARGET" "$PORT" 2>&1

echo -e "\n[7] 本地监听端口(非回环):"
ss -tlnp | grep -v '127.0.0.1' | head -10

echo -e "\n[8] 防火墙状态:"
if command -v firewall-cmd &>/dev/null; then
    sudo firewall-cmd --list-all 2>/dev/null
else
    sudo iptables -L -n --line-numbers 2>/dev/null | head -20
fi

echo -e "\n====== 诊断完成 ======"

使用方式:

BASH
chmod +x network-diagnose.sh
./network-diagnose.sh 10.0.0.50 443

八、常用排查命令速查表

命令 用途 示例
ip addr 查看IP地址 ip addr show eth0
ip route 查看路由表 ip route show
ping 测试连通性 ping -c 4 8.8.8.8
traceroute 查看路由路径 traceroute 8.8.8.8
ss 查看端口监听 ss -tlnp
nc 测试端口连通 nc -zv host port
dig DNS查询 dig +short domain.com
curl HTTP测试 curl -vI http://host:port
tcpdump 抓包分析 tcpdump -i eth0 port 80
iptables 防火墙规则 iptables -L -n

九、总结

网络故障排查的核心思路就是分层定位

  1. 先看物理层:网卡是否 UP、IP 是否正确
  2. 再测连通性:ping 网关 → ping 外网 → traceroute
  3. 检查端口:ss 看本地监听 → nc 测远程端口 → 检查防火墙
  4. 排查 DNS:dig 解析 → 检查 resolv.conf → 检查 hosts
  5. 终极武器:tcpdump 抓包分析实际数据包

养成系统化排查的习惯,遇到网络问题就不会再手忙脚乱了。收藏这篇指南,下次遇到网络故障时按步骤来,效率翻倍!

评论