启动 chroot 并进入非特权用户主目录

启动 chroot 并进入非特权用户主目录

我需要(暂时)监禁一名非特权用户。

我尝试过类似的事情:

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

相关内容