Как запустить команду в chroot-тюрьме не как root и без sudo?

Я устанавливаю минимальный chroot и хочу, чтобы в нем не было sudo или su, но все же запускаю мои процессы без полномочий root. Это небольшая хитрость, так как запускает chroot Requiers root. Я мог бы написать программу, которая делает это, которая будет выглядеть примерно так:

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

Это моя лучшая ставка или есть стандартный инструмент, который делает это для меня?


Я катал свой здесь:

6 ответов

Решение

Если вы вызываете chroot от корня chroot вариант --userspec=USER:GROUP запустит команду под UID/GID без полномочий root.

Кстати, опция '--userspec' впервые введена в coreutils-7.5 в соответствии с репозиторием git. git://git.sv.gnu.org/coreutils,

fakechroot в сочетании с fakeroot позволит вам сделать это. Они заставят все работающие программы действовать так, как будто они запускаются в chroot как root, но на самом деле они будут работать как вы.

Смотрите также справочную страницу fakechroot.

Вы можете использовать возможности linux, чтобы дать вашему бинарному файлу возможность вызывать chroot() без root. Например, вы можете сделать это с chroot двоичный файл. Как не-root, обычно вы получите это:

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

Но после того, как вы запустите setcap команда:

sudo setcap cap_sys_chroot+ep /usr/sbin/chroot 

Это позволит вам сделать вызов chroot.

Я не рекомендую вам делать это с системой chroot, что вы вместо этого делаете это с вашей собственной программой и вызываете chroot. Таким образом, вы сможете лучше контролировать происходящее и даже можете отменить привилегию cap_sys_chroot после ее вызова, поэтому последующие вызовы chroot в вашей программе не будут выполнены.

Пользовательский 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;
}

Сделайте этот корень setuid и принадлежащим пользовательской группе, в которую вы добавляете своего привилегированного пользователя (и не имеете "другого" доступа).

Вы можете использовать Linux Containers для создания среды chroot, которая находится в совершенно другом пространстве имен (IPC, filesytem и даже сеть)

Существует даже LXD, который может управлять созданием контейнеров на основе изображений и настраивать их для работы в качестве непривилегированных пользователей, так что если недоверенному коду удается каким-то образом избежать контейнера, он сможет выполнять код только как непривилегированный пользователь и не как корень системы.

Ищите "Контейнеры Linux" и "LXD" в вашей любимой поисковой системе;)

В наши дни chroot без прав root возможен с unshareкоманда, предоставляемая пространствами имен mount .

Предположим, вы хотите войти в ~/Projects/my-backup каталог и запустите в нем ~/Projects/my-backup/bin/bashдвоичный. Итак, вы бежите:

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

Здесь:

  • -m означает, что вы можете использовать mount --bindвнутри нового chroot (обратите внимание, что крепления не будут видны внешнему миру, только вашему chroot)
  • -r выглядит так, как будто вы root внутри chroot
  • chroot … это обычная команда chroot.

Возможные подводные камни:

  1. Убедитесь, что у вас правильно установлены переменные среды. Например, при переходе в Ubuntu из Archlinux я получал такие ошибки, как bash: ls: command not found. Оказалось, мой $PATH не содержал /bin/ (в Archlinux это символическая ссылка на /usr/bin/) , поэтому мне пришлось запустить:

            PATH=$PATH:/bin/ unshare -mr chroot ~/Projects/my-backup/ /bin/bash
    
  2. Обратите внимание, что /proc или же /devфайловые системы не будут заполнены, поэтому запуск двоичного файла, который требует их, не удастся. Существует --mount-proc вариант, но, похоже, он недоступен для пользователя без полномочий root.

Другие вопросы по тегам