Po przeczytaniu o przestrzeniach nazw Linuksa miałem wrażenie, że są one, wśród wielu innych funkcji, alternatywą dla chroot. Na przykład w tym artykule :
Inne zastosowania [przestrzeni nazw] obejmują [...] chroot () - izolację stylu procesu od części hierarchii pojedynczego katalogu.
Jednak gdy klonuję przestrzeń nazw montowania, na przykład za pomocą następującego polecenia, nadal widzę całe oryginalne drzewo główne.
unshare --mount -- /bin/bash
Rozumiem, że jestem teraz w stanie wykonać dodatkowe montowania w nowej przestrzeni nazw, które nie są współużytkowane z oryginalną przestrzenią nazw, a zatem zapewnia izolację, ale wciąż jest to ten sam katalog główny, np. /etc
Wciąż jest taki sam dla obu przestrzeni nazw. Czy nadal muszę chroot
zmienić root lub czy istnieje alternatywa?
Spodziewałem się, że to pytanie dostarczy odpowiedzi, ale odpowiedź tylko się chroot
powtórzy.
EDYCJA 1
Był już usunięty komentarz, który wspomniał pivot_root
. Ponieważ jest to faktycznie część linux/fs/namespace.c
, jest to faktycznie część implementacji przestrzeni nazw. Sugeruje to, że zmiana katalogu głównego tylko za pomocą unshare
i mount
nie jest możliwa, ale przestrzenie nazw zapewniają własną - bardziej sprytną - wersję chroot
. Nadal nie rozumiem tego podejścia, które zasadniczo różni się od niego chroot
, nawet po przeczytaniu kodu źródłowego (w sensie np. Bezpieczeństwa lub lepszej izolacji).
EDYCJA 2
To nie jest duplikat tego pytania . Po wykonaniu wszystkich poleceń z odpowiedzi mam osobne /tmp/tmp.vyM9IwnKuY (lub podobne), ale katalog główny jest nadal taki sam!
pivot_root
ichroot
: Rzuciłem okiem na źródła Dockera i stwierdziłem, że jeśli nie powiedzie siępivot_root
, to wraca dochroot
, tj. Mechanizmy te są uważane za co najmniej podobne pod względem funkcjonalności do celów konteneryzacji.Odpowiedzi:
Wprowadzenie przestrzeni nazw montowania przed skonfigurowaniem a
chroot
pozwala uniknąć zaśmiecania przestrzeni nazw hosta dodatkowymi montowaniami, np/proc
. Dla . Możesz użyćchroot
wewnątrz przestrzeni nazw montowania jako przyjemnego i prostego hacka.Myślę, że zrozumienie
pivot_root
ma wiele zalet , ale ma trochę krzywej uczenia się. Dokumentacja nie wyjaśnia wszystkiego ... chociaż istnieje przykład użycia wman 8 pivot_root
(dla polecenia powłoki).man 2 pivot_root
(dla wywołania systemowego) może być jaśniejsze, jeśli zrobiłby to samo i zawierał przykładowy program C.Jak korzystać z pivot_root
Natychmiast po wejściu w przestrzeń nazw montowania potrzebujesz także
mount --make-rslave /
lub jej odpowiednika. W przeciwnym razie wszystkie zmiany montowania zostaną propagowane do montowań w oryginalnej przestrzeni nazw, w tympivot_root
. Nie chcesz tego :).Jeśli użyłeś
unshare --mount
polecenia, pamiętaj, żemount --make-rprivate
domyślnie jest to udokumentowane . AFAICS to złe ustawienie domyślne i nie chcesz tego w kodzie produkcyjnym. Na przykład w tym momencie przestanieeject
działać na zamontowanym dysku DVD lub USB w obszarze nazw hosta. DVD lub USB pozostałyby zamontowane wewnątrz prywatnego drzewa montowania, a jądro nie pozwoliłoby na wysunięcie DVD.Gdy to zrobisz, możesz zamontować np.
/proc
Katalog, którego będziesz używać. Taki sam sposób, w jaki byś to zrobiłchroot
.W przeciwieństwie do użycia
chroot
,pivot_root
wymaga, aby nowy główny system plików był punktem podłączenia. Jeśli nie jest to jeden już można zaspokoić to po prostu stosując zamontować wiążą:mount --rbind new_root new_root
.Użyj
pivot_root
- a następnieumount
starego systemu plików root z opcją-l
/MNT_DETACH
. ( Nie potrzebujeszumount -R
, co może potrwać dłużej. ).Technicznie korzystanie z
pivot_root
ogólnie musi również obejmować korzystaniechroot
; to nie jest „albo-albo”.Zgodnie
man 2 pivot_root
z definicją jest to definiowane tylko jako zamiana katalogu głównego przestrzeni nazw montowania. Nie jest zdefiniowane, aby zmieniać katalog fizyczny, na który wskazuje katalog główny procesu. Lub bieżący katalog roboczy (/proc/self/cwd
). Zdarza się, że tak się dzieje, ale jest to włamanie do obsługi wątków jądra. Strona twierdzi, że może się to zmienić w przyszłości.Zwykle chcesz tę sekwencję:
Stanowisko
chroot
w tej sekwencji to kolejny subtelny szczegół . Chociażpivot_root
chodzi o zmianę rozmieszczenia przestrzeni nazw montowania, kod jądra wydaje się znaleźć główny system plików, aby się przenieść, patrząc na katalog główny root dla procesu, którychroot
ustawia.Dlaczego warto korzystać z pivot_root
Zasadniczo sensowne jest stosowanie
pivot_root
dla bezpieczeństwa i izolacji. Lubię myśleć o teorii bezpieczeństwa opartego na możliwościach . Przekazujesz listę konkretnych potrzebnych zasobów, a proces nie może uzyskać dostępu do innych zasobów. W tym przypadku mówimy o systemach plików przekazanych do przestrzeni nazw montowania. Ten pomysł ogólnie dotyczy funkcji „przestrzeni nazw” Linuksa, chociaż prawdopodobnie nie wyrażam tego zbyt dobrze.chroot
ustawia tylko katalog główny procesu, ale proces nadal odnosi się do przestrzeni nazw pełnego montowania. Jeśli proces zachowuje uprawnienia do wykonywaniachroot
, może wykonać kopię zapasową przestrzeni nazw systemu plików. Jak wyszczególniono wman 2 chroot
„superużytkownik może uciec z„ więzienia chroot ”do ...”.Innym prowokującym do myślenia sposobem cofnięcia
chroot
jestnsenter --mount=/proc/self/ns/mnt
. Jest to być może silniejszy argument za zasadą.nsenter
/setns()
koniecznie ponownie ładuje katalog główny procesu, z katalogu głównego przestrzeni nazw montowania ... chociaż fakt, że działa to, gdy oba odnoszą się do różnych katalogów fizycznych, może być uważany za błąd jądra. (Uwaga techniczna: w katalogu głównym może być zamontowanych wiele systemów plików jedna nad drugą;setns()
używa górnego, ostatnio zamontowanego).To pokazuje jedną zaletę połączenia przestrzeni nazw montowania z „przestrzenią nazw PID”. Przebywanie w przestrzeni nazw PID uniemożliwiłoby wejście do przestrzeni nazw montowania nieskończonego procesu. Zapobiega również wejściu do katalogu głównego nieskończonego procesu (
/proc/$PID/root
). I oczywiście przestrzeń nazw PID zapobiega również zabiciu dowolnego procesu, który jest poza nią :-).źródło
mount(NULL, "/", NULL, MS_REC|MS_PRIVATE, NULL)
umount -l ./oldroot
pivot_root(".", ".")
sztuczkę, która jest w rzeczywistości najłatwiejszym sposobem użyciapivot_root
w większości przypadków (nie jest tochroot
konieczne).