监视尝试访问不存在的文件或目录的进程

监视尝试访问不存在的文件或目录的进程

我们正在将网站从一个服务器配置迁移到新配置,并且网站将位于与以前不同的路径中。我们计划认真检查并用新路径替换旧路径,但如果我们错过任何路径,是否有某种方法可以监视任何试图访问旧路径的进程,并知道该进程所拥有的 UID 是什么?

答案1

您可以使用这个小 systemtap 脚本:

#!/usr/bin/stap
function proc:string() { return sprintf("PID(%d) UID(%d) PROC(%s)", pid(), uid(), execname()) }

probe syscall.open.return, syscall.stat.return,
  syscall.open64.return ?, syscall.stat64.return ? {
  filename = user_string($filename)
  if ($return < 0) {
    printf("failed %s on %s by %s\n", pn(), proc(), filename)
  }
}

它将在返回时挂钩系统调用 open 和 stat (您可以复制/粘贴代码,也许我忘记了其他一些系统调用)。由于系统调用是与内核通信的唯一方式,因此您不会错过任何东西。该脚本将产生这种输出:

failed syscall.stat.return on PID(4203) UID(1000) PROC(bash) by /tmp/rofl
failed syscall.stat.return on PID(4203) UID(1000) PROC(bash) by /tmp/hihi

使用 systemtap 的优点包括:

  • 对过程的干扰较小
  • 系统范围(不仅是受监视的进程),但您可以直接在脚本中减少其选择
  • 资源消耗较少(仅显示失败的操作,而不是所有操作之后都进行 grep)
  • 您可以改进脚本以获取有关调用程序的详细信息(例如,其回溯、调用时间等)。这取决于您的应用程序。

对于缺点:

  • 不是标准的,您必须安装它(但足够标准,可以在大多数发行版上使用)。在 Redhat 及变体上:sudo yum install systemtap
  • 需要有调试信息来构建模块。在 Redhat 及变体上:sudo debuginfo-install kernel

一些有用的链接:Tapset(包含的函数)索引,和一个初学者指南

祝您移民顺利!

答案2

像这样的事情应该这样做:

strace -f \
-e trace=open,stat,stat64,lstat,lstat64,chdir,mkdir,rename,symlink,creat \
 -o >(grep "the paths you want to catch" > log) \
commandToStartYourServer

您希望-f交换机跟踪子进程。跟踪选项是fabricate用于跟踪 IO 的子集(制造跟踪"open,stat,stat64,lstat,lstat64,execve,exit_group,chdir,mkdir,rename,clone,vfork,fork,symlink,creat"

这通过 grep 和进程替换(基本上是系统级别的管道)过滤输出来进一步限制磁盘 IO。

答案3

你可以使用 fatrace。大多数现代系统中应该存在内核支持 (fanotify),但 fatrace 用户空间应用程序不在某些操作系统的标准存储库中。如果您的旧文件位于单独的文件系统上,则 fatrace 特别好。

http://www.lanedo.com/filesystem-monitoring-linux-kernel/

--

更常见的是auditd,尽管使用起来有点困难。

http://linux-audit.com/configuring-and-auditing-linux-systems-with-audit-daemon/

--

当符号链接允许通过完全不同的路径进行访问时,通过路径监视文件使用情况存在一个根本问题,因此您可能需要特别注意这一点。

相关内容