Chroot-Gefängnisse sind spezifisch für BSD. Eine Chroot unter Linux ist kein Gefängnis. Zuletzt habe ich überprüft, dass es nicht möglich war, als Benutzer zu chrooten.
Xenoterracide
1
@xenoterracide-Jails sind BSD-spezifisch, chroot wird in der Linux-Community jedoch allgemein als "chroot-Jail" bezeichnet. Es ist ziemlich verwirrt.
Pehrs
2
Was versuchst du zu tun und warum? Es gibt Tools wie fakechroot und schroot, die je nach Ihren Anforderungen eine praktikable Alternative darstellen.
Unter Linux kann der Systemaufruf chroot (2) nur von einem privilegierten Prozess ausgeführt werden. Die Fähigkeit, die der Prozess benötigt, ist CAP_SYS_CHROOT.
Der Grund, warum Sie als Benutzer nicht chroot können, ist ziemlich einfach. Angenommen, Sie haben ein Setuid-Programm wie sudo, das prüft, ob Sie etwas tun dürfen. Legen Sie es jetzt in eine Chroot-Chroot mit Ihren eigenen / etc / sudoers. Plötzlich haben Sie eine sofortige Privilegieneskalation.
Es ist möglich, ein Programm so zu entwerfen, dass es sich selbst in der Chroot-Umgebung befindet und als Setuid-Prozess ausgeführt wird. Dies wird jedoch im Allgemeinen als schlechtes Design angesehen. Die zusätzliche Sicherheit der Chroot motiviert die Sicherheitsprobleme mit der Setuid nicht.
Mit den neuen Möglichkeiten von Namespaces in Linux ist es vielleicht möglich, einen neuen "Benutzer" -Namespace zu erstellen (die Freigabe aufzuheben), in dem sich ein "eingebetteter" Root-Benutzer befindet, und chrootdann auszuführen .
imz - Ivan Zakharyaschev
1
@ imz - IvanZakharyaschev Sie haben absolut Recht, und ich hoffe, es macht Ihnen nichts aus, dass ich mir die Freiheit genommen habe, das als leicht überprüfbare Antwort aufzuschreiben.
HDV
@hvd Großartig! Es muss sehr nützlich sein, da es zeigt, wie die neuen ungewohnten Linux-Funktionen mit konkreten Befehlen verwendet werden.
imz - Ivan Zakharyaschev
6
@ imz - IvanZakharyaschev kommentiert die Antwort von pehrs, dass es mit der Einführung von Namespaces möglich sein könnte, aber dies wurde nicht getestet und als Antwort veröffentlicht. Ja, das ermöglicht es in der Tat einem Nicht-Root-Benutzer, chroot zu verwenden.
Bei einer statisch verknüpften dashund einer statisch verknüpften busyboxund einer ausgeführten bashShell, die als Nicht-Root ausgeführt wird:
Die Root - Benutzer - ID in diesem Namespace wird auf die Nicht-Root - Benutzer - ID außerhalb dieses Namensraumes abgebildet, und umgekehrt, weshalb die System zeigt Dateien , die von dem aktuellen Benutzer gehören , wie durch Benutzer - ID 0. Ein regelmäßigen Besitz ls -al root, ohne unshare, tun Zeigen Sie sie als Eigentum des aktuellen Benutzers an.
Hinweis: Es ist bekannt, dass Prozesse, die in der Lage sind, zu verwenden chroot, in der Lage sind, aus a auszubrechen chroot. Da einem normalen Benutzer Berechtigungen erteilt unshare -rwürden chroot, wäre dies ein Sicherheitsrisiko, wenn dies in einer chrootUmgebung zulässig wäre . In der Tat ist es nicht erlaubt und scheitert mit:
Freigabe aufheben: Freigabe fehlgeschlagen: Vorgang nicht zulässig
CLONE_NEWUSER wurde in Flags angegeben und der Aufrufer befindet sich in einer Chroot-Umgebung (dh das Stammverzeichnis des Aufrufers stimmt nicht mit dem Stammverzeichnis des Mount-Namespaces überein, in dem er sich befindet).
Das Ausführen von pivot_root in einem Mount-Namespace hat einen ähnlichen Effekt wie chroot, vermeidet jedoch den Konflikt mit Benutzernamensräumen.
Timothy Baldwin
1
Man kann einem chroot- oder mount-Namespace entkommen, indem man nach / proc absteigt, wenn es sich um einen Prozess außerhalb mit derselben UID in demselben oder untergeordneten PID- und Benutzernamensräumen handelt.
Timothy Baldwin
2
In diesen Tagen möchten Sie sich mit LXC (Linux Containers) anstatt mit chroot / BSD befassen. Es liegt irgendwo zwischen einer Chroot und einer virtuellen Maschine und bietet Ihnen viel Sicherheitskontrolle und allgemeine Konfigurierbarkeit. Ich glaube, Sie müssen nur Mitglied der Gruppe sein, die die erforderlichen Dateien / Geräte besitzt. Möglicherweise sind jedoch auch Funktionen / Systemberechtigungen erforderlich. Auf jeden Fall sollte es sehr machbar sein, da LXC ziemlich neu ist, lange nachdem SELinux etc. zum Linux-Kernel hinzugefügt wurde.
Denken Sie auch daran, dass Sie Skripte nur als root schreiben können, den Benutzern jedoch die sichere Berechtigung erteilen, diese Skripte mit sudo auszuführen (wenn Sie möchten, müssen Sie jedoch sicherstellen, dass das Skript sicher ist).
Die Kombination von fakeroot / fakechroot ergibt eine Chroot-Simulation für einfache Anforderungen wie das Erstellen von Tar-Archiven, bei denen Dateien anscheinend Eigentum von root zu sein scheinen. Fakechroot-Manpage ist http://linux.die.net/man/1/fakechroot .
Sie erhalten zwar keine neue Berechtigung, aber wenn Sie ein Verzeichnis besitzen (z. B. Fake-Distribution), bevor Sie es aufrufen
Dies ist eine nette Idee, aber sie scheint unvorhersehbar mit Symlinks umzugehen. Meiner ~/fake-distrobenutzt busybox, welche symlinks ls, mvund andere gängige Dienstprogramme dazu /bin/busybox. Wenn ich explizit anrufe /bin/busybox mv ..., funktionieren die Dinge, aber wenn ich anrufe, /bin/mv ...bekomme ich sh: /bin/mv: not found. Die Einstellung export FAKECHROOT_EXCLUDE_PATH=/vor dem Ausführen von fakechroot behebt dieses Symptom, bricht dann jedoch bei anderen Symlinks (z /usr/bin/vim -> /usr/bin/vim.vim. B. ) ab.
Ponkadoodle
Vielleicht würde FAKECHROOT_EXCLUDE_PATH = /: / usr dann helfen?
Sylvainulg
1
Es scheint, dass es mit Benutzernamensräumen tatsächlich möglich ist, ohne root zu chrooten. Hier ist ein Beispielprogramm, das zeigt, dass es möglich ist. Ich habe erst begonnen zu untersuchen, wie Linux-Namespaces funktionieren, und bin mir daher nicht ganz sicher, ob dieser Code die beste Vorgehensweise ist oder nicht.
Speichern unter user_chroot.cc. Kompilieren mit g++ -o user_chroot user_chroot.cc. Verwendung ist ./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;
}
}
Ich habe dies auf einem minimalen rootfs getestet, das mit multistrap erzeugt wurde (ausgeführt als Nicht-root). Einige Systemdateien mögen /etc/passwdund /etc/groupswurden von den Host-Rootfs in die Gast-Rootfs kopiert.
Scheitert bei Failed to unshare user namespacemir unter Linux 4.12.10 (Arch Linux).
Ponkadoodle
@wallacoloo vielleicht printf () zu perror () ändern und sehen, was der eigentliche Fehler war. In man7.org/linux/man-pages/man2/unshare.2.html erfahren Sie, welche Fehlercodes aus einem erfolglosen unshareAnruf resultieren können . Sie können auch diese Python - Version versuchen , die besser Störmeldeversand haben könnte: github.com/cheshirekow/uchroot
Nein. Wenn ich mich richtig erinnere, gibt es eine Kernel-Level-Sache, die Chroot tut, um dies zu verhindern. Ich kann mich nicht erinnern, was das für ein Ding war. Ich habe es untersucht, als ich mit Gentoos Catalyst Build-Tool rumgespielt habe (und ein Chroot unter Gentoo ist dasselbe wie ein Chroot unter Ubuntu). Es wäre zwar möglich, dies ohne ein Passwort zu erreichen ... aber solche Dinge sind dem Bereich potenzieller Sicherheitslücken überlassen und stellen sicher, dass Sie wissen, was Sie tun.
Antworten:
Unter Linux kann der Systemaufruf chroot (2) nur von einem privilegierten Prozess ausgeführt werden. Die Fähigkeit, die der Prozess benötigt, ist CAP_SYS_CHROOT.
Der Grund, warum Sie als Benutzer nicht chroot können, ist ziemlich einfach. Angenommen, Sie haben ein Setuid-Programm wie sudo, das prüft, ob Sie etwas tun dürfen. Legen Sie es jetzt in eine Chroot-Chroot mit Ihren eigenen / etc / sudoers. Plötzlich haben Sie eine sofortige Privilegieneskalation.
Es ist möglich, ein Programm so zu entwerfen, dass es sich selbst in der Chroot-Umgebung befindet und als Setuid-Prozess ausgeführt wird. Dies wird jedoch im Allgemeinen als schlechtes Design angesehen. Die zusätzliche Sicherheit der Chroot motiviert die Sicherheitsprobleme mit der Setuid nicht.
quelle
chroot
dann auszuführen .@ imz - IvanZakharyaschev kommentiert die Antwort von pehrs, dass es mit der Einführung von Namespaces möglich sein könnte, aber dies wurde nicht getestet und als Antwort veröffentlicht. Ja, das ermöglicht es in der Tat einem Nicht-Root-Benutzer, chroot zu verwenden.
Bei einer statisch verknüpften
dash
und einer statisch verknüpftenbusybox
und einer ausgeführtenbash
Shell, die als Nicht-Root ausgeführt wird:Die Root - Benutzer - ID in diesem Namespace wird auf die Nicht-Root - Benutzer - ID außerhalb dieses Namensraumes abgebildet, und umgekehrt, weshalb die System zeigt Dateien , die von dem aktuellen Benutzer gehören , wie durch Benutzer - ID 0. Ein regelmäßigen Besitz
ls -al root
, ohneunshare
, tun Zeigen Sie sie als Eigentum des aktuellen Benutzers an.Hinweis: Es ist bekannt, dass Prozesse, die in der Lage sind, zu verwenden
chroot
, in der Lage sind, aus a auszubrechenchroot
. Da einem normalen Benutzer Berechtigungen erteiltunshare -r
würdenchroot
, wäre dies ein Sicherheitsrisiko, wenn dies in einerchroot
Umgebung zulässig wäre . In der Tat ist es nicht erlaubt und scheitert mit:welche mit der Dokumentation von unshare (2) übereinstimmt :
quelle
In diesen Tagen möchten Sie sich mit LXC (Linux Containers) anstatt mit chroot / BSD befassen. Es liegt irgendwo zwischen einer Chroot und einer virtuellen Maschine und bietet Ihnen viel Sicherheitskontrolle und allgemeine Konfigurierbarkeit. Ich glaube, Sie müssen nur Mitglied der Gruppe sein, die die erforderlichen Dateien / Geräte besitzt. Möglicherweise sind jedoch auch Funktionen / Systemberechtigungen erforderlich. Auf jeden Fall sollte es sehr machbar sein, da LXC ziemlich neu ist, lange nachdem SELinux etc. zum Linux-Kernel hinzugefügt wurde.
Denken Sie auch daran, dass Sie Skripte nur als root schreiben können, den Benutzern jedoch die sichere Berechtigung erteilen, diese Skripte mit sudo auszuführen (wenn Sie möchten, müssen Sie jedoch sicherstellen, dass das Skript sicher ist).
quelle
Die Kombination von fakeroot / fakechroot ergibt eine Chroot-Simulation für einfache Anforderungen wie das Erstellen von Tar-Archiven, bei denen Dateien anscheinend Eigentum von root zu sein scheinen. Fakechroot-Manpage ist http://linux.die.net/man/1/fakechroot .
Sie erhalten zwar keine neue Berechtigung, aber wenn Sie ein Verzeichnis besitzen (z. B. Fake-Distribution), bevor Sie es aufrufen
Es sieht jetzt so aus, als ob Sie root sind und alles in der gefälschten Distribution besitzen.
quelle
~/fake-distro
benutzt busybox, welche symlinksls
,mv
und andere gängige Dienstprogramme dazu/bin/busybox
. Wenn ich explizit anrufe/bin/busybox mv ...
, funktionieren die Dinge, aber wenn ich anrufe,/bin/mv ...
bekomme ichsh: /bin/mv: not found
. Die Einstellungexport FAKECHROOT_EXCLUDE_PATH=/
vor dem Ausführen von fakechroot behebt dieses Symptom, bricht dann jedoch bei anderen Symlinks (z/usr/bin/vim -> /usr/bin/vim.vim
. B. ) ab.Es scheint, dass es mit Benutzernamensräumen tatsächlich möglich ist, ohne root zu chrooten. Hier ist ein Beispielprogramm, das zeigt, dass es möglich ist. Ich habe erst begonnen zu untersuchen, wie Linux-Namespaces funktionieren, und bin mir daher nicht ganz sicher, ob dieser Code die beste Vorgehensweise ist oder nicht.
Speichern unter
user_chroot.cc
. Kompilieren mitg++ -o user_chroot user_chroot.cc
. Verwendung ist./user_chroot /path/to/new_rootfs
.Ich habe dies auf einem minimalen rootfs getestet, das mit multistrap erzeugt wurde (ausgeführt als Nicht-root). Einige Systemdateien mögen
/etc/passwd
und/etc/groups
wurden von den Host-Rootfs in die Gast-Rootfs kopiert.quelle
Failed to unshare user namespace
mir unter Linux 4.12.10 (Arch Linux).unshare
Anruf resultieren können . Sie können auch diese Python - Version versuchen , die besser Störmeldeversand haben könnte: github.com/cheshirekow/uchrootNein. Wenn ich mich richtig erinnere, gibt es eine Kernel-Level-Sache, die Chroot tut, um dies zu verhindern. Ich kann mich nicht erinnern, was das für ein Ding war. Ich habe es untersucht, als ich mit Gentoos Catalyst Build-Tool rumgespielt habe (und ein Chroot unter Gentoo ist dasselbe wie ein Chroot unter Ubuntu). Es wäre zwar möglich, dies ohne ein Passwort zu erreichen ... aber solche Dinge sind dem Bereich potenzieller Sicherheitslücken überlassen und stellen sicher, dass Sie wissen, was Sie tun.
quelle