我想获取在 Linux 启动过程中使用的文件列表。我们正在开发基于 RHEL 6.4 的受保护的企业系统。指定文件的完整性将由特殊硬件检查。
所以问题是 - 如何获取这些文件的列表(解决了来自不同启动服务和守护进程的依赖项)。
设置审计子系统以记录对 的调用open。
auditctl -a exit,always -S open,openat,creat,execve
Run Code Online (Sandbox Code Playgroud)
从 initramfs 执行此操作,以便在主系统(/sbin/init在真正的根文件系统上)启动时规则就位。
请注意,您提议的操作不会为典型设置带来任何真正的安全性。任何可以用其他版本替换这些文件的人都拥有 root 访问权限,也可以将虚假数据提供给日志系统。
如果启动媒体受到外部保护,因此 root 无法修改它(例如,因为它是只读的或在安全引导加载程序的独占控制下),并且如果加载内核模块被阻止,那么如果操作正确,则测量文件是可靠的. 但是,如果您对这些措施所做的只是将它们与参考值进行比较,那么这比使用受完整性保护的根文件系统(即实际上在 dmcrypt 上使用 Trusted Grub 作为引导加载程序)更困难且效率更低。
感谢 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
Run Code Online (Sandbox Code Playgroud)
并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>
Run Code Online (Sandbox Code Playgroud)
为了以 systemtap 日志格式接收启动过程中访问的文件列表,我们应该实现以下内容:
systemtap下载并安装正确命名的和软件包版本kernel debuginfo(我已获得此链接,但如果您使用的是 CentOS,最好使用此链接);
创建/tmp/stap并/tmp/stap/data
mkdir -p /tmp/stap/data
Run Code Online (Sandbox Code Playgroud)
将bootprobe2.1.stp和bootinit.sh放入/root并使其可执行: chmod +x /root/boot*
bootinit.sh如果 5 是您的默认运行级别,则编辑“exec /sbin/init 3”并将其更改为“exec /sbin/init 5” 。
从 bootprobe2.stp 创建 .ko 模块
cd /root
stap bootprobe2.1.stp -m bootprobe2 -p4
Run Code Online (Sandbox Code Playgroud)
重启。
暂停grub(按 Esc 或 Shift)并在默认内核上按“a”。在内核行末尾输入以下内容并按 Enter:
init=/root/bootinit.sh,
Run Code Online (Sandbox Code Playgroud)
将恢复正常启动。登录后,kill进程stapio,将目录复制bootprobe2.log出来tmpfs /tmp/stap/data并卸载。
killall stapio
cp /tmp/stap/data/bootprobe2.log /tmp/stap/
umount /tmp/stap/data
Run Code Online (Sandbox Code Playgroud)
现在检查文件/tmp/stap/bootprobe2.logfile 以获取启动期间读取的所有文件的列表。
| 归档时间: |
|
| 查看次数: |
3172 次 |
| 最近记录: |