如何在不影响文件系统的情况下运行 bash 脚本?

如何在不影响文件系统的情况下运行 bash 脚本?

我正在尝试为 Linux 系统 (ubuntu) 创建一些沙箱软件。我的主要目标是找出我选择的 bash 脚本执行了哪些文件,但实际上并没有运行它们。我还想阻止对系统的更改,这样正在运行的脚本会认为它有能力写入文件,但实际上却没有。我不想在低权限下运行 bash 脚本,因为如果它试图更改某些内容,它将无法运行。请不要建议通过虚拟机运行它,这对我来说太慢了。

我唯一想到的办法是挂接任何写入系统调用,这样当它尝试写入文件时,系统将返回 SUCCESS 但不执行任何操作。此外,挂接任何执行系统调用以捕获脚本执行的所有程序并阻止执行其他文件,同时将成功返回给脚本。但我不知道该怎么做。

有什么想法吗?提前致谢。

答案1

尝试使用覆盖,带有chroot。首先,确定您要 chroot 到的路径,并确保它存在,对于您要覆盖的路径/(即修改将发生的位置),也同样如此:

mkdir -p /chroot
mkdir -p /tmp/tmproot

我选择了 中的目录,/tmp/因为它在我的系统上是tmpfs(可能不建议,但对我来说没问题),因此不会有任何更改影响到磁盘。您可以使用squashfs并将其挂载到某处,然后将其用作覆盖,但我认为这存在只读的问题。

现在:

$ mount -t overlayfs -o lowerdir=/,upperdir=/tmp/tmproot overlayfs /chroot/
$ chroot /chroot/ /bin/bash -l
root:/$ touch test
root:/$ ls
...  sys  test  tmp  ...
root:/$ logout
$ ls /
...  sys  tmp  ...
$ ls /tmp/tmproot/
root  test

如果您使upperdir独立于物理磁盘(可能通过使用tmpfs),这应该可以保护lowerdir

请注意,创建了一个root文件夹 - 这是我的.bash_history。复制了原始.bash_history,然后将其附加到。

答案2

这是一个不可能的结果:脚本的行为可能取决于它之前写入文件的信息。如果您实际上不允许它写入文件(但让脚本相信它确实写入了文件),那么您可能会以一种在“真正”运行它时不会发生的方式影响脚本的行为。

例如:

#!/bin/bash

write_bit_to_file () {
    # write a random bit to a file
    echo $((RANDOM % 2)) >> file.txt
}

get_bit_from_file () {
    # read the random bit from the file
    tail -1 file.txt
}

# MAIN SCRIPT
#############

# ... do some stuff, save some info for later ...
write_bit_to_file
# ... do more stuff, retrieve info from file ...
if (( $(get_bit_from_file) )); then
    # access foo.txt and do something
    echo "I'm going to access foo.txt"
else
    # access bar.txt and do something
    echo "I'm going to access bar.txt"
fi

这显然是一个非常人为的脚本,但我希望您明白这一点:如果脚本实际上没有写入file.txt,但认为它确实写入了,那么您将收到错误(例如,如果file.txt不存在)或意外行为(例如,如果file.txt存在,但包含与预期不同的信息,因为write_bit_to_file实际上没有写入文件)。但是,如果您真正运行该脚本,它将按预期运行(例如,随机访问foo.txtbar.txt)。

可以做的是编写一个监视器来执行你的脚本,观察它写入的文件,在执行之前备份这些文件,并在脚本结束时将这些文件恢复到其原始状态。但那会相当糟糕 ;)

编辑:这个答案,muru 建议了一种非常好的方法来实现类似于此监视器的功能,甚至更好,因为它永远不会影响您的实际根文件系统,并保留脚本对文件的修改以供以后重复使用。这就是方法!:-)

相关内容