进程会计

作者:Keith Gilbertson

最近在一家财富 500 强公司现场时,我无意中听到一位技术支持人员兴奋地对一位项目经理耳语:“不要在您的 PC 上玩任何游戏!公司审计员有办法确切地知道您使用了哪些程序以及使用了多长时间!”

在响亮地向这位技术人员保证他完全是公事公办,并且不打算玩任何游戏之后,这位经理笑了笑。然后他用更小的声音说他不必担心;与公司的大多数人不同,他使用的是 Linux 而不是 Windows。

如果这位技术人员的故事是真的,那么这位经理确实有理由担心。尽管据传这家特定公司的审计应用程序是为 Windows 开发的,但 Linux 内核具有内置的进程会计功能。它允许系统管理员在每次程序在 Linux 系统上执行时,在日志文件中收集详细信息。凭借此功能,我们神话般的公司审计员实际上可以收集有关谁在 Linux 计算机上玩游戏以及玩了多长时间的信息。

尽管公司对了解哪些员工在公司设备上沉迷于纸牌游戏的兴趣值得怀疑,但使用进程会计 (PA) 还是有充分理由的。在本文中,我将讨论一些进程会计有用的情况,解释在哪里获取以及如何使用标准进程会计命令,然后演示如何在 C 程序中使用进程会计结构和系统调用。

预备知识

我假设您的系统已将进程会计支持编译到内核中。我做出此假设是因为我访问过的所有 Linux 系统上的内核都配置为允许进程会计,但您的发行版可能有所不同。如果您以 root 身份编译并运行本文中的第一个代码清单,但没有命令行参数,却收到错误消息,则很可能您的内核中未包含进程会计支持。您需要编译一个新的内核,并在“常规设置”菜单中的“BSD 进程会计”项中回答“是”CONFIG_BSD_PROCESS_ACCOUNTING。重新编译内核超出了本文的范围,但说明可以在 Linux 文档项目 (www.tldp.org/HOWTO/Kernel-HOWTO.html) 中找到。

在繁忙的系统上,请记住,启用进程会计需要大量的磁盘空间。在我的配备 Red Hat 7.2 的 Pentium III 系统上,每次执行程序时,都会将 64 字节的数据写入进程会计日志文件。在研究本文并在磁盘空间不足的测试机器上运行进程会计实用程序时,我发现一个监视进程每秒执行一次。该机器上的驱动器很快就满了。某些服务器的守护程序将为每个传入的连接启动一个单独的进程。在每小时执行近 25,000 个进程的生产服务器上,每月大约生成 1.1GB 的进程会计数据。表 1 中列出的 accttrim 和 handleacct.sh 脚本等实用程序可用于定期截断、备份和压缩日志文件。如果您计划在繁忙的系统上进行进程会计,那么了解和使用这些实用程序对您来说非常重要。

最后,请注意,您必须拥有 Linux 系统上的 root 权限才能启用或禁用进程会计,无论是使用标准命令还是创建自己的命令。

进程会计的用途

进程会计最早的用途之一是计算计算机安装中用户占用的 CPU 时间,然后相应地向用户收费。随着当今计算资源的日益丰富和相对较低的费用,此应用程序已逐渐被淘汰。但是,如果分布式计算模型流行起来,此应用程序可能会再次变得重要。

系统管理员可能希望使用从 PA 工具收集的数据来监视用户访问最多的程序,然后针对这些类型的程序优化系统配置。例如,PA 工具收集的数据部分包括程序输入和输出的字节数以及 CPU 使用率。运行高百分比 I/O 密集型应用程序的系统可能需要以不同于运行高百分比 CPU 密集型应用程序的系统的方式进行优化。

在某些时候,管理员可能需要评估两个功能相似的产品。让我们想象一下,在做出选择之前,管理员希望查看人们实际使用的是哪种鱼类预测产品。为此,可以打开进程会计一周,以记录日志文件中执行的所有命令的名称。然后,管理员可以解析日志文件,找出哪个命令运行得更频繁。

进程会计最典型的应用是作为系统安全措施的补充。在公司服务器遭到入侵的情况下,进程会计工具创建的日志文件可用于收集取证证据。仔细查看攻击者在受损系统上使用的程序,可以提供有关已造成的损害、入侵者的手段和可能的动机的有用信息。从进程会计日志中收集的证据也可能在法庭上有所帮助。我知道一个刑事案件,其中此数据在被告人没有异议的情况下,导致了轻罪判决。

标准进程会计命令

即使进程会计工具已编译到您的内核中,您的系统上也可能未安装用于进程会计的用户命令。如果是这种情况,并且您希望快速入门,请首先尝试查找适用于您的特定 Linux 发行版的进程会计命令。

您的发行版的软件包很可能配置为将日志文件放置在适合您的系统设置的位置,从而使安装更加简单。在我的 Red Hat 7.2 发行版 CD 上,我在第二张光盘的目录中找到了 ps-acct-6.3.2-9.i386.rpm。如果您使用 gnorpm 图形安装工具,该软件包将出现在“软件包/应用程序/系统”层次结构中。在 Debian 系统上,安装 acct 软件包。

如果您要从源代码安装,则有两个版本的实用程序可用。一个版本在 BSD 许可下,可在 www.ibiblio.org/pub/Linux/system/admin/accounts 上找到。文件名将类似于 acct-1.3.73.tar.gz,具体取决于版本号而略有不同。为了使这些实用程序在我的系统上编译,我必须编辑 lastcomm.c 文件并注释掉 strcpy 函数的原型。

还有一套由 Noel Cragg 编写并根据 GNU GPL 许可的进程会计实用程序集。它可在 www.gnu.org/directory/System_administration/Monitoring/acct.html 上找到。

系统上安装的确切进程会计命令将因您选择的特定软件包而异。表 1 显示了您可能遇到的命令列表以及每个命令的用途。

表 1. 进程会计命令

GNU 会计实用程序的安装

让我们快速了解一下如何在系统上安装 GNU 会计实用程序。使用以下命令

tar zxvf acct_6.3.5.orig.tar.gz
cd acct-6.3.5
./configure
make
su
make install

现在,一些基本的进程会计命令已安装在您的系统上。您现在可以启用会计并开始使用这些命令了。

实用程序的使用

在本篇关于使用进程会计命令的简短介绍中,我将介绍两个命令:accton 和 lastcomm。我选择这两个命令是因为它们是所有进程会计版本上的标准命令。

accton 命令用于打开或关闭进程会计。如果在命令行中指定了文件名,则该文件名将用于记录进程会计信息。如果未指定任何参数,则进程会计将被关闭。

要启动系统上的进程会计工具,请 su 以成为 root 用户。通过在所需位置执行 touch 来确保日志文件存在。示例

touch  /var/log/pacct

然后键入您的 accton 程序的完整路径(通常为 /usr/sbin/accton 或 /sbin/accton),后跟文件名。示例

/sbin/accton /var/log/pacct
您刚刚启动了进程会计工具。请注意,数据实际上并非在每个进程开始执行时添加到文件中;而是在进程退出时写入。前面提到的项目经理可以整天玩 xbill 游戏,并且不会将此信息写入进程会计文件,只要他从不退出该程序即可。当他晚上回家时,他可以选择让 xbill 运行并最小化窗口,或者他可以简单地关闭计算机电源而不执行正确的关机。

现在您已打开会计,以普通用户身份运行一些正常命令,以获取 lastcomm 命令的一些数据,您将在下一步中使用该命令。完成后,再次 su 成为 root 用户,并运行 /usr/sbin/accton/sbin/accton,不带任何参数以关闭进程会计。

lastcomm 命令打印会计日志文件中包含的信息,最近的记录首先打印。您可以使用 -f 命令行选项来指定文件名。通常,系统上的进程会计日志文件设置为只有 root 用户才能读取它。然后,此命令由 root 用户执行,例如

lastcomm -f /var/log/pacct

当您键入上述命令时,输出类似于此

id         root   stdin  0.00 secs Mon Jul 22 12:41
xauth   S  root   stdin  0.00 secs Mon Jul 22 12:41
xauth   S  keithg stdin  0.00 secs Mon Jul 22 12:41
xauth   S  keithg stdin  0.01 secs Mon Jul 22 12:41
bubbles  X keithg ??     0.01 secs Mon Jul 22 12:33
ls         keithg ??     0.01 secs Mon Jul 22 12:26
bash     X keithg ??     0.03 secs Mon Jul 22 08:25
lastcomm 显示每个命令的命令名称、选项、用户名、终端和退出时间。也可以在命令行中指定特定的命令、用户或终端。例如,如果您只想查找 su 程序何时启动的实例,则可以键入
lastcomm -f /var/log/pacct --command su
现在您将看到如下输出
su      root     ??      0.01 secs Mon Jul 22 10:52
su      keithg   stdout  0.05 secs Mon Jul 22 09:32
su      keithg   stdout  0.00 secs Mon Jul 22 09:17
su      root     ??      0.00 secs Mon Jul 22 03:29
su      keithg   tty1    0.00 secs Sun Jul 21 19:49
请注意,在每一行中,左列中列出的命令现在都是 su。有关这些命令和表中的其他程序的更多详细信息,请参阅各自的 man 页面。
编程细节

用于收集进程会计详细信息的 acct 结构记录在头文件 /usr/include/linux/acct.h 和 /usr/include/sys/acct.h 中。表 2 显示了 acct 结构中可用的成员以及每个成员的简要说明。

表 2. acct 结构中的成员

从表中可以看出,大量信息被打包到 64 字节的会计记录中。如果您觉得需要比标准进程会计提供的更多信息,请查阅本文末尾“资源”中列出的 Mann 和 Mitchell 的著作。

示例程序

清单 1. 启用和禁用文件会计

清单 1 简单演示了 acct 系统调用的用法。acct 调用接受一个参数,即进程会计信息附加到的文件的名称。如果参数为 NULL,则进程会计将被关闭。此外,当进行系统调用时,文件必须已经存在,否则调用将失败并返回错误。

如果以普通用户的 ID 运行的程序调用 acct,则调用也会失败并返回错误。尝试打开和关闭进程会计的程序必须具有 root 权限才能成功。

清单 1 中的代码类似于 accton 命令的典型实现,但有两个主要区别。第一个区别是此代码将在消息中向标准输出报告其操作。第二个区别是,如果命令行中指定的文件不存在,它将被创建。

该文件包含 <unistd.h> 头文件。所有使用 acct 调用的程序都应包含此文件。该程序检查 argc 是否等于 1,这意味着命令行中没有传递任何参数。如果是这样,该程序将尝试通过使用 NULL 参数调用 acct 来关闭进程会计。

如果命令使用参数运行,则程序将假定第一个参数是文件名。如果该文件不存在,则程序将尝试使用 creat 系统调用创建该文件。然后,程序将使用文件名作为参数调用 acct 以打开进程会计。如果从系统调用返回错误代码,则将打印一条消息,并且程序将退出。

清单 2. 解析会计文件

清单 2 演示了如何将日志文件中的记录读取到内存中的 acct 结构中,以便可以打印或操作信息。此程序包含 <sys/acct.h> 头文件。所有需要使用 acct 结构的程序都应包含此文件。main 函数中的局部变量包括文件描述符、用于保存从文件读取的字节数的变量和一个 acct 结构。

程序用户必须在命令行中指定文件名。程序尝试以只读访问权限打开此文件。如果打开成功,程序将从文件中将记录 read() 直接读取到本地 acct 结构 a 中。由于本文的空间限制,我假设 read() 总是返回请求的确切字节数,直到到达文件末尾。程序继续读取和打印记录中的命令名称,直到从 read() 调用返回零,表示文件结束条件。

本文中的清单旨在简单介绍系统会计结构。健壮的程序将创建一个缓冲区以一次读取多个会计记录,并且它们将检查诸如从文件中读取的字节数少于请求的字节数之类的问题。要查看健壮程序的示例,请查看您已安装的进程会计实用程序的源代码。

结论

您现在拥有足够的信息来启用进程会计并使用标准命令来检索有关在 Linux 系统上执行的程序的信息。如果您有兴趣,您还可以学习制作自定义工具来解析进程会计日志文件。

如果您将进程会计用于系统安全,请记住,它绝不是一个全面的解决方案,而只是一种小型工具。实际上,正如 Mann 和 Mitchell 指出的那样,您应该小心信任进程会计日志文件中的信息;日志可能已被技术娴熟的攻击者修改。

通过对 Linux 中的进程会计工具的基本了解和一些实验,您可以在自己的计算机上设置这些实用程序。如果您有幸拥有工作系统中 root 访问权限,您也将准备好从会计日志文件中删除所有 Sokoban 游戏的痕迹——以防万一那个邪恶的公司审计员真的有一天出现在您的部门。

资源

Process Accounting
Keith Gilbertson (keithg@kellnet.com) 是俄亥俄州鲍ling格林州立大学的毕业生。他在伊利湖附近的梅西百货数据中心的无线和 Linux 开发团队担任程序员分析师。在湖上,鱼不怕企鹅。
加载 Disqus 评论