Co to znaczy, że kontener Linux (kontener LXC) nazywa się „nieuprzywilejowany”?
Co to znaczy, że kontener Linux (kontener LXC) nazywa się „nieuprzywilejowany”?
Odpowiedzi:
Nieuprzywilejowane kontenery LXC to te, które korzystają z przestrzeni nazw użytkowników ( userns ). Tj. Funkcja jądra, która pozwala na mapowanie zakresu identyfikatorów UID na hoście do przestrzeni nazw, w której użytkownik z UID 0 może ponownie istnieć.
W przeciwieństwie do mojego początkowego postrzegania nieuprzywilejowanych kontenerów LXC przez jakiś czas, nie oznacza to, że kontener musi być własnością nieuprzywilejowanego użytkownika hosta. To tylko jedna możliwość.
Istotne jest:
usermod [-v|-w|--add-sub-uids|--add-sub-gids]
)lxc.id_map = ...
)Więc nawet root
mogą posiadać nieuprzywilejowane kontenery, ponieważ skuteczne identyfikatory UID procesów kontenerowych na hoście znajdą się w zakresie określonym przez mapowanie.
Jednak root
najpierw musisz zdefiniować podrzędne identyfikatory. W przeciwieństwie do użytkowników utworzonych za pomocą adduser
, root
domyślnie nie będzie miał zakresu identyfikatorów podrzędnych.
Pamiętaj również, że masz do dyspozycji pełen zakres, więc możesz mieć 3 pojemniki z następującymi liniami konfiguracji (pokazano tylko mapowanie UID):
lxc.id_map = u 0 100000 100000
lxc.id_map = u 0 200000 100000
lxc.id_map = u 0 300000 100000
zakładając, że root
jest właścicielem podrzędnych identyfikatorów UID od 100000 do 400000. Cała znaleziona przeze mnie dokumentacja sugeruje użycie 65536 podrzędnych identyfikatorów na kontener, niektórzy używają 100000, aby uczynić go bardziej czytelnym dla człowieka.
Innymi słowy: Nie musisz przypisywać tego samego zakresu do każdego kontenera.
Z ponad 4 miliardami (~ 2^32
) możliwych podrzędnych identyfikatorów, co oznacza, że możesz być hojny, gdy podchodzisz do podległych zakresów użytkownikom hosta.
Wcierać to ponownie. Nieuprzywilejowany gość LXC nie musi być uruchamiany przez nieuprzywilejowanego użytkownika na hoście.
Konfigurowanie kontenera z podrzędnym odwzorowaniem UID / GID w następujący sposób:
lxc.id_map = u 0 100000 100000
lxc.id_map = g 0 100000 100000
gdy użytkownik root
hosta posiada podany zakres identyfikatora, pozwoli ci jeszcze bardziej ograniczyć gości.
Istnieje jednak jedna ważna dodatkowa zaleta w takim scenariuszu (i tak, sprawdziłem, czy to działa): możesz automatycznie uruchomić swój kontener podczas uruchamiania systemu.
Zwykle podczas przeszukiwania sieci w poszukiwaniu informacji o LXC zostaniesz poinformowany, że nie jest możliwe automatyczne uruchomienie nieuprzywilejowanego gościa LXC. Jest to jednak prawdą domyślnie tylko w przypadku kontenerów, które nie znajdują się w ogólnosystemowej pamięci masowej kontenerów (zwykle coś podobnego /var/lib/lxc
). Jeśli są (co zwykle oznacza, że zostały utworzone przez root i są uruchamiane przez root), to jest zupełnie inna historia.
lxc.start.auto = 1
wykona to zadanie całkiem nieźle, po umieszczeniu go w konfiguracji kontenera.
Sam się z tym trochę zmagałem, więc dodaję tutaj sekcję.
Oprócz dołączonego fragmentu konfiguracji, za pomocą lxc.include
którego zwykle występuje nazwa /usr/share/lxc/config/$distro.common.conf
(gdzie $distro
jest nazwą dystrybucji), powinieneś sprawdzić, czy /usr/share/lxc/config/$distro.userns.conf
w systemie jest też jakiś znak , i również to uwzględnić. Na przykład:
lxc.include = /usr/share/lxc/config/ubuntu.common.conf
lxc.include = /usr/share/lxc/config/ubuntu.userns.conf
Ponadto dodaj mapowania podległych identyfikatorów:
lxc.id_map = u 0 100000 65535
lxc.id_map = g 0 100000 65535
co oznacza, że identyfikator UID hosta 100000 znajduje się root
w przestrzeni nazw użytkownika gościa LXC.
Teraz upewnij się, że uprawnienia są prawidłowe. Jeśli nazwa gościa byłaby przechowywana w zmiennej środowiskowej $lxcguest
, uruchomiłbyś następujące czynności:
# Directory for the container
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest
chmod ug=rwX,o=rX $(lxc-config lxc.lxcpath)/$lxcguest
# Container config
chown root:root $(lxc-config lxc.lxcpath)/$lxcguest/config
chmod u=rw,go=r $(lxc-config lxc.lxcpath)/$lxcguest/config
# Container rootfs
chown 100000:100000 $(lxc-config lxc.lxcpath)/$lxcguest/rootfs
chmod u=rwX,go=rX $(lxc-config lxc.lxcpath)/$lxcguest/rootfs
Powinno to pozwolić na uruchomienie kontenera po pierwszej próbie wystąpienia błędów związanych z uprawnieniami.
chroot
tym może pomóc, ale LXC łączy różne przestrzenie nazw (UTS, mount itp.), Aby spenetrować cały system.
unshare
już powiedziałem, robi to znakomicie dla dowolnej / wszystkich różnych przestrzeni nazw - a nawet zapewni ci oddzielny, prywatny /proc
montaż z jednym przełącznikiem cli. Jeśli twoja pojedyncza aplikacja jest, init
a Twoja chroot
jest initramfs
, otrzymasz cały pojemnik w kilka sekund.
Aby nawiązanie na 0xC0000022L, którego rozwiązanie działało w porządku dla mnie, napisałem increase-uid-gid.pl skrypt Perla do automatyzacji niezbędne posiadanie wymaganych zmian więc pliki w pojemnikach lxc są prawidłowo odwzorowane.
Bez tego, przy tej proponowanej konfiguracji, plik w katalogu głównym kontenera LXC należącym do 0 / root na głównym hoście, w samym kontenerze LXC, zostanie zmapowany na 65534 / nobody. Aby zostać zamapowanym na 0 / root w kontenerze LXC, muszą należeć do 100000 na hoście.
Jest to opisane tutaj https://yeupou.wordpress.com/2017/06/23/setting-up-lxc-containers-with-mapped-giduid/, a skrypt można uzyskać bezpośrednio na gitlab https://gitlab.com /yeupou/stalag13/blob/master/usr/local/bin/increase-uid-gid.pl
lxc
nie jest to konieczne. Za pomocą tegoutil-linux
narzędzia można utworzyć dowolny kontener przestrzeni nazwunshare
. Do tego kontenera możesz wejść za pomocąutil-linux
narzędziansenter
. To drugie narzędzie pozwala również dodawać uruchomione procesy do już utworzonego kontenera bez niego. Obsługa przestrzeni nazw jest zaimplementowana w jądrze.