我在一家拥有一定数量遗留批处理流程的公司工作。
当涉及到数据库连接时,其中一些东西确实存在漏洞。
- 我需要记录系统中打开数据库连接的每个进程。
Strace 不是一个选项,进程太多,它们的生命周期太短,我需要审核多个框。
IPtables 不是一个选项,您可以匹配进程路径/用户,但您不能记录该信息(据我所知)
通常的工具,如 lsof/netstat 等,只包含有关活动进程和它们正在使用的连接的信息。
另一方面,这些批处理作业已经死了——所以我无法将进程与套接字相关联。
所以现在是学习 systemtap 的最佳时机。或者编写自定义内核模块。但是我没有专业知识/时间开始侵入系统调用表,此外,我想学习 systemtap 因为它似乎是非常有用的工具。
我的最终目标是编写一个探针,它 -
- 尽可能多地打印出有关本地连接到 MySQL 的每个进程的信息。
但细节决定成败。我无法在 Debian 上安装它(喘息)(根本),而且我在 Ubuntu 12(精确)上遇到奇怪的错误。
在 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 审计框架,灵感来自于以下帖子:
我的 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"
理想情况下,我也希望能够按主机和端口进行过滤。
我已经设法让它在 Ubuntu 上运行,Debian 是另一回事。
我已经创建了带有安装/监控脚本的存储库
https://bitbucket.org/sentimental/poc_stap
这些脚本还提供程序参数,因此对于顽皮的 PHP 脚本,现在可以识别作恶者。
与其说是一个答案,不如说一句警告:SystemTap 可能会令人困惑,有时甚至只是简单的错误,有时则不直观。尽管如此,它仍然是一个很好的工具,只是要小心使用它并使用其他工具交叉检查您的结果。
Brendan Gregg 的这篇博客文章对 SystemTap 的怪异世界进行了非常深入的分析。当然,由于博主平时使用的是
dtrace
,所以他的观点可能有失偏颇。不管怎样,这篇文章写得很好,让我重新考虑了 SystemTap 的可靠性。博客文章还有一些代码示例,可以帮助您解决问题。这是博客文章中的引述: