服务器流量突增,进程查不到来源,最后靠它搞定了。
前两天公司内网一台服务器突然流量飙升,监控系统报警不停。我上去看了下,CPU和内存都正常,但网卡收发数据特别猛。这就不对劲了,一般这种问题不是DDoS就是内部有程序在偷偷传数据。可top、htop、ps都看了一遍,没发现可疑进程。总不能是黑客进来了吧?心有点慌,但还得查。
后来想到,直接看系统资源找不到源头,那就只能抓包看网络流量到底是谁在通信了。Linux下最常用的抓包工具就是tcpdump,虽然之前用得不多,但这时候也只能硬着头皮上了。先确认下有没有装这个命令,输入`tcpdump -h`,发现能出协助说明,还好系统自带了。
第一步是看看都有哪些网卡可以用。输入`tcpdump -D`,列出了当前机器的所有网络接口,列如ens192、lo这些。我们的服务跑在ens192上,所以接下来就盯这个口。为了不被dns解析卡住,还得加上`-n`参数,不然每抓一个包都去反查ip,速度慢还可能干扰结果。
然后试着抓一下所有流量,命令是`sudo tcpdump -i ens192 -n`。屏幕上刷刷地往外蹦数据,一大堆IP和端口号来回通信。根本看不出重点。这时候就得靠过滤条件了。列如我想看是不是有人在扫端口,可以加个`port 22`或者`port 80`来缩小范围。但这次问题是流量大,估计是批量传输,可能是udp或者某个特定协议在作怪。

我先试着抓icmp包看看有没有人在ping flood,命令是`tcpdump -i ens192 -n icmp`,跑了十秒没啥异常。再试udp,`tcpdump -i ens192 udp`,结果一下子出来了好多包,源IP是我们内网另一台开发机,目标端口是53,这不就是DNS查询吗?
顺着这条线索继续深挖。开发机不应该往生产服务器发这么多DNS请求啊。于是改用更详细的命令:`tcpdump -i ens192 -nn -c 20 udp port 53`,抓20个包看看内容。果然,全是从那台开发机发来的域名解析请求,问的还都是些乱七八糟的域名,像ads.google.com、tracking-api.com这种。
基本能判断是开发那边跑了个程序,在做批量爬虫或者广告追踪之类的任务,结果配置错了DNS服务器,把请求全都打到我们这台生产机上了。这台机器恰好开了dnsmasq做内网解析,就默默扛下了所有请求,导致负载上升。
找到缘由后就好办了。联系开发同事改了配置,把DNS指向正确的测试服务器。再观察几分钟,流量很快就恢复正常了。整个过程从发现问题到定位,前后不到一个小时,tcpdump算是立了大功。

实则这工具功能挺多的。列如你可以只抓某一个IP的包,命令是`host 172.16.1.100`;也可以抓特定端口,像`port 80`就是HTTP流量;还能组合条件,列如“来自某个IP且目标端口是443”的包:`src host 172.16.1.100 and dst port 443`。要是想保存下来慢慢分析,就用`-w 文件名.pcap`,之后拿wireshark打开看也行。
有一次我还用它抓过HTTP里的Cookie。命令稍微复杂点:`tcpdump -i ens192 -nn -A -s0 -l | egrep -i 'Set-Cookie|Host:|Cookie:'`,这样就能实时看到哪些请求带了Cookie信息。虽然目前大部分都是HTTPS了,看不到明文,但在调试内部系统时还是很有用。
还有次排查邮件发送失败的问题,用了`port 25`抓SMTP包,配合`grep 'MAIL FROM'`直接看到了应用发出的邮件指令,很快发现是认证字段拼错了。如果不是靠抓包,光看日志根本查不出来。
这工具也不是一开始就会用的。刚开始我也常常忘加`-n`,结果抓包时自己产生的dns请求又触发新的包,越抓越多,差点把自己绕进去。后来才清楚,实战中最重大的不是懂多少参数,而是知道怎么一步步缩小范围,从海量数据里揪出关键线索。

它还能检测端口扫描行为。列如有人在用nmap扫你,就会看到一堆SYN包发到不同端口,用`tcpdump -i any 'tcp[tcpflags] == tcp-syn'`就能捕获这类扫描行为。虽然真正的安全防护不能只靠这个,但至少能第一时间知道有人在试探你。
最实用的一个技巧是抓包存文件。有时候问题不是立刻能解决的,就得先把数据留下来。`-w /tmp/debug.pcap`几句话的事,后面随时可以用`-r /tmp/debug.pcap`回放分析。配合wireshark图形界面,连产品经理都能看懂。
用惯了就觉得,这东西就像是网络世界的行车记录仪。平时感觉不到它的存在,等真出问题了,它能告知你到底发生了什么。不像有些监控只给个数字,tcpdump直接给你看原始证据。
不过也得提醒一句,抓包要小心权限和范围。默认监听的网卡可能不对,有时候得指定`-i any`才能抓全。而且普通用户不能直接运行,得sudo,否则会提示没权限。另外,长时间抓包文件会很大,最好加上`-C`按大小切分,或者`-G`按时长轮转。

有一次我忘了限制数量,直接`tcpdump -w log.pcap`跑后台,一不小心把磁盘写满了。还好是测试机,不然就麻烦了。所以目前养成习惯,要么加`-c`限制包数,要么加`-s0`控制单包大小,避免拖垮系统。






收藏了,感谢分享