SystemTap在应急排查中的应用
字数 1890 2025-08-26 22:11:35
SystemTap在应急排查中的应用 - 详细教学文档
1. SystemTap概述
SystemTap是一个用于动态监控和跟踪运行中Linux内核的工具,它利用Kprobe提供的API实现内核级别的调试和性能分析。
1.1 主要特点
- 提供简单的命令行接口
- 使用类似C语言的脚本语言
- 动态调试,几乎不影响系统性能
- 支持多种内核事件探测
1.2 适用场景
- 监控DNS/UDP/ICMP/ARP请求(挖矿病毒检测等)
- 追踪进程对文件的操作
- 监控所有内外连接尝试
- 跟踪进程创建、终止及模块加载/卸载
- Rootkit检测
2. 技术背景
2.1 Linux调试技术发展
静态调试(插桩/tracepoint)
- 早期需要编写内核模块
- 开发要求高,容易干扰系统稳定性
- 过程繁琐,效率低下
动态调试
- 类似Windows下的动态调试
- 灵活捕获内核调用,门槛低
- 代表工具:GDB、KDB、Dtrace、SystemTap
2.2 SystemTap原理
- 将脚本翻译成C代码
- 编译生成内核模块
- 加载模块并挂载探测点
- 事件发生时执行处理程序
- 会话结束后卸载模块
3. 安装与配置
3.1 安装步骤(以CentOS 6.8 x64为例)
-
下载与内核版本完全一致的调试包:
kernel-debuginfo kernel-debuginfo-common kernel-devel -
手动安装:
rpm -ivh kernel-debuginfo-common-x86_64-2.6.32-642.el6.x86_64.rpm rpm -ivh kernel-debuginfo-2.6.32-642.el6.x86_64.rpm rpm -ivh kernel-devel-2.6.32-642.el6.x86_64.rpm yum install systemtap systemtap-runtime -
测试安装:
stap -V stap -h stap -e 'probe begin{printf("Hello, World\n"); exit();}'
3.2 常见问题解决
- 如果提示"Incorrect version or missing kernel-devel package":安装与内核版本匹配的kernel-devel包
4. SystemTap工作流程
4.1 重要目录和文件
/lib/modules/KERNEL_VERSION/systemtap/:保存SystemTap工具模块/usr/share/systemtap/tapset/:标准tapset库/usr/share/doc/packages/systemtap/examples:示例脚本~/.systemtap/cache:缓存文件/tmp/stap*:临时目录(包含转换的C代码和内核对象)
5. 脚本编写基础
5.1 脚本结构
- 文件后缀:
.stp - 基本结构:
probe event { statements } global variables function definitions
5.2 常用事件和函数
常用事件:
begin:会话开始end:会话结束kernel.function("function_name"):内核函数调用syscall.*:系统调用netfilter.*:网络过滤事件
常用函数:
tid():当前线程IDpid():当前进程IDuid():当前用户IDcpu():当前CPU编号execname():当前进程名称gettimeofday_s():Unix时间戳(秒)ctime():格式化时间字符串pp():当前探测点描述
6. 实际应用案例
6.1 监控DNS请求
#! /usr/bin/env stap
global the_dport = 53
probe netfilter.ip.local_out {
if (the_dport == dport)
printf("%s[PID:%d,TID:%d] sent packet to %s:%d\n",
execname(), pid(), tid(), daddr, dport)
}
6.2 监控ICMP请求
#! /usr/bin/env stap
probe netfilter.ip.local_out {
if (0 == dport)
printf("%s[PID:%d,TID:%d] sent %d to %s:%d\n",
execname(), pid(), tid(), length, daddr, dport)
}
probe netfilter.ip.local_in {
if (0 == sport)
printf("%s recv %d from %s:%d\n",
execname(), length, saddr, sport)
}
6.3 监控传入TCP连接(成功连接)
#! /usr/bin/env stap
probe begin {
printf("%6s %16s %6s %6s %16s\n",
"UID", "CMD", "PID", "PORT", "IP_SOURCE")
}
probe kernel.function("tcp_accept").return?,
kernel.function("inet_csk_accept").return? {
sock = $return
if (sock != 0)
printf("%6d %16s %6d %6d %16s\n",
uid(), execname(), pid(),
inet_get_local_port(sock),
inet_get_ip_source(sock))
}
6.4 监控传入TCP连接尝试(无论成功与否)
#! /usr/bin/env stap
probe tcp.receive {
if (dport != 22) # 排除22端口
printf("%s:%d --> %s:%d\n",
saddr, sport, daddr, dport)
}
6.5 监控TCP外联(无论成功与否)
probe begin {
printf("ok\n");
}
probe syscall.connect {
if (uaddr_af == "AF_INET" || uaddr_af == "AF_INET6")
printf("%s[%d]: %s\n",
execname(), pid(), argstr);
}
6.6 监控文件操作
#!/usr/bin/stap
probe vfs.{write,read} {
if (dev == MKDEV($1, $2) && ino == $3)
printf("%s(%d) %s(%d) %s 0x%x/%u\n",
execname(), pid(), pexecname(), ppid(),
ppfunc(), dev, ino)
}
使用步骤:
- 获取要监控的文件信息:
df /path/to/file ls -i /path/to/file - 确定主从设备号和inode号
- 执行脚本:
stap /usr/share/systemtap/examples/io/inodewatch.stp 主设备号 从设备号 inode号
7. 高级应用
7.1 用户态调试
SystemTap不仅可用于内核调试,还可用于用户空间应用程序的调试和分析。
7.2 性能分析
可以编写脚本分析系统性能瓶颈,如函数调用耗时、系统调用频率等。
8. 参考资料
- SystemTap官方教程:https://sourceware.org/systemtap/tutorial/
- SystemTap函数库:https://sourceware.org/systemtap/tapsets/index.html
- 调试包下载源:
- https://mirrors.ocf.berkeley.edu/centos-debuginfo/
- https://oss.oracle.com/el6/debuginfo/
- http://debuginfo.centos.org/6/x86_64/
- kernel-devel下载:
- ftp://ftp.pbone.net/mirror/ftp.scientificlinux.org/linux/scientific/
- https://www.central.org/dl/linuxdev/
- IBM红皮书:《SystemTap: Instrumenting the Linux Kernel for Analyzing Performance and Functional Problems》