跳转到内容

网络故障

网络故障排查的关键是分层排查、逐步缩小范围。本文按照从物理层到应用层的顺序,介绍一套系统性的网络排查方法。

网络故障排查应该遵循 OSI 模型从底层向上的顺序:

  1. 物理层 / 链路层 — 网线、网卡、链路状态
  2. 网络层 — IP 地址、路由、网关
  3. DNS — 域名解析
  4. 防火墙 — firewalld / iptables 规则
  5. 传输层 / 应用层 — 端口、服务监听状态

原则: 不要跳过低层直接排查高层。如果 IP 地址都没配对,排查 DNS 毫无意义。

查看网络接口状态
$ ip link show

关注 state UP 还是 state DOWN。如果接口处于 DOWN 状态:

启用网络接口
$ sudo ip link set eth0 up
检查网卡驱动是否加载
$ lspci | grep -i ethernet
$ lsmod | grep -i e1000 # 示例:Intel 网卡
使用 ethtool 检查链路状态
$ sudo ethtool eth0

在输出中查找 Link detected: yes。如果显示 no,说明物理连接有问题(网线、交换机端口、虚拟网络配置等)。

查看网卡统计信息(错误和丢包)
$ ip -s link show eth0

关注 errorsdropped 计数。大量错误可能意味着硬件问题或双工模式不匹配。

查看所有接口的 IP 地址
$ ip addr show
查看路由表
$ ip route show

确认以下信息:

  • 接口有正确的 IP 地址
  • 子网掩码正确
  • 存在默认路由(default via x.x.x.x
测试到网关的连通性
$ ping -c 3 $(ip route show default | awk '{print $3}')

如果 ping 网关失败,问题在本地网络配置或物理连接。

查看所有连接配置
$ nmcli connection show
查看指定连接的详细配置
$ nmcli connection show "有线连接 1"
查看设备状态
$ nmcli device status
重新激活连接
$ sudo nmcli connection down "有线连接 1" && sudo nmcli connection up "有线连接 1"

DHCP 未获取到地址:

手动请求 DHCP 地址
$ sudo nmcli connection modify "有线连接 1" ipv4.method auto
$ sudo nmcli connection up "有线连接 1"
查看 DHCP 客户端日志
$ journalctl -u NetworkManager --since "5 minutes ago" | grep -i dhcp

设置静态 IP:

配置静态 IP 地址
$ sudo nmcli connection modify "有线连接 1" \
ipv4.method manual \
ipv4.addresses "192.168.1.100/24" \
ipv4.gateway "192.168.1.1" \
ipv4.dns "8.8.8.8 8.8.4.4"
$ sudo nmcli connection up "有线连接 1"

如果 IP 层正常(能 ping 通 IP 地址)但无法访问域名:

检查 DNS 配置
$ cat /etc/resolv.conf
测试 DNS 解析
$ dig google.com
使用指定 DNS 服务器测试
$ dig @8.8.8.8 google.com
简洁输出
$ dig +short google.com
测试反向解析
$ dig -x 8.8.8.8

resolv.conf 被覆盖:

NetworkManager 会管理 /etc/resolv.conf。如果手动修改总是被覆盖:

通过 nmcli 配置 DNS 服务器
$ sudo nmcli connection modify "有线连接 1" ipv4.dns "8.8.8.8 114.114.114.114"
$ sudo nmcli connection up "有线连接 1"

DNS 解析慢:

测试解析延迟
$ time dig google.com

如果延迟很高,可能是 DNS 服务器不可达或响应慢。尝试更换 DNS:

临时测试其他 DNS 服务器
$ dig @114.114.114.114 google.com
$ dig @223.5.5.5 google.com

本地 hosts 文件问题:

检查 /etc/hosts 是否有异常条目
$ cat /etc/hosts
检查 nsswitch.conf 中的解析顺序
$ grep hosts /etc/nsswitch.conf

正常配置一般为:hosts: files dns myhostname

防火墙是 EL 系统上网络问题的最常见原因之一。服务正常运行但外部无法访问,十有八九是防火墙。

查看 firewalld 状态
$ sudo firewall-cmd --state
列出当前区域的所有规则
$ sudo firewall-cmd --list-all
列出所有已放行的服务
$ sudo firewall-cmd --list-services
列出所有已放行的端口
$ sudo firewall-cmd --list-ports
临时放行端口(重启后失效)
$ sudo firewall-cmd --add-port=8080/tcp
临时放行服务
$ sudo firewall-cmd --add-service=http
永久放行端口
$ sudo firewall-cmd --add-port=8080/tcp --permanent
$ sudo firewall-cmd --reload
永久放行服务
$ sudo firewall-cmd --add-service=http --permanent
$ sudo firewall-cmd --add-service=https --permanent
$ sudo firewall-cmd --reload
临时开启 firewalld 日志
$ sudo firewall-cmd --set-log-denied=all
查看被拒绝的流量
$ sudo journalctl -f | grep REJECT

测试完毕后关闭日志:

关闭拒绝日志
$ sudo firewall-cmd --set-log-denied=off

如果需要快速确认是否是防火墙问题:

临时将接口移到 trusted 区域(允许所有流量)
$ sudo firewall-cmd --zone=trusted --change-interface=eth0

警告: 这会完全开放该接口,仅用于临时测试,测试后立即恢复。

恢复接口到默认区域
$ sudo firewall-cmd --zone=public --change-interface=eth0
查看所有监听的 TCP 端口
$ sudo ss -tlnp
查看所有监听的 UDP 端口
$ sudo ss -ulnp
查看指定端口是否在监听
$ sudo ss -tlnp | grep :80

如果服务没有监听预期的端口,检查服务状态:

检查服务状态
$ systemctl status nginx
$ journalctl -u nginx -n 30 --no-pager
测试本地 HTTP 服务
$ curl -v http://localhost/
测试并显示响应头
$ curl -I http://localhost/
测试特定端口
$ curl -v http://localhost:8080/
安装 traceroute(如果没有)
$ sudo dnf install -y traceroute
追踪到目标的路由
$ traceroute 8.8.8.8
使用 TCP 模式追踪(更能穿透防火墙)
$ sudo traceroute -T -p 80 example.com
抓取指定接口上指定端口的流量
$ sudo tcpdump -i eth0 port 80 -nn -c 20
抓包保存到文件供后续分析
$ sudo tcpdump -i eth0 port 443 -w /tmp/capture.pcap -c 100

场景一:服务器能 ping 通但 HTTP 不通

Section titled “场景一:服务器能 ping 通但 HTTP 不通”

排查顺序:

  1. 确认 Web 服务在运行:systemctl status nginx
  2. 确认服务监听正确端口:ss -tlnp | grep :80
  3. 确认本地可以访问:curl http://localhost/
  4. 检查防火墙:firewall-cmd --list-all
  5. 检查 SELinux:ausearch -m avc -ts recent
确认目标端口是否可达
$ timeout 5 bash -c 'echo > /dev/tcp/目标IP/目标端口' && echo "端口可达" || echo "端口不可达"

可能原因:

  • 对方防火墙阻挡
  • 路由问题(traceroute 排查)
  • ISP 或中间网络设备阻断

场景三:NetworkManager 连接反复断开重连

Section titled “场景三:NetworkManager 连接反复断开重连”
查看 NetworkManager 日志
$ journalctl -u NetworkManager --since "30 minutes ago" | grep -E '(connect|disconnect|fail)'
检查网络接口的物理状态变化
$ dmesg | grep -i 'link'

可能原因:

  • 网线接触不良
  • 网卡驱动问题
  • DHCP 租约冲突

从 CentOS 迁移后,网络接口名称或配置文件可能变化:

检查连接配置文件
$ ls /etc/NetworkManager/system-connections/
$ ls /etc/sysconfig/network-scripts/ifcfg-* 2>/dev/null
重新创建连接
$ sudo nmcli connection add type ethernet con-name "主连接" ifname eth0
$ sudo nmcli connection modify "主连接" ipv4.method auto
$ sudo nmcli connection up "主连接"
目标命令
查看接口状态ip link show
查看 IP 地址ip addr show
查看路由表ip route show
测试连通性ping -c 3 目标
DNS 解析dig 域名
查看监听端口ss -tlnp
追踪路由traceroute 目标
防火墙规则firewall-cmd --list-all
查看连接nmcli connection show
抓包分析tcpdump -i 接口 port 端口
HTTP 测试curl -v URL
NetworkManager 日志journalctl -u NetworkManager