[AI] SolusVM 异常 tc 限速排查与解决思路

SolusVM 异常 tc 限速排查与解决思路

本文档记录了排查 SolusVM 节点机上不明进程持续下发 tc (Traffic Control) 1Mbit 限速规则的完整思路,重点介绍了如何利用 Linux auditd 审计系统进行溯源。

1. 现象确认与目标设定

背景: 节点机上不断出现针对 KVM 虚拟网卡 (如 kvm1234.0) 的 1Mbit tc 限速规则。为了维持网络正常,用户编写了一个 /root/fix_tc.sh 脚本并放在 cron 中(甚至使用 sleep 实现了高频死循环)不断删除这些限速规则。

目标: 找出到底是哪个脚本或进程在不断地下发这些 tc 规则,并从根源上解决问题。

初步推断: 既然解除限速的脚本在不断地删除规则,说明下发限速的动作也是在频繁或者定期发生的,很可能是 SolusVM 内部的某个计划任务 (Cron Job) 触发的。

2. 核心溯源利器:auditd (Linux 审计守护进程)

当我们面对“系统里不知道谁在偷偷执行某个命令”这种问题时,auditd 是最强大的溯源工具。它可以监控文件访问、系统调用以及命令的执行,并记录下详细的上下文信息(包括是谁、在什么时间、作为哪个父进程的子进程执行了什么)。

2.1 寻找监控目标

首先,我们需要知道 tc 命令的绝对路径:

which tc
# 输出通常是 /usr/sbin/tc 或 /sbin/tc

2.2 配置 auditd 监控规则

我们需要让 auditd 监控对 /usr/sbin/tc 这个文件的执行操作 (x 权限)。

# -a always,exit: 每次系统调用退出时评估
# -F path=/usr/sbin/tc: 监控指定路径的文件
# -F perm=x: 监控执行权限
# -k tc_monitor: 给这条规则打个标签,方便搜索日志
auditctl -a always,exit -F path=/usr/sbin/tc -F perm=x -k tc_monitor

(注意:测试完成后,记得使用 auditctl -W tc_monitor 或者重启 auditd 服务来清理规则,避免日志爆炸。)

2.3 抓取与分析审计日志

等待片刻,让可疑脚本有时间触发 tc 命令。然后使用 ausearch 工具或者直接使用 grep 查看审计日志。

# 使用 ausearch 搜索带有 tc_monitor 标签的日志
ausearch -k tc_monitor -i | tail -n 50

# 或者直接在原始日志中抓取 (更适合复杂的 awk/sed 处理)
grep tc_monitor /var/log/audit/audit.log | tail -n 20

审计日志的一条典型记录如下 (SYSCALL 类型):

type=SYSCALL msg=audit(1778298713.063:87672): arch=c000003e syscall=59 success=yes exit=0 ... ppid=2955471 pid=2955625 ... comm="tc" exe="/usr/sbin/tc" subj=kernel key="tc_monitor" ...

关键信息提取:

  • exe="/usr/sbin/tc": 确认执行的是 tc 命令。
  • pid=2955625: 执行该 tc 命令的进程 ID。由于 tc 执行极快,这个进程通常在抓取到时已经消失。
  • ppid=2955471: 这是最关键的一环! 这是调用 tc 的父进程 ID (Parent PID)。

2.4 追踪父进程 (PPID)

我们提取出日志中出现频率最高的 PPID。如果这个 PPID 对应的进程还在运行,我们就可以直接使用 ps 命令看到它:

ps -fp <提取出的PPID>

在本次排查中,由于 PHP 脚本执行也相对较快,直接 ps 可能抓不到。但通过长期监控和关联,我们可以确认这些 PPID 源自 /usr/bin/php 进程。这印证了我们的猜想:是 SolusVM 的 PHP 定时任务在捣鬼。

3. 剥茧抽丝:控制变量法验证可疑脚本

确认是 PHP 脚本后,我们列出 SolusVM 在 /etc/cron.d/ 下可能相关的计划任务:

  • /etc/cron.d/solusvm_traffic_accounting_slv (包含 data_aggr.phpbw_setrules.php)
  • /etc/cron.d/solusvm_networkspeed (包含 trafficloader.php)

为了找出真凶,我们采用控制变量法进行手动验证:

步骤:

  1. 清理现场: 手动清空所有 KVM 网卡的 tc 规则。

    for dev in $(ls /sys/class/net | grep kvm); do tc qdisc del dev $dev root 2>/dev/null; done
    
  2. 执行嫌疑 A (data_aggr.php):

    php -d auto_prepend_file=none /usr/local/solusvm/includes/data_aggr.php
    
  3. 检查结果:

    for dev in $(ls /sys/class/net | grep kvm | head -n 5); do tc class show dev $dev; done
    

    结果:限速规则没有出现。嫌疑 A 排除。

  4. 重复上述步骤,测试嫌疑 B (bw_setrules.php)。 结果:嫌疑 B 排除。

  5. 执行嫌疑 C (trafficloader.php):

    php -d auto_prepend_file=none /usr/local/solusvm/includes/trafficloader.php --mode=all
    

    此时遇到分支:脚本提示 "Lock File Found. Traffic Shaping Disabled",规则未出现。

4. 关键突破:发现全局控制开关

Traffic Shaping Disabled 的提示表明系统存在一个全局开关。经过目录结构摸排,发现控制文件位于 /usr/local/solusvm/data/

  • traffic-enabled : 开启流量整形 (当前系统的状态)
  • traffic-disabled: 关闭流量整形

最终验证:

  1. 确保开关处于开启状态:
    rm -f /usr/local/solusvm/data/traffic-disabled
    touch /usr/local/solusvm/data/traffic-enabled
    
  2. 再次清理现场的 tc 规则。
  3. 再次执行嫌疑 C (trafficloader.php):
    执行瞬间,终端输出了大量关于配置 tc (sch_htb) 的系统警告。
  4. 最终确认: 再次检查网卡规则,1Mbit 的限速规则重新出现了!

至此,通过 auditd 锁定大方向,辅以控制变量法的精准验证,我们确定了罪魁祸首是被 ionCube 加密的 /usr/local/solusvm/includes/trafficloader.php 脚本。

5. 解决方案总结

由于 trafficloader.php 核心逻辑被加密,无法直接修改代码来修复其内部的逻辑错误(例如为什么误判需要限速)。我们有以下几种解决方案:

方案一:使用官方控制开关禁用流量整形 (强烈推荐)

这是最安全、最彻底的方法。既然该节点不需要 (或不信任) SolusVM 自动下发的带宽限制功能,直接通过官方预留的开关将其全局禁用。

# 禁用 SolusVM 的流量整形功能
rm -f /usr/local/solusvm/data/traffic-enabled
touch /usr/local/solusvm/data/traffic-disabled

# 清理当前已存在的错误规则
for dev in $(ls /sys/class/net | grep kvm); do tc qdisc del dev $dev root 2>/dev/null; done

执行此操作后,trafficloader.php 即使运行也会直接退出,不再下发规则。同时,你可以安全地停掉并删除你之前编写的那个一直跑死循环的 /root/fix_tc.sh 脚本,降低系统负载。

方案二:禁用相关的定时任务 (不推荐)

直接注释掉 /etc/cron.d/solusvm_networkspeed 文件中调用 trafficloader.php 的行。
这种方法比较粗暴,可能会影响 SolusVM 依赖此脚本进行的其他网络状态上报功能。

方案三:检查主控面板配置

检查 SolusVM 主控端 (Master Node) 的配置。很可能是主控面板上对这些 VPS 错误地配置了 "Network Speed" 为 1Mbit,导致节点机接收到指令后忠实地执行了限速。如果能在主控端修正配置,则无需在节点机上做任何修改。

posted @ 2026-05-09 14:29  季文康  阅读(15)  评论(0)    收藏  举报