我在一家拥有一定数量遗留批处理流程的公司工作。
当涉及到数据库连接时,有些东西确实存在漏洞。
- 我需要记录系统中的每个打开数据库连接的进程。
Strace 不是一个选项,有太多进程,它们寿命太短,我需要审核多个盒子。
IPtables 不是一个选项,您可以匹配进程路径/用户,但您无法记录该信息(据我所知)
常用的工具例如 lsof/netstat 等仅包含有关活动进程及其正在使用的连接的信息。
另一方面,这些批处理作业已经停止 - 所以我无法将进程与套接字关联起来。
所以现在是学习 systemtap 的好时机。或者编写自定义内核模块。但我没有专业知识/时间来开始侵入系统调用表,此外,我想学习 systemtap,因为它看起来是一个相当有用的工具。
我的最终目标是编写一个探测器 -
- 打印出尽可能多的有关本地连接到 MySQL 的每个进程的信息。
但魔鬼在细节中..我无法在 Debian(wheezy)上安装它(根本),而且我在 Ubuntu 12(Precise)上遇到了奇怪的错误。
在 Ubuntu 上,基本的 systemtap 探测工作得很好(这些是基本的复制和粘贴示例)。
#! /usr/bin/env stap
probe begin { println("hello world") exit () }
它产生了预期的输出。
sudo stap -v stapinit.stp
Pass 1: parsed user script and 76 library script(s) using 22792virt/13512res/2224shr kb, in 90usr/0sys/93real ms.
Pass 2: analyzed script: 1 probe(s), 1 function(s), 0 embed(s), 0 global(s) using 23056virt/14000res/2304shr kb, in 10usr/0sys/2real ms.
Pass 3: translated to C into "/tmp/stap2ntfcM/stap_32acf6b6a3f643d9444c9c8339e390d8_687.c" using 23056virt/14332res/2584shr kb, in 0usr/0sys/0real ms.
Pass 4: compiled C into "stap_32acf6b6a3f643d9444c9c8339e390d8_687.ko" in 1290usr/390sys/1902real ms.
Pass 5: starting run.
hello world
Pass 5: run completed in 10usr/40sys/596real ms.
但是更复杂的探测器就会失效,例如:
# Show sockets setting options
# Return enabled or disabled based on value of optval
function getstatus(optval)
{
if ( optval == 1 )
return "enabling"
else
return "disabling"
}
probe begin
{
print ("\nChecking for apps setting socket options\n")
}
# Set a socket option
probe tcp.setsockopt
{
status = getstatus(user_int($optval))
printf (" App '%s' (PID %d) is %s socket option %s... ", execname(), pid(), status, optstr)
}
# Check setting the socket option worked
probe tcp.setsockopt.return
{
if ( ret == 0 )
printf ("success")
else
printf ("failed")
printf ("\n")
}
probe end
{
print ("\nClosing down\n")
}
生产 -
Pass 1: parsed user script and 76 library script(s) using 22812virt/13660res/2224shr kb, in 90usr/10sys/120real ms.
semantic error: missing i386 kernel/module debuginfo under '/lib/modules/3.2.0-27-generic-pae/build' while resolving probe point kernel.function("tcp_setsockopt")
semantic error: no match while resolving probe point tcp.setsockopt
semantic error: missing i386 kernel/module debuginfo under '/lib/modules/3.2.0-27-generic-pae/build' while resolving probe point kernel.function("tcp_setsockopt").return
semantic error: no match while resolving probe point tcp.setsockopt.return
Pass 2: analyzed script: 2 probe(s), 1 function(s), 0 embed(s), 0 global(s) using 23136virt/14424res/2540shr kb, in 70usr/580sys/1255real ms.
Pass 2: analysis failed. Try again with another '--vp 01' option.
看起来我缺少一个依赖项,但我已经安装了厨房水槽。
sudo apt-get install elfutils
sudo apt-get install linux-headers-generic gcc libcap-dev
sudo apt-get install systemtap-sdt-dev
sudo apt-get install systemtap systemtap-doc linux-image linux-headers-generic-pae
- 更新 1
apt-get install systemtap 建议的软件包可能有些误导。
linux-headers-virtual 、 linux-image 、 linux-source 和 linux-tools 是虚拟包,因此将跟踪当前升级到的任何内核。
sudo apt-get install linux-headers-virtual linux-image linux-source linux-tools
为了保险起见,我还安装了 fdutils 和 kernel-package
sudo apt-get install fdutils kernel-package
将尝试此并报告。
- 更新 2
仍然损坏,同样的错误,这实际上是我尝试安装它的第三个系统。
我还发现了以下 Ubuntu 错误,也许是软件包有问题?
https://bugs.launchpad.net/ubuntu/+source/systemtap/+bug/824105
- 更新 3
Ubuntu 的问题似乎是他们没有构建内核调试符号包,或者至少没有以标准方式分发它。我的结论是 systemtap 包在 Ubuntu 上有问题,因为它没有安装关键的依赖项。
https://bugs.launchpad.net/ubuntu/+source/systemtap/+bug/106957
在我的 Debian 机器上,我遇到了不同的问题,测试已启用 - 因此 gcc 已升级到 4.6,而 linux-headers 包需要 gcc 4.3
root@datasift:~# apt-get install systemtap linux-image-`uname -r`-dbg linux-headers-`uname -r`
Reading package lists... Done
Building dependency tree
Reading state information... Done
systemtap is already the newest version.
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:
The following packages have unmet dependencies:
linux-headers-2.6.32-5-amd64 : Depends: gcc-4.3 but it is not going to be installed
E: Broken packages
root@datasift:~# uname -a
Linux datasift.sentimentmetrics.com 2.6.32-5-amd64 #1 SMP Sun May 6 04:00:17 UTC 2012 x86_64 GNU/Linux
- 结论
因此,总而言之 - systemtap 有可能在 Debian 上正常工作,但在 Ubuntu 上工作的可能性很小,而且我没有时间继续。我希望我运行的是 BSD/Solaris 或具有标准仪表接口的东西,但不管喜欢与否,Linux 都是商品之神。
更新 4
与此同时,我设法使用 Linux 审计框架,受到以下帖子的启发:
我如何才能识别 Linux 上哪个进程正在进行 UDP 流量?
我的 auditd 命令:
auditctl -a exit,always -F arch=b64 -F a0=2 -S socket
生成以下格式的日志消息:
type=SYSCALL msg=audit(1344346149.672:1670): arch=c000003e syscall=41 success=yes exit=5 a0=2 a1=1 a2=6 a3=1999999999999999 items=0 ppid=1 pid=29674 auid=0 uid=1003 gid=1003 euid=1003 suid=1003 fsuid=1003 egid=1003 sgid=1003 fsgid=1003 tty=(none) ses=124 comm="php5" exe="/usr/bin/php5" key=(null)
这些都很好,但最终是无用的,因为它们不包含程序参数。
我真正需要的(至少)是一些可以捕捉参数的东西,例如:
exe="/usr/bin/php5" args="/Administraitor/learn-to-code-hehe.php"
理想情况下,我希望能够按主机和端口进行过滤。
答案1
我已经设法让它在 Ubuntu 上运行起来,但 Debian 则是另一回事。
我已经创建了包含安装/监控脚本的存储库
https://bitbucket.org/sentimental/poc_stap
脚本还提供程序参数,因此对于恶意的 PHP 脚本,现在可以识别出犯错者。
答案2
与其说是答案,不如说是警告:SystemTap 可能令人困惑,有时甚至只是简单的错误,有时不直观。不过,它仍然是一个很好的工具,只是要小心使用它,并且也要用其他工具交叉检查你的结果。
这篇博文Brendan Gregg 的文章对 SystemTap 的奇特世界进行了非常深入的分析。当然,由于博主通常使用dtrace
,他的观点可能会有偏差。无论如何,这篇文章写得很好,让我再次思考 SystemTap 的可靠性。博客文章中还有一些代码示例,可能有助于您解决问题。
以下是博客文章中的一段引文:
在使用 SystemTap 时,我会记录自己所做的一切,包括哪些方法有效,哪些方法无效,以及如何解决问题。事实证明,这是一个方便的参考资料。
在最近一些关于 DTrace 的帖子中,人们问它与 SystemTap 相比如何——有些人评论说他们也没有时间研究。我被鼓励发布我的经验,这很容易从我的笔记中做到。我也可以(可能应该)将其中一些放入 SystemTap 错误数据库中。
我分享的是使用 SystemTap 的各种经验,包括我因为不知道自己在做什么而犯错的时候。我将从跟踪磁盘 I/O 的叙述开始,它将各种经验联系在一起。之后,它会变得有点不连贯,从各种笔记中剪辑出来。我会尽量保持技术性、积极性和建设性。也许这会对 SystemTap 项目本身有所帮助,看看用户(具有强大的动态跟踪和内核工程背景)遇到了什么困难。