тюрьмы chroot специфичны для BSD. chroot в Linux не является тюрьмой. Последнее, что я проверил, было невозможно выполнить chroot как пользователь.
ксенотеррацид
1
@xenoterracide Jails специфичны для BSD, но chroot обычно известен как «chroot jail» в сообществе Linux. Это довольно запутано.
pehrs
2
Что вы пытаетесь сделать и почему? Существуют такие инструменты, как fakechroot и schroot, которые обеспечивают работоспособную альтернативу в зависимости от ваших требований.
В Linux системный вызов chroot (2) может быть выполнен только привилегированным процессом. Способность, в которой нуждается процесс, является CAP_SYS_CHROOT.
Причина, по которой вы не можете использовать chroot как пользователя, довольно проста. Предположим, у вас есть программа setuid, такая как sudo, которая проверяет / etc / sudoers, если вам разрешено что-то делать. Теперь поместите его в chroot chroot с вашим собственным / etc / sudoers. Внезапно вы получаете мгновенное повышение привилегий.
Можно спроектировать программу для самореализации и запуска ее как процесса setuid, но это обычно считается плохим дизайном. Дополнительная безопасность chroot не мотивирует проблемы безопасности с setuid.
Благодаря новым возможностям пространств имен в linux, возможно, возможно создать (отменить) новое пространство имен «user», где будет «встроенный» пользователь root, и chrootзатем выполнить его .
imz - Иван Захарящев
1
@ imz - IvanZakharyaschev Вы абсолютно правы, и я надеюсь, вы не возражаете, что я взял на себя смелость написать это как легко проверяемый ответ.
HVd
@hvd Отлично! Это должно быть очень полезно, потому что оно демонстрирует, как использовать новые незнакомые функции Linux с конкретными командами.
imz - Иван Захарящев
6
@ imz - IvanZakharyaschev комментирует ответ pehrs, что это может быть возможно с введением пространств имен, но это не было проверено и опубликовано как ответ. Да, это действительно позволяет пользователю без полномочий root использовать chroot.
При наличии статически связанной dash, статически связанной busyboxи работающей bashоболочки, работающей без полномочий root:
Идентификатор пользователя root в этом пространстве имен сопоставляется с идентификатором пользователя без полномочий root вне этого пространства имен, и наоборот, поэтому система показывает файлы, принадлежащие текущему пользователю, как принадлежащие идентификатору пользователя 0. Обычный ls -al root, без unshare, делает показать их как принадлежащих текущему пользователю.
Примечание: это хорошо известно , что процессы, которые способны использовать chroot, способны вырваться из chroot. Так unshare -rкак предоставит chrootразрешения обычному пользователю, это будет представлять угрозу безопасности, если это будет разрешено внутри chrootсреды. В самом деле, это не разрешено, и терпит неудачу с:
CLONE_NEWUSER был указан в флажках, а вызывающий абонент находится в среде chroot (т. Е. Корневой каталог вызывающего не совпадает с корневым каталогом пространства имен монтирования, в котором он находится).
Запуск pivot_root в пространстве имен монтирования имеет эффект, аналогичный chroot, но позволяет избежать конфликта с пространствами имен пользователей.
Тимоти Болдуин
1
Можно выйти из пространства имен chroot или mount, спустившись в / proc, если это процесс снаружи с тем же UID в том же или дочернем PID и пространствах имен пользователя.
Тимоти Болдуин
2
В наши дни вы хотите смотреть на LXC (Linux Containers) вместо chroot / BSD jail. Это где-то между chroot и виртуальной машиной, что дает вам большой контроль безопасности и общую настраиваемость. Я считаю, что все, что вам нужно, чтобы запустить его как пользователь, - это быть членом группы, которая владеет необходимыми файлами / устройствами, но могут также быть задействованы возможности / системные разрешения. В любом случае, это должно быть очень выполнимо, поскольку LXC появился совсем недавно, еще долго после того, как SELinux и т. Д. Был добавлен в ядро Linux.
Также имейте в виду, что вы можете просто писать скрипты как root, но давать пользователям безопасное разрешение на запуск этих скриптов (без пароля, если хотите, но убедитесь, что скрипт безопасен) с использованием sudo.
Комбинация fakeroot / fakechroot дает симуляцию chroot для простых нужд, таких как создание tar-архивов, где файлы, по-видимому, принадлежат root. Справочная страница Fakechroot находится по адресу http://linux.die.net/man/1/fakechroot .
Вы не получаете никаких новых разрешений, но если у вас есть каталог (например, fake-distro) перед вызовом
Это хорошая идея, но она, кажется, обрабатывает символические ссылки непредсказуемо. Мое ~/fake-distroиспользование BusyBox, которые символьные ссылки ls, mvи другие общие утилиты для /bin/busybox. Если я звоню явно /bin/busybox mv ..., все работает, но если я звоню, /bin/mv ...я получаю sh: /bin/mv: not found. Установка export FAKECHROOT_EXCLUDE_PATH=/перед запуском fakechroot исправляет этот симптом, но затем он ломается на других символических ссылках (например /usr/bin/vim -> /usr/bin/vim.vim).
Ponkadoodle
может быть, FAKECHROOT_EXCLUDE_PATH = /: / usr поможет, тогда?
sylvainulg
1
Похоже, что с пространствами имен пользователей фактически возможно выполнить chroot без root. Вот пример программы, которая демонстрирует, что это возможно. Я только начал исследовать, как работают пространства имен linux, и поэтому я не совсем уверен, является ли этот код наилучшей практикой или нет.
Сохранить как user_chroot.cc. Компилировать с g++ -o user_chroot user_chroot.cc. Использование есть ./user_chroot /path/to/new_rootfs.
// references:
// [1]: http://man7.org/linux/man-pages/man7/user_namespaces.7.html
// [2]: http://man7.org/linux/man-pages/man2/unshare.2.html
#include <sched.h>
#include <sys/types.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <cerrno>
#include <cstdio>
#include <cstring>
int main(int argc, char** argv) {
if(argc < 2) {
printf("Usage: %s <rootfs>\n", argv[0]);
}
int uid = getuid();
int gid = getgid();
printf("Before unshare, uid=%d, gid=%d\n", uid, gid);
// First, unshare the user namespace and assume admin capability in the
// new namespace
int err = unshare(CLONE_NEWUSER);
if(err) {
printf("Failed to unshare user namespace\n");
return 1;
}
// write a uid/gid map
char file_path_buf[100];
int pid = getpid();
printf("My pid: %d\n", pid);
sprintf(file_path_buf, "/proc/%d/uid_map", pid);
int fd = open(file_path_buf, O_WRONLY);
if(fd == -1) {
printf("Failed to open %s for write [%d] %s\n", file_path_buf, errno,
strerror(errno));
} else {
printf("Writing : %s (fd=%d)\n", file_path_buf, fd);
err = dprintf(fd, "%d %d 1\n", uid, uid);
if(err == -1) {
printf("Failed to write contents [%d]: %s\n", errno,
strerror(errno));
}
close(fd);
}
sprintf(file_path_buf, "/proc/%d/setgroups", pid);
fd = open(file_path_buf, O_WRONLY);
if(fd == -1) {
printf("Failed to open %s for write [%d] %s\n", file_path_buf, errno,
strerror(errno));
} else {
dprintf(fd, "deny\n");
close(fd);
}
sprintf(file_path_buf, "/proc/%d/gid_map", pid);
fd = open(file_path_buf, O_WRONLY);
if(fd == -1) {
printf("Failed to open %s for write [%d] %s\n", file_path_buf, errno,
strerror(errno));
} else {
printf("Writing : %s (fd=%d)\n", file_path_buf, fd);
err = dprintf(fd, "%d %d 1\n", gid, gid);
if(err == -1) {
printf("Failed to write contents [%d]: %s\n", errno,
strerror(errno));
}
close(fd);
}
// Now chroot into the desired directory
err = chroot(argv[1]);
if(err) {
printf("Failed to chroot\n");
return 1;
}
// Now drop admin in our namespace
err = setresuid(uid, uid, uid);
if(err) {
printf("Failed to set uid\n");
}
err = setresgid(gid, gid, gid);
if(err) {
printf("Failed to set gid\n");
}
// and start a shell
char argv0[] = "bash";
char* new_argv[] = {
argv0,
NULL
};
err = execvp("/bin/bash", new_argv);
if(err) {
perror("Failed to start shell");
return -1;
}
}
Я проверил это на минимальном rootfs, сгенерированном с помощью multiistrap (выполняется без полномочий root). Некоторые системные файлы, такие как /etc/passwdи /etc/groupsбыли скопированы из rootfs хоста в гостевые rootfs.
Сбой Failed to unshare user namespaceдля меня на Linux 4.12.10 (Arch Linux).
Ponkadoodle
@wallacoloo, возможно, измените printf () на perror () и посмотрите, что было на самом деле. обратитесь к man7.org/linux/man-pages/man2/unshare.2.html, чтобы узнать, какие коды ошибок могут возникнуть в результате неудачного unshareвызова. Вы также можете попробовать эту версию питона , которая может иметь более сообщений об ошибке: github.com/cheshirekow/uchroot
Нет. Если я правильно помню, есть какая-то вещь уровня ядра, которую делает chroot, которая предотвращает это. Я не помню, что это была за вещь. Я исследовал это, когда возился с инструментом Gentoo Catalyst Build (и chroot в gentoo такой же, как chroot в ubuntu). Хотя было бы возможно сделать это без passwd ... но такие вещи остаются в сфере потенциальных уязвимостей безопасности и убедиться, что вы знаете, что делаете.
Ответы:
В Linux системный вызов chroot (2) может быть выполнен только привилегированным процессом. Способность, в которой нуждается процесс, является CAP_SYS_CHROOT.
Причина, по которой вы не можете использовать chroot как пользователя, довольно проста. Предположим, у вас есть программа setuid, такая как sudo, которая проверяет / etc / sudoers, если вам разрешено что-то делать. Теперь поместите его в chroot chroot с вашим собственным / etc / sudoers. Внезапно вы получаете мгновенное повышение привилегий.
Можно спроектировать программу для самореализации и запуска ее как процесса setuid, но это обычно считается плохим дизайном. Дополнительная безопасность chroot не мотивирует проблемы безопасности с setuid.
источник
chroot
затем выполнить его .@ imz - IvanZakharyaschev комментирует ответ pehrs, что это может быть возможно с введением пространств имен, но это не было проверено и опубликовано как ответ. Да, это действительно позволяет пользователю без полномочий root использовать chroot.
При наличии статически связанной
dash
, статически связаннойbusybox
и работающейbash
оболочки, работающей без полномочий root:Идентификатор пользователя root в этом пространстве имен сопоставляется с идентификатором пользователя без полномочий root вне этого пространства имен, и наоборот, поэтому система показывает файлы, принадлежащие текущему пользователю, как принадлежащие идентификатору пользователя 0. Обычный
ls -al root
, безunshare
, делает показать их как принадлежащих текущему пользователю.Примечание: это хорошо известно , что процессы, которые способны использовать
chroot
, способны вырваться изchroot
. Такunshare -r
как предоставитchroot
разрешения обычному пользователю, это будет представлять угрозу безопасности, если это будет разрешено внутриchroot
среды. В самом деле, это не разрешено, и терпит неудачу с:которая соответствует документации unshare (2) :
источник
В наши дни вы хотите смотреть на LXC (Linux Containers) вместо chroot / BSD jail. Это где-то между chroot и виртуальной машиной, что дает вам большой контроль безопасности и общую настраиваемость. Я считаю, что все, что вам нужно, чтобы запустить его как пользователь, - это быть членом группы, которая владеет необходимыми файлами / устройствами, но могут также быть задействованы возможности / системные разрешения. В любом случае, это должно быть очень выполнимо, поскольку LXC появился совсем недавно, еще долго после того, как SELinux и т. Д. Был добавлен в ядро Linux.
Также имейте в виду, что вы можете просто писать скрипты как root, но давать пользователям безопасное разрешение на запуск этих скриптов (без пароля, если хотите, но убедитесь, что скрипт безопасен) с использованием sudo.
источник
Комбинация fakeroot / fakechroot дает симуляцию chroot для простых нужд, таких как создание tar-архивов, где файлы, по-видимому, принадлежат root. Справочная страница Fakechroot находится по адресу http://linux.die.net/man/1/fakechroot .
Вы не получаете никаких новых разрешений, но если у вас есть каталог (например, fake-distro) перед вызовом
теперь он ищет какую-то команду, как будто вы root и владеете всем в fake-distro.
источник
~/fake-distro
использование BusyBox, которые символьные ссылкиls
,mv
и другие общие утилиты для/bin/busybox
. Если я звоню явно/bin/busybox mv ...
, все работает, но если я звоню,/bin/mv ...
я получаюsh: /bin/mv: not found
. Установкаexport FAKECHROOT_EXCLUDE_PATH=/
перед запуском fakechroot исправляет этот симптом, но затем он ломается на других символических ссылках (например/usr/bin/vim -> /usr/bin/vim.vim
).Похоже, что с пространствами имен пользователей фактически возможно выполнить chroot без root. Вот пример программы, которая демонстрирует, что это возможно. Я только начал исследовать, как работают пространства имен linux, и поэтому я не совсем уверен, является ли этот код наилучшей практикой или нет.
Сохранить как
user_chroot.cc
. Компилировать сg++ -o user_chroot user_chroot.cc
. Использование есть./user_chroot /path/to/new_rootfs
.Я проверил это на минимальном rootfs, сгенерированном с помощью multiistrap (выполняется без полномочий root). Некоторые системные файлы, такие как
/etc/passwd
и/etc/groups
были скопированы из rootfs хоста в гостевые rootfs.источник
Failed to unshare user namespace
для меня на Linux 4.12.10 (Arch Linux).unshare
вызова. Вы также можете попробовать эту версию питона , которая может иметь более сообщений об ошибке: github.com/cheshirekow/uchrootНет. Если я правильно помню, есть какая-то вещь уровня ядра, которую делает chroot, которая предотвращает это. Я не помню, что это была за вещь. Я исследовал это, когда возился с инструментом Gentoo Catalyst Build (и chroot в gentoo такой же, как chroot в ubuntu). Хотя было бы возможно сделать это без passwd ... но такие вещи остаются в сфере потенциальных уязвимостей безопасности и убедиться, что вы знаете, что делаете.
источник