带宽跑满排查:用 iftop 与 nethogs 定位异常流量来源

服务器带宽突然被吃满,网站打开缓慢、SSH 卡顿甚至远程连不上,这是很多站长都遇到过的紧急状况。这篇文章如何帮你解决:我们会给你一套从”总带宽异常”到”具体进程/连接”的排查路径,用 iftop(实时按连接统计流量的命令行工具)和 nethogs(按进程统计流量的命令行工具)快速定位异常流量的真实来源,并区分正常业务高峰、爬虫抓取和恶意外联三种情况,避免凭感觉重启服务器却让问题反复出现。

排查的核心思路是三层收敛:先确认带宽确实跑满,再定位是哪些连接在传输,最后归因到具体进程和业务。很多排查失败的原因是跳过第一层直接看进程,结果在几十个进程里无从下手。下面我们按这个顺序展开。

第一步:确认带宽真的跑满了

在动手之前,先拿到客观数据。登录服务器后,先看网卡的实时速率:

# 每秒刷新一次网卡流量,观察接收与发送速率
sar -n DEV 1 5

关注 rxKB/s 和 txKB/s 两列。假设你购买的是 100Mbps(兆比特每秒)带宽,理论吞吐上限约 12.5MB/s,换算成 KB/s 大约是 12800。如果 txKB/s 长期贴近这个数值,说明出站带宽确实跑满;如果是 rxKB/s 高,则是入站方向异常。

另一个常用的确认工具是 vnstat,它适合看趋势而不是瞬时值:

# 查看当天的每小时流量分布
vnstat -d
vnstat -h

如果历史数据显示最近 24 小时流量比平时高出 5 到 10 倍,且增长起点明确(比如凌晨 3 点突然开始),这就是典型的异常信号;如果是随业务时间平滑上涨,则更可能是正常业务增长或被爬虫持续抓取。

这一步的输出决定后续方向:确认跑满后,就要进入连接级定位。

带宽跑满排查思路示意:从网卡总流量到连接再到进程的三层收敛

第二步:用 iftop 找到占用带宽的连接

iftop 的价值在于把网卡流量拆到每一条 TCP/UDP 连接,让你直接看到”谁在和服务器说话”。安装并启动:

# Debian/Ubuntu
apt install iftop -y
# CentOS/AlmaLinux
yum install epel-release -y && yum install iftop -y

# 监听 eth0 网卡,直接显示 IP 不做反向解析(避免 DNS 查询拖慢刷新)
iftop -i eth0 -n -P

三个参数是关键:-i 指定流量最大的网卡(用 sar 输出里最高的那个接口名);-n 禁止域名反查,否则每行刷新都会先做一次 DNS(域名解析系统)查询,在高流量时界面会卡住;-P 显示端口,没有端口就无法判断流量属于网站、数据库还是别的服务。

进入界面后,重点看屏幕中间的连接列表,按 T 键切换为累计流量排序,观察发送(<= 方向)最大的前几条连接。常见的三种模式:

  • 目标端口是 443/80,且对端 IP 数量成百上千:像是正常网站流量或大规模爬虫抓取。
  • 单个陌生 IP 独占大部分出站流量,端口随机:高度可疑,可能是数据外泄或被当作跳板。
  • 对端全部是内网 IP(10.x / 172.16-31.x / 192.168.x):数据库同步、备份任务等内部传输,结合时间点判断是否是计划内任务。

想把现场数据保留下来给同事或服务商分析,可以用文本模式输出:

# 输出 10 行、每 2 秒刷新一次的文本结果
iftop -i eth0 -n -P -t -s 10 > /tmp/iftop-snapshot.txt

拿到可疑 IP 列表后,下一步就是回答”是哪个进程在跟这些 IP 通信”。

iftop 连接级流量视图:橙色连接条占据大部分带宽

第三步:用 nethogs 把连接归因到进程

iftop 告诉你”哪条连接”,nethogs 告诉你”哪个进程”。两个工具的视角互补,缺一不可:

# Debian/Ubuntu
apt install nethogs -y
# CentOS/AlmaLinux
yum install epel-release -y && yum install nethogs -y

# 每 1 秒刷新,监听 eth0
nethogs eth0 -d 1

nethogs 的输出按进程排列,包含 PID、用户、发送和接收速率。按 m 键可以循环切换显示模式(速率 / 累计流量 / 总量),排查持续性问题建议看累计模式,避免瞬时波动误导判断。

如果发现某个不认识的进程(比如随机命名的二进制文件、位于 /tmp 下的可执行文件)占据了绝大部分流量,先确认它的真身再处理:

# 查看进程详情:启动命令、运行路径、父进程
ls -l /proc/<PID>/exe
cat /proc/<PID>/cmdline | tr '\0' ' '; echo
ps -o pid,ppid,user,lstart,cmd -p <PID>

举一个真实场景:一台 WordPress 站点服务器凌晨带宽跑满,iftop 显示出站集中在与一个海外 IP 的随机高端口连接,nethogs 归因到一个位于 /tmp/.x/ 目录下的未知进程。这就是典型的挖矿或代理木马特征——处理顺序应该是先 kill <PID> 止血、再用 find /tmp -type f -executable 清理残留,最后改密钥、查入侵路径,而不是只重启了事。

反过来,如果 nethogs 显示占用流量的是 php-fpm、nginx 或 mysqldump 这类正常进程,说明流量来自业务本身,处理方式就完全不同——下一节我们按场景给出处置方案。

nethogs 进程归因:正常进程与可疑进程的流量线对比

三种典型场景的处置方式

定位到来源之后,按性质选择不同的处置路径,这比盲目重启有效得多。

场景一:正常业务高峰。 判断依据是流量集中在 443/80 端口、对端 IP 分散、时间与你的访问曲线吻合。这时的应对是容量规划而不是”堵”:检查流量是否已接近套餐上限,评估是否需要升级带宽。如果你的站点跑在 VPS(虚拟专用服务器)上且近期访问量明显增长,可以参考我们整理的 iperf3 带宽实测方法,先实测确认真实可用带宽再决定是否扩容。

场景二:爬虫或采集抓取。 表现为流量大但 CPU 不高、访问路径集中在同一批 URL。先在网站访问日志里统计 UA(User-Agent,浏览器标识字符串)和对端 IP 频次,确认是搜索引擎蜘蛛还是恶意采集器。对恶意抓取,用 nginx 的 limit_req 模块限速即可:limit_req_zone $binary_remote_addr zone=perip:10m rate=10r/s; 这行配置把单个 IP 限制在每秒 10 个请求,对正常用户几乎无感。

场景三:恶意外联或攻击。 即第二步和第三步里那些陌生 IP + 未知进程的组合。止血动作是立刻用防火墙断掉外联,例如 nftables 规则:nft add rule inet filter output ip daddr <可疑IP> drop。之后的取证与加固属于安全事件流程,可以参考服务器遭受 CC 攻击后的应急处理和 DDoS 攻击应急响应指南,那里有完整的 WAF(Web 应用防火墙)与高防接入步骤。

iftop 与 nethogs 的分工对比

两个工具经常被混用,但它们的定位完全不同。选错工具会浪费宝贵的排查时间:

维度 iftop nethogs
统计单元 单条连接(IP + 端口) 进程(PID)
回答的问题 谁在和服务器通信 服务器上哪个程序在通信
适合场景 判断流量方向、找可疑 IP 归因到业务进程或恶意程序
局限 看不到进程名 看不到对端 IP 分布

我们的建议是把 iftop 作为第一入口(先看方向和对象),nethogs 作为第二入口(再定责任进程),两者交叉验证。如果需要更长期的监控而不是单次排查,可以部署 Netdata 实时监控,把带宽异常从”事后排查”变成”实时告警”;告警规则的接入方式见服务器监控告警配置实践。

还有一个容易踩的坑值得提醒:如果你的服务器前面有 CDN(内容分发网络)回源架构,iftop 看到的入站流量可能全部来自 CDN 节点,出站流量才是回源请求。这种拓扑下不要误判为”被大量 IP 扫描”,应该结合回源日志和缓存命中率一起看,相关结构可以参考多层缓存架构设计。

日常预防与总结

排查只能解决这一次,要让带宽问题不再反复发生,建议把下面几件事固化下来:

  • 用 vnstat 做每日流量基线记录,偏离基线 50% 以上时告警,能提前数小时发现异常。
  • 每月检查一次 /tmp、/dev/shm 下是否有可执行文件,挖矿木马最常藏在这些目录。
  • 定时任务(备份、同步)尽量安排在业务低谷时段,并用 ionice/tc 限制其带宽占用。
  • 对外暴露的端口只保留必要服务,在云服务器防火墙配置指南中有按发行版整理的规则模板。

总结一下完整路径:sar 确认带宽跑满 → iftop -n -P 找到可疑连接 → nethogs 归因到进程 → 按业务高峰、爬虫、恶意行为三种场景分别处置。整个流程通常 10 分钟内可以完成定位,关键在于按层收敛、不跳步。

如果你需要一台带宽质量透明、流量计费清晰的服务器,我们建议在选购阶段就把带宽类型(独享/共享)、月流量额度和超出策略问清楚。Hostease 的 VPS 主机与独立服务器都提供明确的带宽规格说明,配合本文的排查方法,你可以随时验证实际到手带宽是否符合承诺。

发表评论