我需要(暂时)监禁一名非特权用户。
我尝试过类似的事情:
sudo chroot --userspec=mcon:users /wherever/chroottarget /bin/bash -i
这几乎有效,但它没有设置环境变量(而“sudo”设置了!),所以我收到错误:
bash: /root/.bashrc: Permission denied
我该如何解决这个问题?(注意:上述命令应该在 bash 脚本中)
更新:我找到了一种(相当复杂的)方法来做我需要的事情:
sudo bash -c "HOME=<jailed home> chroot --userspec=<user>:<group> <chroottarget> /bin/bash -i"
理想情况下,我应该阅读 HOME被判入狱/etc/passwd,以及所有其他环境变量(从被判入狱/etc/profile),这个“解决方案”将保持调用者环境中的所有变量不变。
有没有更好的办法?
答案1
通过 C 程序调用chroot()
和系统调用怎么样?setuid()
一个简单的 C 程序示例:
执行这个简单的 C 程序的先决条件(可以随意添加将 /etc/profile、/etc/passwd 和/或设置环境所需的任何其他内容复制到 /tmp 的步骤):
您已将 /bin/*、/usr/bin/*、/lib* 复制到 /tmp。
例如,使用以下命令集:
~$ sudo cp -rH /bin/ /tmp/
~$ mkdir /tmp/usr/
~$ sudo cp -rH /usr/bin/ /tmp/usr/
~$ sudo cp -rH /lib* /tmp/
/*
* \file chrooted_user_is_non_root.c
*
* DISCLAIMER: Notice how I do not check return values/perform any error
* checks. This code snippet is for illustration purposes only and not
* meant to be used in production.
*
* Inspired by:
* https://stackoverflow.com/a/3946135/4726668
*/
#include <unistd.h>
#include <stdlib.h>
int main (void)
{
chdir ("/tmp");
chroot ("/tmp");
setuid (1000); // Set to a non-privileged user id.
system ("ls -id /"); // If inode number of / is not 2, then you are *most likely* inside chroot.
system ("id"); // If this prints non-zero uid, then you are not root.
return 0;
}
请注意在使用和不使用 sudo 运行此程序时输出的差异:
~$ gcc chrooted_user_is_non_root.c -o chrooted_user_is_non_root.elf
~$ sudo ./chrooted_user_is_non_root.elf
2883585 /
uid=1000 gid=0 groups=0
~$ ./chrooted_user_is_non_root.elf
2 /
uid=1000(user_foo) gid=1000(user_foo) groups=1000(user_foo),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),122(lpadmin),135(lxd),136(sambashare)
正如代码注释中提到的,上面的代码片段受到以下启发:https://stackoverflow.com/a/3946135/4726668
答案2
您需要更改环境变量 $HOME 来匹配用户。
export HOME=/home/user-name