VPS 上线跑业务,最怕的就是"突然连不上"或者"网站一会快一会慢"。很多新手第一反应是重装系统,其实 90% 的网络故障都能通过一套标准的排查流程定位出来。本文从最基础的 ping 讲起,到路由追踪、DNS 解析、端口连通性,再到 tcpdump 抓包,带你走一遍完整的网络排错全链路,并给出最常见的故障案例与解决办法。
一、排查前的准备:理清思路与工具全景
网络排错不要盲目敲命令,先按"物理链路 → IP 层 → 传输层 → 应用层"的层次顺序排查,可以少走很多弯路。一张表看清各环节对应的工具:
| 排查层次 | 检查内容 | 推荐命令 |
|---|---|---|
| 物理链路 / 网卡 | 网卡状态、速率、链路是否 UP | ip link、ethtool |
| 网络层(IP) | 连通性、丢包、延迟、路由 | ping、traceroute、mtr、ip route |
| 传输层(端口) | 端口是否监听、防火墙是否放行 | ss、nc、telnet、iptables |
| 应用层 | HTTP 响应、DNS 解析 | curl、dig、nslookup、tcpdump |
动手之前,先确认基础信息:
# 查看网卡状态与 IP(重点看 state UP 与 inet 地址) ip addr show ip link show # 查看默认路由是否正常 ip route show # 查看网卡速率与协商模式 ethtool eth0
网卡都处于 DOWN 或者没有获取到 IP 时,后面所有排查都没有意义,这一步务必放在最前面。
二、ping 详解:连通性、丢包率与 RTT 延迟
ping 基于 ICMP 协议,是检查"目标是否可达"最直接的工具。基本用法:
# 指定次数与间隔,适合测试丢包 ping -c 10 -i 0.2 1.1.1.1 # 不解析域名,输出更快更干净 ping -n -c 10 8.8.8.8 # 指定包大小,用于测试 MTU 相关问题(见案例 4) ping -M do -s 1472 8.8.8.8 # 每秒输出统计汇总 ping -q -c 100 1.1.1.1
正常的输出长这样:
64 bytes from 1.1.1.1: icmp_seq=1 ttl=57 time=12.3 ms 64 bytes from 1.1.1.1: icmp_seq=2 ttl=57 time=12.1 ms --- 1.1.1.1 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1002ms rtt min/avg/max/mdev = 12.102/12.200/12.300/0.098 ms
判断要点:
- 丢包率:0% 为正常;高于 1% 说明链路不稳定,需要结合 mtr 定位丢包节点。
- TTL 变化:Windows 初始 TTL 为 128、Linux 为 64,用 255 减去回包 TTL 可大致推断经过的路由跳数。
- time 波动(mdev):平均延迟低但波动大,通常是链路拥塞或带宽被限速。
另外,很多云厂商默认在安全组中禁用了 ICMP,导致 ping 不通但网站正常。遇到这种情况先确认目标主机是否真的禁 ICMP:
# 允许本机回应 ICMP(部分系统默认值) sysctl net.ipv4.icmp_echo_ignore_all # 输出 0 表示允许回应,1 表示忽略所有 ping # 临时关闭"忽略 ping" echo 0 > /proc/sys/net/ipv4/icmp_echo_ignore_all # 永久生效写入 /etc/sysctl.conf echo "net.ipv4.icmp_echo_ignore_all = 0" >> /etc/sysctl.conf sysctl -p
三、traceroute 路由追踪:定位故障节点
ping 只能告诉你"通不通",traceroute 能告诉你"走到哪一跳断的"。它利用 TTL 逐跳递增的原理,让沿途路由器逐个回 ICMP 超时报文:
# 不解析主机名,速度更快 traceroute -n -w 1 8.8.8.8 # 使用 TCP 探测(很多路由器/防火墙丢弃 UDP 报文,用 -T 更可靠) traceroute -T -p 443 -n www.baidu.com # 使用 ICMP 探测 traceroute -I -n 8.8.8.8
输出示例:
1 192.168.1.1 1.2 ms 1.1 ms 1.1 ms 2 10.0.0.1 3.0 ms 3.1 ms 2.9 ms 3 * * * ← 该跳不回 ICMP,正常 4 61.144.1.2 15.2 ms 15.5 ms 15.1 ms 5 8.8.8.8 12.0 ms 12.3 ms 12.2 ms
判断要点:
- 中间某跳显示 * * * 不一定是故障,很多骨干路由器不回 ICMP;只要最终能到达目标且延迟可接受就正常。
- 若从第 N 跳开始全部 * * * 且最终无法到达,说明故障点在第 N 跳附近(路由器丢弃、线路中断或 BGP 路由问题)。
- 注意观察 延迟突增的那一跳,跨地域/跨运营商骨干节点延迟升高属于正常现象。
四、mtr:持续探测丢包与抖动的组合拳
mtr 结合了 ping 和 traceroute,能持续统计每一跳的丢包率与延迟,是定位"丢包发生在哪一跳"的最强工具。Debian/Ubuntu 安装:
apt update && apt install -y mtr # CentOS/RHEL yum install -y mtr
运行并观察:
mtr -r -c 100 -n 8.8.8.8 HOST: vps Loss% Snt Last Avg Best Wrst StDev 1.|-- 192.168.1.1 0.0% 100 1.1 1.2 0.9 2.1 0.2 2.|-- 100.64.0.1 0.0% 100 3.0 3.1 2.8 3.9 0.3 3.|-- 61.144.1.2 80.0% 100 15.0 15.4 14.8 16.2 0.5 ← 丢包源头 4.|-- 202.97.1.2 0.0% 100 12.0 12.2 11.8 13.0 0.3 5.|-- 8.8.8.8 80.0% 100 12.3 12.5 12.1 13.2 0.4 ← 之后全部丢包
判断要点:
- 如果只有某一条中间路由丢包,但后面的节点不丢,通常只是该路由器对 ICMP 限速,属于正常现象。
- 如果从第 N 跳开始之后所有跳都丢包,说明第 N 跳就是故障节点:常见原因是该路由器 ICMP 被丢弃、链路拥塞、或被运营商 QoS 限速。
- 云 VPS 遇到"国际线路丢包",多半是跨海骨干链路拥塞,可考虑 BBR 加速或换 CN2/GIA 线路。
五、dig/nslookup:DNS 解析排错
网站打不开但 IP 能 ping 通,八成是 DNS 问题。dig 是排查 DNS 的瑞士军刀,先看系统自带的 DNS 服务器配置:
# 查看本机 DNS 配置(含 systemd-resolved 时代) cat /etc/resolv.conf # 使用指定 DNS 服务器解析,绕过系统缓存 dig @8.8.8.8 www.example.com A dig @223.5.5.5 www.example.com +short # 查看完整解析链路 dig www.example.com +trace # 查看其他记录类型 dig example.com MX dig example.com NS dig example.com CNAME
典型输出与判断:
$ dig @8.8.8.8 www.example.com +short 203.0.113.10 # 解析失败时输出类似: ;; connection timed out; no servers could be reached
常见 DNS 故障与处理:
- 解析超时:本机配置的 DNS 不可达,换成 223.5.5.5(阿里)或 119.29.29.29(腾讯)并写入
/etc/resolv.conf。 - 解析到旧 IP:本地缓存问题,重启 DNS 缓存服务:
systemctl restart systemd-resolved。 - 域名有 A 记录但解析不到:检查域名 NS 是否被恶意篡改,用
dig +trace从根服务器逐级核对。 - IPv6 干扰:服务器只配了 IPv4,但解析返回 AAAA 记录导致连接卡顿,可用
sysctl -w net.ipv6.conf.all.disable_ipv6=1关闭 IPv6。
六、ss 与 curl:端口连通性与 HTTP 层检查
IP 通了、DNS 也正常,但服务还是连不上,就要查端口。ss 用于检查本机监听状态:
# 查看所有监听端口及对应进程 ss -tlnp # 只看 80/443 是否被监听 ss -tlnp | grep -E ':80|:443' # 查看建立中的连接数(排查攻击/连接数打满) ss -tan state established | wc -l # 查看 TIME_WAIT 数量 ss -tan state time-wait | wc -l
远程测试端口连通性(本机没有 nc 时用 bash 自带 /dev/tcp):
# nc 测试 nc -vz -w 3 8.8.8.8 443 # bash 方式 timeout 3 bash -c 'echo > /dev/tcp/8.8.8.8/443' && echo "端口开放" || echo "端口不通"
curl 检查 HTTP 层响应,重点看状态码与耗时:
# 查看响应头,重点看 HTTP 状态码与 Server
curl -I -m 10 https://www.example.com
# 分段统计耗时,定位是连接慢还是传输慢
curl -o /dev/null -s -w \
'DNS: %{time_namelookup}s\nTCP连接: %{time_connect}s\nTLS握手: %{time_appconnect}s\n首字节: %{time_starttransfer}s\n总耗时: %{time_total}s\nHTTP状态码: %{http_code}\n' \
https://www.example.com
# 指定解析 IP,绕过 DNS 直接测试
curl -H "Host: www.example.com" --resolve www.example.com:443:203.0.113.10 -I https://www.example.com
当 curl 本机正常、远程超时时,99% 是云安全组或 iptables 未放行该端口,而不是应用本身的问题。
七、tcpdump 抓包分析:让数据说话
前面所有工具都是"间接推断",tcpdump 直接抓取网卡上的数据包,能看到请求到底有没有发出去、有没有收到回应。基础用法:
# 抓取 eth0 上发往 8.8.8.8 的包,不解析域名,打印 20 个 tcpdump -i eth0 -nn -c 20 host 8.8.8.8 # 抓 80 端口流量并保存到文件(之后用 tcpdump 或 wireshark 分析) tcpdump -i eth0 -nn -s 0 -w /tmp/http.pcap port 80 # 抓 SYN 包,判断 TCP 三次握手是否完成 tcpdump -i eth0 -nn 'tcp[tcpflags] & tcp-syn != 0' # 抓 ICMP 包,验证 ping 是否发出/收到 tcpdump -i eth0 -nn icmp # 配合 -c 自动退出,适合一次性排查 tcpdump -i eth0 -nn -c 50 'tcp port 22'
排错实战:本地 curl 一直超时,用 tcpdump 一抓便知真相——
$ curl -v -m 5 http://203.0.113.10/ & $ tcpdump -i eth0 -nn -c 30 host 203.0.113.10 22:01:05.123456 IP 1.2.3.4.52341 > 203.0.113.10.80: Flags [S], seq 1000... 22:01:05.123789 IP 203.0.113.10.80 > 1.2.3.4.52341: Flags [S.], seq 2000, ack 1001... 22:01:05.123850 IP 1.2.3.4.52341 > 203.0.113.10.80: Flags [.], ack 2001... ← 三次握手完成 # 如果只看到 SYN 没有回包,说明目标端口未监听或被防火墙丢弃 # 如果看到 RST(Reset),说明端口有服务但被主动拒绝
判断要点:
- 只发 SYN 无回包 → 丢包或被防火墙 DROP,检查安全组/iptables。
- 收到 RST → 端口有进程但主动拒绝,检查服务配置或防火墙 REJECT。
- 有握手但 无 HTTP 数据 → 应用层问题(PHP-FPM 卡死、后端超时等)。
八、常见故障案例与排错手册
案例 1:外网 ping 不通,但网站正常访问
现象:本地 ping VPS 丢 100%,但浏览器能打开网站。
原因:云服务商安全组默认禁 ICMP,或系统设置了 icmp_echo_ignore_all=1。
解决:在云控制台安全组放行 ICMP 协议;服务器侧按第二节方法检查 sysctl。
案例 2:SSH 时断时续、丢包率忽高忽低
现象:mtr 显示国内某跳之后大面积丢包。
原因:跨运营商骨干链路拥塞,或被云厂商 QoS 限速(出网带宽打满)。
解决:先用 vnstat / iftop 确认不是本机带宽被打满;若不是,则属线路问题,可尝试开启 BBR、更换线路(CN2 GIA)或使用中转。
案例 3:DNS 解析超时,网站报"无法解析服务器地址"
现象:dig @8.8.8.8 正常,但系统默认解析超时。
原因:/etc/resolv.conf 被覆盖为不可达的 DNS,或 systemd-resolved 缓存异常。
解决:
# 直接指定公共 DNS 测试 echo -e "nameserver 223.5.5.5\nnameserver 119.29.29.29" > /etc/resolv.conf # 若为 systemd-resolved 管理,改用: systemctl restart systemd-resolved resolvectl dns eth0 223.5.5.5 119.29.29.29
案例 4:MTU 过大导致 SSH 卡顿、网页打不开
现象:SSH 能连上但一执行命令就卡死,ping -M do -s 1472 失败(PMTU 黑洞)。
原因:VPS 走隧道/IPSec 时实际 MTU 小于 1500,大包被静默丢弃。
解决:把网卡 MTU 降到 1450 或 1400 试到不丢包为止:
# 临时修改 ip link set eth0 mtu 1450 # 永久修改(Netplan 示例,Ubuntu 20.04+) # /etc/netplan/01-netcfg.yaml # ethernets: # eth0: # mtu: 1450 netplan apply # 或写入 /etc/network/interfaces(Debian) # auto eth0 # mtu 1450
案例 5:端口不通但防火墙已放行
现象:iptables 已放行 8080,但远程仍连不上。
原因:服务只监听了 127.0.0.1(本机回环),未监听 0.0.0.0。
解决:
# 确认监听地址 ss -tlnp | grep 8080 # 输出 127.0.0.1:8080 即只监听本机,需把配置里的 listen 改为 0.0.0.0:8080 # 同时检查云控制台安全组是否放行该端口
九、附:网络排错速查命令清单
# 一网打尽,按顺序执行即可覆盖绝大多数场景 ip addr && ip route # 网卡与路由 ping -c 10 8.8.8.8 # 基础连通性 mtr -r -c 50 -n 8.8.8.8 # 丢包定位 dig @223.5.5.5 example.com # DNS 解析 ss -tlnp # 监听端口 curl -vI -m 5 https://example.com # HTTP 层 tcpdump -i eth0 -nn -c 100 host 8.8.8.8 # 抓包兜底
最后提醒:排错时要先改一个变量、再观察一个结果,不要同时动防火墙、DNS 和网卡配置。把上面这些命令用熟,90% 的 VPS 网络问题都能在十分钟内定位到根因。



