Co to jest nieuprzywilejowany kontener LXC?


20

Co to znaczy, że kontener Linux (kontener LXC) nazywa się „nieuprzywilejowany”?

Odpowiedzi:


20

Nieuprzywilejowane kontenery LXC to te, które korzystają z przestrzeni nazw użytkowników ( ). 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:

  1. że zakres podrzędnych identyfikatorów UID i GID jest zdefiniowany dla użytkownika hosta ( usermod [-v|-w|--add-sub-uids|--add-sub-gids])
  2. ... i że ten zakres jest mapowany w konfiguracji kontenera ( lxc.id_map = ...)

Więc nawet rootmogą posiadać nieuprzywilejowane kontenery, ponieważ skuteczne identyfikatory UID procesów kontenerowych na hoście znajdą się w zakresie określonym przez mapowanie.

Jednak rootnajpierw musisz zdefiniować podrzędne identyfikatory. W przeciwieństwie do użytkowników utworzonych za pomocą adduser, rootdomyś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):

  1. lxc.id_map = u 0 100000 100000
  2. lxc.id_map = u 0 200000 100000
  3. lxc.id_map = u 0 300000 100000

zakładając, że rootjest 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.

Nieuprzywilejowany kontener będący własnością i uruchamiany przez root

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 roothosta 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.

Właściwe uzyskiwanie uprawnień i konfiguracji

Sam się z tym trochę zmagałem, więc dodaję tutaj sekcję.

Oprócz dołączonego fragmentu konfiguracji, za pomocą lxc.includektórego zwykle występuje nazwa /usr/share/lxc/config/$distro.common.conf(gdzie $distrojest nazwą dystrybucji), powinieneś sprawdzić, czy /usr/share/lxc/config/$distro.userns.confw 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.


4
Dobra odpowiedź - ale lxcnie jest to konieczne. Za pomocą tego util-linuxnarzędzia można utworzyć dowolny kontener przestrzeni nazw unshare. Do tego kontenera możesz wejść za pomocą util-linuxnarzędzia nsenter. 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.
mikeserv

4
@mikeserv: masz na myśli, że nie potrzebujesz LXC, aby korzystać z userns ? Wiedziałem to. Wiem również, że Docker ma teraz własną bibliotekę korzystającą z tych udogodnień. Ale w jaki sposób spakowałbyś cały system bez pomocy udogodnień oferowanych przez LXC? A dlaczego miałbyś to zrobić? Mam na myśli to, że zawiera jedną aplikację, co w połączeniu z chroottym może pomóc, ale LXC łączy różne przestrzenie nazw (UTS, mount itp.), Aby spenetrować cały system.
0xC0000022L

2
Cóż ... Jak unsharejuż powiedziałem, robi to znakomicie dla dowolnej / wszystkich różnych przestrzeni nazw - a nawet zapewni ci oddzielny, prywatny /procmontaż z jednym przełącznikiem cli. Jeśli twoja pojedyncza aplikacja jest, inita Twoja chrootjest initramfs, otrzymasz cały pojemnik w kilka sekund.
mikeserv

0

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

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.