las cárceles chroot son específicas de bsd. un chroot en linux no es una cárcel. La última vez que verifiqué que no era posible hacer un chroot como usuario.
xenoterracide
1
@xenoterracide Las cárceles son específicas de BSD, pero chroot se conoce comúnmente como una "cárcel chroot" en la comunidad Linux. Está bastante confundido.
pehrs
2
¿Qué intentas hacer y por qué? Existen herramientas como fakechroot y schroot que brindan una alternativa viable según sus requisitos.
En Linux, la llamada al sistema chroot (2) solo se puede realizar mediante un proceso con privilegios. La capacidad que necesita el proceso es CAP_SYS_CHROOT.
La razón por la que no puedes hacer chroot como usuario es bastante simple. Suponga que tiene un programa setuid como sudo que comprueba / etc / sudoers si se le permite hacer algo. Ahora póngalo en un chroot chroot con sus propios / etc / sudoers. De repente tienes una escalada de privilegios instantánea.
Es posible diseñar un programa para que se ejecute a sí mismo y ejecutarlo como un proceso setuid, pero esto generalmente se considera un mal diseño. La seguridad adicional del chroot no motiva los problemas de seguridad con el setuid.
Con las nuevas posibilidades de espacios de nombres en Linux, tal vez sea posible crear (no compartir) un nuevo espacio de nombres "usuario", donde habría un usuario raíz "incrustado", y chrootluego realizarlo .
imz - Ivan Zakharyaschev
1
@ imz - IvanZakharyaschev Tienes toda la razón, y espero que no te importe que me haya tomado la libertad de escribir eso como una respuesta fácilmente comprobable.
hvd
@hvd ¡Genial! Debe ser muy útil, ya que demuestra cómo usar las nuevas características desconocidas de Linux con comandos concretos.
imz - Ivan Zakharyaschev
6
@ imz - IvanZakharyaschev comenta sobre la respuesta de pehrs de que puede ser posible con la introducción de espacios de nombres, pero esto no ha sido probado y publicado como respuesta. Sí, eso sí hace posible que un usuario no root use chroot.
Dado un enlace estático dash, y un enlace estático busybox, y una ejecuciónbash shell en ejecución que se ejecuta como no root:
La ID de usuario raíz en ese espacio de nombres se asigna a la ID de usuario no root fuera de ese espacio de nombres, y viceversa, razón por la cual el sistema muestra los archivos propiedad del usuario actual como propiedad de la ID de usuario 0. Una regular ls -al root, sinunshare , hace mostrarlos como propiedad del usuario actual.
Nota: es bien sabido que los procesos que son capaces de usar chroot, son capaces de salir de a chroot. Dado unshare -rque otorgaría chrootpermisos a un usuario ordinario, sería un riesgo de seguridad si se permitiera dentro de unchroot entorno. De hecho, no está permitido y falla con:
CLONE_NEWUSER se especificó en banderas y la persona que llama está en un entorno chroot (es decir, el directorio raíz de la persona que llama no coincide con el directorio raíz del espacio de nombres de montaje en el que reside).
Ejecutar pivot_root en un espacio de nombres de montaje tiene un efecto similar a chroot pero evita el conflicto con los espacios de nombres de usuario.
Timothy Baldwin
1
Se puede escapar de un espacio de nombres chroot o mount descendiendo a / proc si es un proceso externo con el mismo UID en el mismo PID o espacio de nombres de usuario.
Timothy Baldwin
2
En estos días, desea mirar LXC (Contenedores de Linux) en lugar de la cárcel chroot / BSD. Está en algún lugar entre un chroot y una máquina virtual, lo que le brinda mucho control de seguridad y una configuración general. Creo que todo lo que necesita para ejecutarlo como usuario es ser miembro del grupo que posee los archivos / dispositivos necesarios, pero también puede haber capacidades / permisos del sistema involucrados. De cualquier manera, debería ser muy factible, ya que LXC es bastante reciente, mucho después de que SELinux, etc., se haya agregado al kernel de Linux.
Además, tenga en cuenta que solo puede escribir scripts como root, pero otorgue a los usuarios un permiso seguro para ejecutar esos scripts (sin una contraseña si lo desea, pero asegúrese de que el script sea seguro) usando sudo.
La combinación de fakeroot / fakechroot proporciona un simulacro de chroot para necesidades simples, como la producción de archivos tar donde los archivos parecen ser propiedad de root. La página de manual de Fakechroot es http://linux.die.net/man/1/fakechroot .
Sin embargo, no obtiene ningún permiso nuevo, pero si posee un directorio (p. Ej., False-distro) antes de invocar
Esta es una buena idea, pero parece manejar enlaces simbólicos de forma impredecible. My ~/fake-distrousa busybox, que enlaces simbólicos ls, mvy otras utilidades comunes para /bin/busybox. Si llamo explícitamente /bin/busybox mv ..., las cosas funcionan, pero si llamo /bin/mv ...obtengo sh: /bin/mv: not found. La configuración export FAKECHROOT_EXCLUDE_PATH=/antes de ejecutar el fakechroot corrige ese síntoma, pero luego se rompe en otros enlaces simbólicos (por ejemplo /usr/bin/vim -> /usr/bin/vim.vim).
Parece que con espacios de nombres de usuario es posible de hecho chroot sin root. Aquí hay un programa de ejemplo que demuestra que es posible. Solo he comenzado a explorar cómo funcionan los espacios de nombres de Linux y, por lo tanto, no estoy completamente seguro de si este código es la mejor práctica o no.
Guardar como user_chroot.cc. Compilar con g++ -o user_chroot user_chroot.cc. El uso es ./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;
}
}
He probado esto en un rootfs mínimo generado con multistrap (ejecutado como no root). Algunos archivos del sistema tienen gusto /etc/passwdy /etc/groupsfueron copiados de los rootfs del host en los rootfs invitados.
Failed to unshare user namespaceMe falla en Linux 4.12.10 (Arch Linux).
Ponkadoodle
@wallacoloo quizás modifique printf () a perror () y vea cuál fue el error real. consulte man7.org/linux/man-pages/man2/unshare.2.html para ver qué códigos de error pueden resultar de una unsharellamada fallida . También puede probar esta versión de Python que podría tener mejores mensajes de error: github.com/cheshirekow/uchroot
No. Si recuerdo correctamente, hay algo de nivel de kernel que hace chroot que lo impide. No recuerdo qué era esa cosa. Lo investigué cuando me metí con la herramienta Catalyst Build de Gentoo (y un chroot en gentoo es lo mismo que un chroot en ubuntu). Aunque sería posible hacer que suceda sin una contraseña ... pero esas cosas se dejan al ámbito de las posibles vulnerabilidades de seguridad y se aseguran de que sepa lo que está haciendo.
Respuestas:
En Linux, la llamada al sistema chroot (2) solo se puede realizar mediante un proceso con privilegios. La capacidad que necesita el proceso es CAP_SYS_CHROOT.
La razón por la que no puedes hacer chroot como usuario es bastante simple. Suponga que tiene un programa setuid como sudo que comprueba / etc / sudoers si se le permite hacer algo. Ahora póngalo en un chroot chroot con sus propios / etc / sudoers. De repente tienes una escalada de privilegios instantánea.
Es posible diseñar un programa para que se ejecute a sí mismo y ejecutarlo como un proceso setuid, pero esto generalmente se considera un mal diseño. La seguridad adicional del chroot no motiva los problemas de seguridad con el setuid.
fuente
chroot
luego realizarlo .@ imz - IvanZakharyaschev comenta sobre la respuesta de pehrs de que puede ser posible con la introducción de espacios de nombres, pero esto no ha sido probado y publicado como respuesta. Sí, eso sí hace posible que un usuario no root use chroot.
Dado un enlace estático
dash
, y un enlace estáticobusybox
, y una ejecuciónbash
shell en ejecución que se ejecuta como no root:La ID de usuario raíz en ese espacio de nombres se asigna a la ID de usuario no root fuera de ese espacio de nombres, y viceversa, razón por la cual el sistema muestra los archivos propiedad del usuario actual como propiedad de la ID de usuario 0. Una regular
ls -al root
, sinunshare
, hace mostrarlos como propiedad del usuario actual.Nota: es bien sabido que los procesos que son capaces de usar
chroot
, son capaces de salir de achroot
. Dadounshare -r
que otorgaríachroot
permisos a un usuario ordinario, sería un riesgo de seguridad si se permitiera dentro de unchroot
entorno. De hecho, no está permitido y falla con:que coincide con el unshare (2) :
fuente
En estos días, desea mirar LXC (Contenedores de Linux) en lugar de la cárcel chroot / BSD. Está en algún lugar entre un chroot y una máquina virtual, lo que le brinda mucho control de seguridad y una configuración general. Creo que todo lo que necesita para ejecutarlo como usuario es ser miembro del grupo que posee los archivos / dispositivos necesarios, pero también puede haber capacidades / permisos del sistema involucrados. De cualquier manera, debería ser muy factible, ya que LXC es bastante reciente, mucho después de que SELinux, etc., se haya agregado al kernel de Linux.
Además, tenga en cuenta que solo puede escribir scripts como root, pero otorgue a los usuarios un permiso seguro para ejecutar esos scripts (sin una contraseña si lo desea, pero asegúrese de que el script sea seguro) usando sudo.
fuente
La combinación de fakeroot / fakechroot proporciona un simulacro de chroot para necesidades simples, como la producción de archivos tar donde los archivos parecen ser propiedad de root. La página de manual de Fakechroot es http://linux.die.net/man/1/fakechroot .
Sin embargo, no obtiene ningún permiso nuevo, pero si posee un directorio (p. Ej., False-distro) antes de invocar
ahora busca algún comando como si fuera root y sea dueño de todo dentro de fake-distro.
fuente
~/fake-distro
usa busybox, que enlaces simbólicosls
,mv
y otras utilidades comunes para/bin/busybox
. Si llamo explícitamente/bin/busybox mv ...
, las cosas funcionan, pero si llamo/bin/mv ...
obtengosh: /bin/mv: not found
. La configuraciónexport FAKECHROOT_EXCLUDE_PATH=/
antes de ejecutar el fakechroot corrige ese síntoma, pero luego se rompe en otros enlaces simbólicos (por ejemplo/usr/bin/vim -> /usr/bin/vim.vim
).Parece que con espacios de nombres de usuario es posible de hecho chroot sin root. Aquí hay un programa de ejemplo que demuestra que es posible. Solo he comenzado a explorar cómo funcionan los espacios de nombres de Linux y, por lo tanto, no estoy completamente seguro de si este código es la mejor práctica o no.
Guardar como
user_chroot.cc
. Compilar cong++ -o user_chroot user_chroot.cc
. El uso es./user_chroot /path/to/new_rootfs
.He probado esto en un rootfs mínimo generado con multistrap (ejecutado como no root). Algunos archivos del sistema tienen gusto
/etc/passwd
y/etc/groups
fueron copiados de los rootfs del host en los rootfs invitados.fuente
Failed to unshare user namespace
Me falla en Linux 4.12.10 (Arch Linux).unshare
llamada fallida . También puede probar esta versión de Python que podría tener mejores mensajes de error: github.com/cheshirekow/uchrootNo. Si recuerdo correctamente, hay algo de nivel de kernel que hace chroot que lo impide. No recuerdo qué era esa cosa. Lo investigué cuando me metí con la herramienta Catalyst Build de Gentoo (y un chroot en gentoo es lo mismo que un chroot en ubuntu). Aunque sería posible hacer que suceda sin una contraseña ... pero esas cosas se dejan al ámbito de las posibles vulnerabilidades de seguridad y se aseguran de que sepa lo que está haciendo.
fuente