如何列出Linux启动期间使用的所有文件

如何列出Linux启动期间使用的所有文件

我想获取 Linux 启动过程中使用的文件列表。我们正在开发基于RHEL 6.4的受保护企业系统。指定文件的完整性将由特殊硬件进行检查。

所以问题是 - 如何获取这些文件的列表(具有来自不同引导服务和守护程序的已解决的依赖项)。

答案1

设置审计子系统将通话录音到open.

auditctl -a exit,always -S open,openat,creat,execve

/sbin/init从 initramfs 执行此操作,以便在主系统(在真正的根文件系统上)启动时规则就位。

请注意,您建议执行的操作不会为典型设置带来任何真正的安全性。任何可以用其他版本替换这些文件的人都拥有 root 访问权限,并且还可以向日志系统提供虚假数据。

如果启动介质受到外部保护,root 无法对其进行修改(例如,因为它是只读的或受安全启动加载程序的独占控制),并且如果加载内核模块被阻止,那么如果操作正确,测量文件可能是可靠的。然而,如果您对这些措施所做的只是将它们与参考值进行比较,那么这比使用受完整性保护的根文件系统(即在 dmcrypt 上的实践中,使用 Trusted Grub 作为引导加载程序)更困难且效率更低。

答案2

一个好的起点是/etc/rci.d代表i您要启动的运行级别的数字。例如,如果您的服务器是无头的,i则通常为 3。查看下面/etc/rc3.d将显示当您启动到运行级别 3 时正在启动哪些服务。

答案3

确保atime在内核中启用了根和引导文件系统(或者未noatime设置),然后在引导后,您可以使用它stat来检查每个文件的访问时间,并查看在引导期间访问了哪些文件。

答案4

感谢 RHEL 的支持,我们已经找到了明确的解决方案。它基于 systemtap 内核模块的使用情况。引自这里以避免链接失效。再次感谢您的所有建议:)

我什至无法想象 systemtap 甚至能够在 init 脚本之前启动并跟踪启动过程。我非常欣赏红帽 支持并亲自向 Pushpendra Chavan 寻求有关此完美工具的帮助(不幸的是,我不知道该方法到底属于哪个开发人员 - 否则我首先会信任他们)。

所以我们需要创建两个简单的脚本:

bootinit.sh:

#!/bin/sh


# Use tmpfs to collect data
/bin/echo "Mounting tmpfs to /tmp/stap/data"
/bin/mount -n -t tmpfs -o size=40M none /tmp/stap/data

# Start systemtap daemon & probe
/bin/echo "Loading bootprobe2.ko in the background. Pid is :"
/usr/bin/staprun \
    /root/bootprobe2.ko \
    -o /root/bootprobe2.log -D

# Give daemon time to start collecting...
/bin/echo "Sleeping a bit.."
sleep 5

# Hand off to real init
/bin/echo "Starting."
exec /sbin/init 3

bootprobe2.1.stp用嵌入式 systemtap 脚本语言编写:

global ident

function get_usertime:long() {
  return task_utime() + @cast(task_current(), "task_struct", "kernel<linux/sched.h>")->signal->utime;
}

function get_systime:long() {
 return task_stime() + @cast(task_current(), "task_struct", "kernel<linux/sched.h>")->signal->stime;
}

function timestamp() {
  return sprintf("%d %s", gettimeofday_s(), ident[pid()])
}

function proc() {
  return sprintf("%d \(%s\)", pid(), execname())
}  

function push(pid, ppid) {
   ident[ppid] = indent(1)
   ident[pid] = sprintf("%s", ident[ppid])
}

function pop(pid) {
  delete ident[pid]
} 

probe syscall.fork.return {
  ret = $return
  printf("%s %s forks %d  \n", timestamp(), proc(), ret)
  push(ret, pid())
}

probe syscall.execve {
  printf("%s %s execs %s \n", timestamp(), proc(), filename)
}

probe syscall.open {
  if ($flags & 1) {
    printf("%s %s writes %s \n", timestamp(), proc(), filename)
  } else {
    printf("%s %s reads %s \n", timestamp(), proc(), filename)
  }
} 

probe syscall.exit {
  printf("%s %s exit with user %d sys %d \n", timestamp(), proc(), get_usertime(), get_systime())
  pop(pid())
}
<linux sched.h=""><linux sched.h="">
</linux></linux>

为了以 systemtap 日志格式接收启动过程中访问的文件列表,我们应该实现以下内容:

下载并安装正确命名的版本systemtapkernel debuginfo软件包(我已经得到了这个链接,但你最好使用如果您使用的是 CentOS);

创建/tmp/stap/tmp/stap/data

mkdir -p /tmp/stap/data

bootprobe2.1.stpbootinit.sh放入/root并使其可执行: chmod +x /root/boot*

如果 5 是您的默认运行级别,则编辑bootinit.sh“exec /sbin/init 3”并将其更改为“exec /sbin/init 5”。

从 bootprobe2.stp 创建 .ko 模块

 cd /root
 stap bootprobe2.1.stp -m bootprobe2 -p4

重启。

暂停grub(按 Esc 或 Shift)并在默认内核上按“a”。在内核行末尾输入以下内容并按 Enter:

init=/root/bootinit.sh,

正常启动将恢复。登录后,kill进程将stapio复制bootprobe2.logtmpfs /tmp/stap/data目录并卸载。

killall stapio
cp /tmp/stap/data/bootprobe2.log /tmp/stap/
umount /tmp/stap/data  

现在检查文件/tmp/stap/bootprobe2.logfile 以获取启动期间读取的所有文件的列表。

相关内容