Как запустить команду в 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.
Возможные подводные камни:
Убедитесь, что у вас правильно установлены переменные среды. Например, при переходе в Ubuntu из Archlinux я получал такие ошибки, как
bash: ls: command not found
. Оказалось, мой$PATH
не содержал/bin/
(в Archlinux это символическая ссылка на/usr/bin/
) , поэтому мне пришлось запустить:PATH=$PATH:/bin/ unshare -mr chroot ~/Projects/my-backup/ /bin/bash
Обратите внимание, что
/proc
или же/dev
файловые системы не будут заполнены, поэтому запуск двоичного файла, который требует их, не удастся. Существует--mount-proc
вариант, но, похоже, он недоступен для пользователя без полномочий root.