Est-il possible pour un utilisateur non root d'exécuter un processus chroot sur Ubuntu?
Est-il possible pour un utilisateur non root d'exécuter un processus chroot sur Ubuntu?
Réponses:
Sous Linux, l' appel système chroot (2) ne peut être effectué que par un processus privilégié. La capacité dont le processus a besoin est CAP_SYS_CHROOT.
La raison pour laquelle vous ne pouvez pas chrooter en tant qu'utilisateur est assez simple. Supposons que vous ayez un programme setuid tel que sudo qui vérifie / etc / sudoers si vous êtes autorisé à faire quelque chose. Maintenant, mettez-le dans un chroot chroot avec vos propres / etc / sudoers. Soudain, vous avez une escalade de privilèges instantanée.
Il est possible de concevoir un programme pour se chrooter et l'exécuter en tant que processus setuid, mais cela est généralement considéré comme une mauvaise conception. La sécurité supplémentaire du chroot ne motive pas les problèmes de sécurité avec le setuid.
chroot
ensuite.
@ imz - IvanZakharyaschev commente la réponse de pehrs que cela pourrait être possible avec l'introduction d'espaces de noms, mais cela n'a pas été testé et publié comme réponse. Oui, cela permet en effet à un utilisateur non root d'utiliser chroot.
Étant donné un lien statique dash
, un lien statique busybox
et un bash
shell en cours d'exécution en tant que non root:
$ mkdir root
$ cp /path/to/dash root
$ cp /path/to/busybox root
$ unshare -r bash -c 'chroot root /dash -c "/busybox ls -al /"'
total 2700
drwxr-xr-x 2 0 0 4096 Dec 2 19:16 .
drwxr-xr-x 2 0 0 4096 Dec 2 19:16 ..
drwxr-xr-x 1 0 0 1905240 Dec 2 19:15 busybox
drwxr-xr-x 1 0 0 847704 Dec 2 19:15 dash
L'ID utilisateur racine dans cet espace de noms est mappé à l'ID utilisateur non root en dehors de cet espace de noms, et vice versa, c'est pourquoi le système affiche les fichiers appartenant à l'utilisateur actuel comme appartenant à l'ID utilisateur 0. Un standard ls -al root
, sans unshare
, ne les afficher comme appartenant à l'utilisateur actuel.
Remarque: il est bien connu que les processus qui sont capables d'utiliser chroot
, sont capables de sortir d'un chroot
. Étant donné que unshare -r
donnerait des chroot
autorisations à un utilisateur ordinaire, ce serait un risque pour la sécurité si cela était autorisé dans un chroot
environnement. En effet, il n'est pas autorisé et échoue avec:
unshare: unshare a échoué: opération non autorisée
qui correspond à la documentation unshare (2) :
EPERM (depuis Linux 3.9)
CLONE_NEWUSER a été spécifié dans des indicateurs et l'appelant est dans un environnement chroot (c'est-à-dire que le répertoire racine de l'appelant ne correspond pas au répertoire racine de l'espace de noms de montage dans lequel il réside).
De nos jours, vous voulez regarder LXC (conteneurs Linux) au lieu de la prison chroot / BSD. C'est quelque part entre un chroot et une machine virtuelle, ce qui vous donne beaucoup de contrôle de sécurité et de configurabilité générale. Je crois que tout ce dont vous avez besoin pour l'exécuter en tant qu'utilisateur est d'être membre du groupe qui possède les fichiers / périphériques nécessaires, mais il peut également y avoir des capacités / autorisations système impliquées. Quoi qu'il en soit, cela devrait être très faisable, car LXC est assez récent, longtemps après que SELinux etc. ait été ajouté au noyau Linux.
Gardez également à l'esprit que vous pouvez simplement écrire des scripts en tant que root mais donner aux utilisateurs une autorisation sécurisée pour exécuter ces scripts (sans mot de passe si vous le souhaitez, mais assurez-vous que le script est sécurisé) à l'aide de sudo.
La combinaison de fakeroot / fakechroot donne un simulacre de chroot pour des besoins simples tels que la production d'archives tar où les fichiers semblent appartenir à root. La page de manuel de Fakechroot est http://linux.die.net/man/1/fakechroot .
Vous n'obtenez cependant aucune nouvelle autorisation, mais si vous possédez un répertoire (par exemple, fake-distro) avant d'invoquer
fakechroot fakeroot chroot ~/fake-distro some-command
il recherche maintenant une commande comme si vous étiez root et que vous possédiez tout dans fake-distro.
~/fake-distro
utilisation busybox, qui symlinks ls
, mv
et d' autres utilitaires communs à /bin/busybox
. Si j'appelle explicitement /bin/busybox mv ...
, les choses fonctionnent, mais si j'appelle, /bin/mv ...
je reçois sh: /bin/mv: not found
. Le réglage export FAKECHROOT_EXCLUDE_PATH=/
avant d'exécuter le fakechroot corrige ce problème, mais il se casse ensuite sur d'autres liens symboliques (par exemple /usr/bin/vim -> /usr/bin/vim.vim
).
Il semble qu'avec les espaces de noms d'utilisateurs, il soit en fait possible de chrooter sans root. Voici un exemple de programme qui démontre que c'est possible. J'ai seulement commencé à explorer le fonctionnement des espaces de noms Linux et je ne suis donc pas tout à fait sûr de savoir si ce code est la meilleure pratique ou non.
Enregistrer sous user_chroot.cc
. Compilez avec g++ -o user_chroot user_chroot.cc
. L'utilisation est ./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;
}
}
J'ai testé cela sur un rootfs minimal généré avec multistrap (exécuté en tant que non root). Certains fichiers système aiment /etc/passwd
et /etc/groups
ont été copiés des rootfs hôtes vers les rootfs invités.
Failed to unshare user namespace
pour moi sur linux 4.12.10 (Arch Linux).
unshare
appel infructueux . Vous pouvez également essayer cette version de python qui pourrait avoir une meilleure messagerie d'erreur: github.com/cheshirekow/uchroot
Non. Si je me souviens bien, chroot fait quelque chose au niveau du noyau qui l'empêche. Je ne me souviens pas de ce que c'était. Je l'ai étudié en jouant avec l'outil Catalyst Build de Gentoo (et un chroot sur gentoo est identique à un chroot sur ubuntu). Bien qu'il soit possible de le faire sans un mot de passe ... mais de telles choses sont laissées au domaine des failles de sécurité potentielles et s'assurent que vous savez ce que vous faites.