简体   繁体   English

如何在没有 sudo 的情况下以 root 身份在 chroot jail 中运行命令?

[英]How to run a command in a chroot jail not as root and without sudo?

I'm setting up a minimal chroot and want to avoid having sudo or su in it but still run my processes as non-root.我正在设置一个最小的 chroot 并希望避免在其中包含 sudo 或 su 但仍以非 root 身份运行我的进程。 This is a bit of a trick as running chroot requiers root.这是一个小技巧,因为运行 chroot 需要 root。 I could write a program that does this that would look something like:我可以编写一个执行此操作的程序,如下所示:

uid = LookupUser(args[username])  // no /etc/passwd in jail
chroot(args[newroot])
cd("/")
setuids(uid)
execve(args[exe:])

Is that my best bet or is there a standard tool that does that for me?这是我最好的选择还是有一个标准工具可以为我做到这一点?


I rolled my own here :在这里推出了自己的:

If you invoke chroot from root, the chroot option --userspec=USER:GROUP will run the command under the non-root UID/GID.如果从 root 调用chrootchroot选项--userspec=USER:GROUP将在非 root UID/GID 下运行命令。

By the way, the option '--userspec' is first introduced in coreutils-7.5 according to a git repository git://git.sv.gnu.org/coreutils .顺便说一下,根据 git 存储库git://git.sv.gnu.org/coreutils在 coreutils-7.5 中首先引入了选项“--userspec”。

fakechroot , in combination with fakeroot , will allow you to do this. fakechrootfakeroot相结合,将允许您执行此操作。 They'll make all programs that are running act as if they're being run in a chroot as root but they'll actually be running as you.它们将使所有正在运行的程序表现得好像它们以 root 身份在 chroot 中运行,但实际上它们会像您一样运行。

See also fakechroot's man page .另请参阅fakechroot 的手册页

A custom chrooter isn't at all hard to write:自定义 chrooter 一点也不难写:

#define _BSD_SOURCE
#include <stdio.h>
#include <unistd.h>
const char newroot[]="/path/to/chroot";
int main(int c, char **v, char **e) {
    int rc; const char *m;
    if ( (m="chdir" ,rc=chdir(newroot)) == 0
      && (m="chroot",rc=chroot(newroot)) == 0
      && (m="setuid",rc=setuid(getuid())) == 0 )
            m="execve", execve(v[1],v+2,e);
    perror(m);
    return 1;
}

Make that setuid root and owned by a custom group you add your favored user to (and no 'other' access).将该 setuid 设为 root 并由您将您喜欢的用户添加到的自定义组拥有(并且没有“其他”访问权限)。

You can make use of linux capabilities to give your binary the ability to call chroot() w/o being root.您可以利用 linux 功能使您的二进制文件能够调用 chroot() 而无需成为 root。 As an example, you can do this to the chroot binary.例如,您可以对chroot二进制文件执行此操作。 As non-root, normally you'd get this:作为非 root,通常你会得到这个:

$ chroot /tmp/
chroot: cannot change root directory to /tmp/: Operation not permitted

But after you run the setcap command:但是在运行setcap命令之后:

sudo setcap cap_sys_chroot+ep /usr/sbin/chroot 

It will let you do the chroot call.它会让你做 chroot 调用。

I don't recommend you do this to the system's chroot , that you instead do it to your own program and call chroot.我不建议您对系统的chroot执行此操作,而是对您自己的程序执行此操作并调用 chroot 。 That way you have more control over what is happening, and you can even drop the cap_sys_chroot privilege after you call it, so successive calls to chroot in your program will fail.这样你就可以更好地控制正在发生的事情,你甚至可以在调用后删除 cap_sys_chroot 权限,所以在你的程序中对 chroot 的连续调用将失败。

You could use Linux Containers to create a chroot environment that is in a totally different namespace (IPC, filesytem, and even network)您可以使用 Linux Containers 创建一个位于完全不同命名空间(IPC、文件系统甚至网络)中的 chroot 环境

There is even LXD which is able to manage the creation of image-based containers and configure them to run as unprivileged users so that if the untrusted code manages to somehow escape the container, it will only be able to execute code as the unprivileged user and not as the system's root.甚至还有 LXD 能够管理基于图像的容器的创建并将它们配置为以非特权用户身份运行,这样如果不受信任的代码设法以某种方式逃离容器,它将只能以非特权用户身份执行代码和不作为系统的根。

Search 'Linux Containers' and 'LXD' on your favorite search engine ;)在您喜欢的搜索引擎上搜索“Linux Containers”和“LXD”;)

These days chrooting without root-permissions is possible with unshare command provided by mount namespaces .现在,使用mount namespaces提供的unshare命令可以在没有 root 权限的情况下进行 chroot。

Plain Unshare普通取消分享

Suppose you want to chroot into ~/Projects/my-backup directory, and run inside it the ~/Projects/my-backup/bin/bash binary .假设您想 chroot 到~/Projects/my-backup目录,并在其中运行~/Projects/my-backup/bin/bash binary 。 So you run:所以你运行:

$ unshare -mr chroot ~/Projects/my-backup/ /bin/bash

Here:在这里:

  • -m means you can use mount --bind inside the new chroot (note that mounts will not be visible to the outside world, only to your chroot) -m表示您可以在新的 chroot 中使用mount --bind (注意,外部世界无法看到挂载,只有您的 chroot 才能看到)
  • -r makes it look as if you are root inside the chroot -r让它看起来好像你是 chroot 里面的 root
  • chroot … is the usual chroot command. chroot …是常用的 chroot 命令。

Possible pitfalls:可能的陷阱:

  1. Make sure you have environment variables set correctly.确保正确设置了环境变量。 For example, upon chrooting into an Ubuntu from Archlinux I was getting errors like bash: ls: command not found .例如,在从 Archlinux chroot 到 Ubuntu 时,我收到类似bash: ls: command not found Turned out, my $PATH did not contain /bin/ (on Archlinux it's a symlink to /usr/bin/ ) , so I had to run:原来,我的$PATH不包含/bin/ (在 Archlinux 上它是/usr/bin/的符号链接) ,所以我不得不运行:

     PATH=$PATH:/bin/ unshare -mr chroot ~/Projects/my-backup/ /bin/bash
  2. Note that /proc or /dev filesystems won't get populated, so running a binary that requires them will fail.请注意, /proc/dev文件系统不会被填充,因此运行需要它们的二进制文件将失败。 There is a --mount-proc option, but it doesn't seem to be accessible to a non-root user.有一个--mount-proc选项,但非 root 用户似乎无法访问它。

  3. chown won't work unless you do some complicated setup with newuidmap and newgidmap commands.除非您使用newuidmapnewgidmap命令进行一些复杂的设置,否则chown将无法工作。

Buildah Unshare Buildah Unshare

This has advantage compared to plain unshare in that it takes care of the needed setup for chown command to start working.与普通的unshare相比,这具有优势,因为它负责chown命令开始工作所需的设置。 You only need to make sure you have defined the ranges in /etc/subuid and /etc/subgid for your user.您只需要确保您已在/etc/subuid/etc/subgid为您的用户定义了范围。

You run it as:你运行它:

$ buildah unshare chroot ~/Projects/my-backup/ /bin/bash

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM