Ubuntu服务器出现异常流量时,最先反映出来的往往不是带宽被占满,而是CPU负载异常、进程莫名占用网络端口、或者日志里出现大量重复请求。排查的第一步不是急着装工具,而是先确认当前网络连接状态。执行 ss -tunap 可以列出所有TCP和UDP连接,重点看State列里SYN_RECV和ESTAB两个状态的数量。如果SYN_RECV数量异常高,基本可以判断服务器正在遭受SYN Flood攻击;如果ESTAB连接里有大量来自同一IP或同一网段的连接,而且本地端口集中在80、443或某个不常用的端口上,那就要立刻进入下一步分析。
用netstat和ss快速定位异常连接ss命令比netstat更快,但netstat的输出格式对新手更友好。建议两个命令配合使用。执行 netstat -ntu | awk '{print $5}' | cut -d: -f1 | sort | uniq -c | sort -nr | head -20 这条命令会统计当前连接数最多的前20个IP地址。如果某个IP的连接数明显超过正常范围,比如超过50个并发连接,就需要重点关注。同时执行 netstat -ntu | awk '{print $4}' | cut -d: -f2 | sort | uniq -c | sort -nr | head -10 可以统计哪些本地端口被频繁访问。如果发现一个平时不对外提供服务的端口突然出现大量连接,那很可能是被扫描或者被植入了后门程序。
通过iftop和nethogs观察实时流量ss和netstat只能看连接快照,看不到实时流量。安装iftop后执行 iftop -i eth0 -P 可以实时显示每个IP的流入流出速率。iftop的界面里,左右两列数字分别代表不同方向的流量,中间显示的是连接双方的IP和端口。观察时重点找那些持续高流量但业务上不应该有大量数据传输的IP对。如果发现某个IP持续以几MB/s的速度从服务器拉取数据,而服务器上并没有提供大文件下载服务,那就要立刻检查这个IP对应的进程。nethogs比iftop更直接,执行 nethogs eth0 可以直接看到是哪个进程在占用网络带宽。这个工具对发现挖矿木马或者被植入的流量代理程序特别有效。
分析Nginx或Apache访问日志中的异常模式如果服务器上运行着Web服务,访问日志是排查异常流量的核心数据源。Nginx默认日志路径在 /var/log/nginx/access.log,Apache在 /var/log/apache2/access.log。执行 awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -20 可以找出访问最频繁的IP。但光看IP数量不够,还要结合请求路径和状态码。执行 awk '{print $1,$7,$9}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -50 可以看到具体是哪些IP在请求哪些URL以及返回了什么状态码。如果某个IP在短时间内大量请求同一个URL且返回404或502,那很可能是扫描器或者CC攻击。如果某个IP大量请求登录接口且返回200,那可能是撞库攻击。
用tcpdump抓包分析可疑流量内容当连接和日志分析都无法确定异常原因时,就需要抓包看流量内容了。执行 tcpdump -i eth0 -nn -s0 -c 1000 -w /tmp/traffic.pcap 可以抓取1000个包保存到文件。如果只想抓某个可疑IP的流量,加上host过滤条件: tcpdump -i eth0 -nn -s0 host 192.168.1.100 -w /tmp/suspicious.pcap 。抓包后用 tcpdump -r /tmp/traffic.pcap -nn | head -50 查看包内容摘要。重点看协议类型、端口号、以及数据包的长度。如果发现大量UDP包发往不常见的端口,或者TCP包的数据部分包含非正常协议特征,那就要进一步分析。对于加密流量,tcpdump看不到内容,但可以通过包大小和发送频率判断行为模式。比如挖矿木马通常会定期向矿池服务器发送固定大小的数据包。
检查系统进程和计划任务中的可疑项异常流量背后一定有对应的进程在运行。执行 ps aux --sort=-%cpu | head -20 查看CPU占用最高的进程,执行 ps aux --sort=-%mem | head -20 查看内存占用最高的进程。重点关注那些进程名看起来正常但路径不正常的,比如一个名为nginx的进程却运行在/tmp目录下。执行 ls -l /proc/PID/exe 可以查看进程的真实可执行文件路径。同时检查crontab: crontab -l 查看当前用户计划任务, ls -la /etc/cron.* 查看系统级计划任务。很多挖矿木马会通过计划任务实现持久化,每隔一段时间重新下载执行恶意程序。还要检查 /etc/init.d/ 和 /etc/systemd/system/ 下是否有可疑的服务文件。
用lsof追踪进程的网络行为lsof是排查进程网络行为的利器。执行 lsof -i -P -n 可以列出所有打开网络连接的进程。输出中COMMAND列是进程名,PID是进程号,USER是运行用户,FD列显示文件描述符类型,TYPE列显示协议类型。如果发现某个进程打开了大量网络连接,执行 lsof -p PID -i 可以只看这个进程的网络连接。再执行 lsof -p PID 可以看到这个进程打开的所有文件,包括它正在读取的配置文件、日志文件、以及可能存在的恶意载荷文件。lsof还能帮助发现那些通过unix socket进行本地通信的可疑进程,这类进程往往不会在netstat中显示网络连接,但可能在偷偷传输数据。
分析系统日志中的认证失败和异常登录异常流量很多时候与暴力破解和未授权访问有关。Ubuntu的认证日志在 /var/log/auth.log。执行 grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -nr | head -20 可以统计尝试暴力破解SSH的IP来源。如果某个IP尝试了上百次密码失败,那这个IP基本可以确定是恶意的。执行 grep "Accepted" /var/log/auth.log | tail -20 查看最近成功登录的记录,确认是否有来自陌生IP的成功登录。如果发现一个不应该有登录权限的IP成功登录了,那服务器很可能已经被入侵。同时检查 /var/log/syslog 中是否有频繁的服务重启记录,有些攻击会导致服务崩溃并自动重启。
使用vnstat和sar分析历史流量趋势实时工具只能看到当前状态,要判断流量异常是从什么时候开始的,需要历史数据。vnstat是一个轻量级的流量统计工具,安装后会自动记录每天每月的流量数据。执行 vnstat -d 查看每日流量统计,执行 vnstat -h 查看每小时流量统计。如果发现某天的流量突然比平时高出数倍,那就可以把排查重点放在那一天的日志和连接记录上。sar命令可以查看历史网络活动,执行 sar -n DEV -f /var/log/sysstat/saXX 查看某天的网络接口统计。sar的输出包含rxpck/s、txpck/s、rxkB/s、txkB/s等指标,如果发现某个时间段内数据包数量异常增加但流量大小没有明显变化,那可能是小包攻击或扫描行为。
配置iptables临时封禁和限速在确认了可疑IP后,需要立即采取措施阻止异常流量。执行 iptables -I INPUT -s 可疑IP -j DROP 可以封禁单个IP。如果要封禁整个网段,执行 iptables -I INPUT -s 可疑网段/24 -j DROP 。对于CC攻击,单纯封禁IP可能不够,因为攻击源可能不断变化。这时可以使用limit模块进行限速: iptables -I INPUT -p tcp --dport 80 -m connlimit --connlimit-above 50 -j DROP 限制单个IP的并发连接数不超过50个。执行 iptables -I INPUT -p tcp --dport 80 -m limit --limit 100/s --limit-burst 200 -j ACCEPT 可以限制每秒新建连接数。这些规则重启后会失效,所以需要同时写入 /etc/iptables/rules.v4 文件持久化。
用fail2ban实现自动化防护手动封禁IP效率太低,fail2ban可以自动监控日志并在发现异常时自动封禁。安装后编辑 /etc/fail2ban/jail.local 配置文件,在[sshd]部分设置 maxretry = 3 表示SSH密码错误3次就封禁,bantime = 3600 表示封禁1小时。对于Nginx,可以添加自定义规则监控访问日志中的异常请求。配置完成后执行 systemctl restart fail2ban 生效。执行 fail2ban-client status 查看所有监控的监狱,执行 fail2ban-client status sshd 查看SSH监狱的封禁情况。fail2ban不仅能封禁暴力破解,还能通过自定义正则表达式封禁扫描器、CC攻击源等。但要注意fail2ban本身也会消耗资源,如果攻击规模很大,fail2ban的封禁列表可能变得非常庞大。
检查DNS流量和外部连接目标很多恶意程序会通过DNS查询与外部控制服务器通信。执行 tcpdump -i eth0 -nn port 53 可以抓取所有DNS查询。如果发现服务器在频繁查询一些奇怪的域名,特别是那些域名看起来像随机生成的字符串,那很可能是恶意程序在尝试连接C2服务器。执行 cat /etc/resolv.conf 检查DNS服务器配置是否被篡改。有些攻击者会修改DNS设置,将服务器的DNS查询重定向到恶意服务器。同时检查 /etc/hosts 文件是否有可疑的域名映射。执行 dig 可疑域名 可以查看域名解析结果,如果解析到的IP与已知的恶意IP库匹配,那就可以确认服务器已经被感染。
使用auditd审计关键系统调用当常规排查手段都无法定位异常流量的来源时,需要启用系统调用审计。安装auditd后,执行 auditctl -w /etc/passwd -p wa -k passwd_changes 监控密码文件的修改,执行 auditctl -w /tmp -p x -k tmp_exec 监控/tmp目录下的可执行文件。执行 auditctl -a always,exit -F arch=b64 -S connect -k network_connect 可以记录所有网络连接系统调用,包括发起连接的进程、目标IP和端口。审计日志在 /var/log/audit/audit.log,执行 ausearch -k network_connect -ts today 可以查看今天所有的网络连接记录。通过审计日志可以精确定位是哪个进程在什么时间发起了异常网络连接,即使这个进程只运行了很短时间就退出了,审计日志中也会留下记录。
检查内核模块和rootkit迹象高级攻击者会通过内核模块隐藏恶意进程和网络连接。执行 lsmod 查看当前加载的内核模块,重点检查是否有来源不明或名称可疑的模块。执行 dmesg | grep -i "taint" 查看内核是否被标记为tainted状态。执行 chkrootkit 和 rkhunter 可以扫描常见的rootkit特征。但要注意这两个工具只能检测已知的rootkit,对于定制化的恶意内核模块可能无能为力。如果怀疑内核被篡改,最可靠的方法是将当前内核与已知干净的内核文件进行哈希比对。执行 sha256sum /boot/vmlinuz-$(uname -r) 然后与官方源中的哈希值对比。如果哈希不一致,说明内核文件被修改过,需要立即从可信源重新安装内核。
建立长期流量基线监控排查完当前异常后,更重要的是建立长期的流量监控体系,以便下次异常发生时能够快速定位。安装Prometheus和Grafana,配合node_exporter可以监控服务器的网络流量、CPU、内存、磁盘等指标。在Grafana中创建仪表盘,设置网络流量告警阈值,当流量超过正常水平的150%时自动发送告警。同时配置日志集中收集,使用rsyslog或filebeat将系统日志和Web日志发送到集中的日志服务器。这样即使攻击者清除了本地日志,集中存储的日志仍然可以用于分析。对于关键服务器,建议每天定时执行连接数统计和异常IP检测脚本,将结果保存到文件或发送到监控平台。
总结排查思路和优先级Ubuntu服务器异常流量排查应该遵循从外到内、从快到慢的原则。先用ss和netstat看连接快照,再用iftop和nethogs看实时流量,然后分析Web日志找异常请求模式,必要时用tcpdump抓包分析内容。同时检查进程、计划任务、系统日志,确认是否有恶意程序在运行。确认可疑IP后立即用iptables封禁,并配置fail2ban实现自动化防护。对于无法定位的异常,启用auditd审计系统调用。排查完成后建立长期监控体系,避免下次再陷入被动。整个过程中要注意保留证据,包括日志文件、抓包文件、进程列表等,这些证据对于后续的安全分析和溯源非常重要。
