Wybierz najmniej uprzywilejowany kontener Docker, gdy usługa jest dystrybuowana jako obraz i wymaga jedynie wąsko określonych plików, portów, urządzeń i możliwości. Wybierz dedykowany nieuprzywilejowany LXC, gdy usługa potrzebuje pełniejszego środowiska Linux, bezpośredniej integracji z systemem lub kilku powiązanych procesów działających w ramach jednego, oddzielnie zarządzanego gościa. Żaden z tych modeli nie pozostaje znaczącą granicą bezpieczeństwa po udostępnieniu szerokiego zakresu katalogów hosta, gniazda Dockera, nieograniczonego dostępu do urządzeń lub uprawnień roota na poziomie hosta.
Najpierw porównaj równoważne granice wdrożenia
Docker i LXC to technologie kontenerowe Linuksa, które współdzielą jądro hosta, ale zazwyczaj pakują różne jednostki. Docker zwykle izoluje jedną aplikację lub stos Compose. LXC tworzy lekki kontener systemowy z własnymi użytkownikami, bazą pakietów, usługami i systemowym systemem plików.
Uczciwe porównanie powinno więc obejmować aplikację Docker działającą bezpośrednio na hoście Linux oraz tę samą uprzywilejowaną usługę domową zainstalowaną w dedykowanym LXC. Nie chodzi tu o Dockera wewnątrz LXC w porównaniu z samym LXC ani o porównanie któregokolwiek z tych modeli z maszyną wirtualną korzystającą z osobnego jądra.
Istniejące porównanie ZimaSpace dotyczące Dockera i instalacji natywnych w LXC omawia pakowanie i utrzymanie. Ten artykuł wyodrębnia decyzję dotyczącą bezpieczeństwa w sytuacji, gdy usługa wymaga uprawnień osłabiających standardowe granice kontenera.
| Oś bezpieczeństwa | Kontener aplikacji Docker | Dedykowany kontener systemowy LXC |
|---|---|---|
| Podstawowa jednostka izolacji | Proces aplikacji i jego spakowane zależności | Przestrzeń użytkownika Linuksa z wieloma usługami i użytkownikami |
| Jądro hosta | Współdzielone z hostem | Współdzielone z hostem |
| Mapowanie roota | Domyślnie działa jako root, chyba że używane są przestrzenie nazw użytkowników lub tryb rootless | Może działać w trybie uprzywilejowanym lub mapować roota kontenera na nieuprzywilejowany identyfikator UID hosta |
| Dostęp do urządzeń | Można odwzorować pojedyncze urządzenia; tryb uprzywilejowany udostępnia je w szerokim zakresie | Węzły urządzeń hosta i uprawnienia można odwzorować w gościu |
| Pliki hosta | Montowania wiązane udostępniają wybrane ścieżki hosta bezpośrednio aplikacji | Montowania wiązane udostępniają ścieżki gościowi i każdemu uprawnionemu procesowi działającemu wewnątrz niego |
| Interfejs API administracyjny | Gniazdo Dockera może przyznać kontrolę nad hostem Dockera | Brak odpowiednika w postaci gniazda demona, chyba że wewnątrz LXC zainstalowano inne środowisko uruchomieniowe |
| Najlepsze zastosowanie | Pakietowa aplikacja o ściśle ograniczonych uprawnieniach | Usługa wymagająca integracji z systemem operacyjnym w ramach granicy nieuprzywilejowanego gościa |
Zacznij od dokładnych uprawnień wymaganych przez usługę
„Uprzywilejowana usługa domowa” może oznaczać kilka niezwiązanych ze sobą uprawnień: odczyt urządzenia szeregowego USB, korzystanie z węzła renderującego GPU, sterowanie interfejsem sieciowym, montowanie systemu plików, powiązanie z niskim portem, dostęp do Bluetooth, odczyt danych SMART lub zarządzanie innymi kontenerami.
Przyznaj najmniejszy zestaw możliwości, urządzeń, ścieżek i trybów sieci, który pozwoli usłudze działać. Wyjaśnienie firmy Snyk dotyczące uprzywilejowanego trybu kontenera podkreśla, że pełny uprzywilejowany dostęp udostępnia wszystkie urządzenia hosta i uprawnienia niemal równoważne uprawnieniom hosta. Nie powinien zastępować zbadania jednego brakującego uprawnienia.
Jeśli usługa potrzebuje tylko /dev/dri/renderD128, jedną ścieżkę szeregową według identyfikatora lub jeden katalog konfiguracyjny tylko do odczytu, zarówno Docker, jak i LXC mogą udostępnić ten wąski zasób. Różnica bezpieczeństwa staje się istotna, gdy wdrożenie wymaga szerokich uprawnień lub dostępu do wielu elementów hosta.
Nieuprzywilejowane LXC tworzy silniejszą granicę mapowania roota
W nieuprzywilejowanym LXC UID 0 wewnątrz gościa jest mapowany na zwykły podrzędny UID na hoście Proxmox. Proces może wyglądać na uruchomiony jako root wewnątrz kontenera, jednocześnie nie mając tożsamości roota hosta poza swoją przestrzenią nazw użytkowników. Zmniejsza to skutki wielu pomyłek dotyczących uprawnień plików oraz niektórych ucieczek z kontenera.
Projekt Linux Containers opisuje mapowanie roota w nieuprzywilejowanym LXC jako główną granicę bezpieczeństwa tej konstrukcji, a AppArmor, seccomp i możliwości dodatkowo ograniczają procesy oraz zasoby hosta.
Korzyść zależy od zachowania nieuprzywilejowanego kontenera. Uprzywilejowany LXC nie korzysta z tego samego remapowania identyfikatorów UID, więc root wewnątrz gościa odpowiada znacznie bezpośredniej rootowi na hoście. Przejście do trybu uprzywilejowanego wyłącznie w celu uproszczenia montowania lub obsługi urządzeń może zniweczyć powód, dla którego LXC wydawał się bezpieczniejszy.
Docker może zmniejszyć ryzyko związane z rootem bez przenoszenia aplikacji do LXC
Kontenery Docker nie muszą działać z nieograniczonym demonem rootful i aplikacją uruchomioną jako root. Obraz kontenera może określać użytkownika innego niż root, środowisko uruchomieniowe może ograniczać możliwości, systemy plików mogą być tylko do odczytu, a przestrzenie nazw użytkowników mogą remapować tożsamości w kontenerze.
Tryb rootless Dockera uruchamia zarówno demona, jak i kontenery bez uprawnień roota na hoście. Może to ograniczyć ryzyko związane z demonem i środowiskiem uruchomieniowym, gdy aplikacja oraz wymagane funkcje pamięci masowej lub sieci obsługują ograniczenia trybu rootless.
Docker nadal zapewnia lepszą granicę, gdy aplikacja jest już dobrze spakowana i potrzebuje tylko jednego, ściśle określonego uprawnienia. Przeniesienie jej do pełnego kontenera LXC dodaje kolejny system operacyjny wymagający aktualizacji, nie zmniejszając automatycznie zasobu mapowanego do przejętej aplikacji.
Gniazdo Dockera może zlikwidować granicę aplikacji
Niektóre pulpity, narzędzia do automatycznych aktualizacji, narzędzia do tworzenia kopii zapasowych i usługi monitorujące żądają dostępu do /var/run/docker.sockGniazdo pozwala klientowi instruować demona Dockera na hoście, aby tworzył kontenery, montował ścieżki hosta, udostępniał urządzenia i zmieniał sieci. Przejęta usługa może więc pośrednio przejąć kontrolę nad hostem bez wykorzystywania luki w jądrze umożliwiającej ucieczkę.
Analiza Netdata wyjaśnia, dlaczego dostęp do gniazda Dockera działa jak administracja hostem: proces prosi uprzywilejowanego demona o wykonanie w jego imieniu potężnych operacji na hoście, bez konieczności wykorzystywania typowej luki umożliwiającej ucieczkę z kontenera.
To pierwsza granica, na której należy się zatrzymać. Jeśli usługa wymaga nieograniczonego dostępu do gniazda Dockera, porównywanie standardowej izolacji Dockera ze standardową izolacją LXC jest mylące. Traktuj usługę jak administratora hosta, w miarę możliwości ogranicz jej API za pomocą specjalnie przygotowanego proxy, odizoluj ją od niezaufanych sieci i odpowiednio zabezpiecz jej dane uwierzytelniające.
Mapowanie urządzeń przemawia za modelem z mniejszą liczbą warstw uprawnień
Kartę GPU, koncentrator USB, tuner, akcelerator Coral, zasilacz UPS lub adapter szeregowy można przekazać do dowolnego wdrożenia. W przypadku bezpośredniego użycia Dockera host udostępnia urządzenie kontenerowi aplikacji. W LXC Proxmox udostępnia urządzenie kontenerowi systemowemu, który następnie uruchamia usługę natywnie albo może przekazać urządzenie dalej do zagnieżdżonego Dockera.
Dedykowany kontener LXC może być bardziej przejrzysty, gdy kilka powiązanych procesów potrzebuje tego samego urządzenia, a użytkownicy lub grupy systemu Linux powinni zarządzać dostępem. Docker może być bardziej przejrzysty, gdy jeden obraz potrzebuje jednego urządzenia, a mapowanie jest opisane bezpośrednio w Compose.
Unikaj udostępniania któremukolwiek kontenerowi wszystkich urządzeń tylko dlatego, że uzyskanie uprawnień do jednego z nich jest trudne. Proxmox zauważa, że izolacja LXC w Proxmox łączy przestrzenie nazw, AppArmor, seccomp i ograniczenia dostępu do urządzeń. Szeroki dostęp do urządzeń usuwa część tej warstwowej granicy, podobnie jak uprzywilejowany tryb Dockera.
Montowania bind hosta przenoszą ryzyko w różne strony
Montowanie bind w Dockerze udostępnia wybraną ścieżkę hosta bezpośrednio aplikacji. Montowanie z prawem zapisu zawierające zdjęcia, kopie zapasowe, konfigurację lub stan innych aplikacji daje przejętemu kontenerowi takie same prawa do modyfikacji, jakie ma zmapowany użytkownik hosta w odniesieniu do tej ścieżki.
Montowanie bind w LXC udostępnia ścieżkę gościowi, gdzie wiele usług i użytkowników administracyjnych może uzyskiwać do niej dostęp zgodnie z mapowaniami UID i GID. Dodatkowa granica systemowa może pomóc uporządkować uprawnienia, ale jednocześnie zwiększa zbiór procesów wewnątrz gościa, które mogą uzyskać dostęp do danych.
W miarę możliwości używaj montowań tylko do odczytu, oddziel konfigurację od dużych zbiorów danych i unikaj mapowania głównego katalogu hosta, /proc, /sys, /devlub katalogów danych Dockera w szerokim zakresie. Jeśli usługa musi nadpisywać chronione dane NAS-u, izolacja aplikacji nie zastąpi migawek ani niezależnych kopii zapasowych.
Uprawnienia sieciowe mogą stworzyć większy zakres szkód niż dostęp do systemu plików
Usługi domowe, takie jak bramy VPN, filtry DNS, narzędzia do wykrywania sieci, integracje z Home Assistantem i systemy monitorowania, mogą żądać sieci hosta, gniazd surowych, przechwytywania pakietów, modyfikowania zapory lub dostępu do kilku sieci VLAN. Te uprawnienia mogą ujawniać ruch i pozwalać usłudze wpływać na inne urządzenia.
Kontener Docker korzystający z sieci hosta traci separację sieciową na poziomie portów, natomiast dodatkowe uprawnienia, takie jak NET_ADMIN lub NET_RAW zwiększyć zakres szkód, jakie może wyrządzić przejęcie. LXC z własnym wirtualnym interfejsem może zapewnić oddzielny adres i zasady zapory, ale uprzywilejowany lub szeroko mostkowany gość nadal może uzyskać dostęp do wrażliwych sieci.
Wybierz granicę, która pozwala zdefiniować najwęższą ścieżkę sieciową. Oddzielna sieć VLAN, dedykowany adres, jawne reguły zapory oraz brak dostępu do zarządzania NAS-em często zmniejszają ryzyko bardziej niż zmiana technologii kontenerów przy pozostawieniu usługi we wszystkich zaufanych sieciach.
Uprzywilejowane LXC i uprzywilejowany Docker zawodzą na różne sposoby
W pełni uprzywilejowany kontener Docker otrzymuje szeroki zakres uprawnień systemu Linux oraz dostęp do urządzeń za pośrednictwem demona Docker działającego z uprawnieniami roota. Uprzywilejowany kontener LXC zapewnia całej przestrzeni użytkownika gościa znacznie ściślejszą relację tożsamości z użytkownikiem root hosta. Żadnego z nich nie należy traktować jak zwykłego nieuprzywilejowanego kontenera aplikacji.
Wytyczne bezpieczeństwa Tigery ostrzegają, że uprzywilejowany tryb Dockera omija najważniejsze mechanizmy izolacji. Dyskusje społeczności Proxmox również ostrzegają, że włączenie zagnieżdżania lub szerokiego dostępu do systemu plików hosta wewnątrz LXC może przy nieostrożnej konfiguracji ujawnić powierzchnie /proc i /sys hosta.
Jeśli usługa rzeczywiście wymaga uprawnień równoważnych uprawnieniom roota na hoście, maszyna wirtualna z dedykowanym jądrem może zapewnić wyraźniejszą granicę odseparowania. Dodatkowe zużycie pamięci i przestrzeni dyskowej może być uzasadnione, gdy usługa jest dostępna z internetu, przetwarza niezaufane dane wejściowe, ładuje sterowniki powiązane z jądrem lub administruje innymi obciążeniami.
Aktualizacje i odzyskiwanie decydują o tym, czy izolacja pozostaje użyteczna
Docker sprawia, że pakiet aplikacji można wymienić. Odtwórz kontener na podstawie przypiętego obrazu lub skrótu, przywróć jego konfigurację i trwałe dane, a następnie ponownie zastosuj te same, wąskie uprawnienia. Jest to szczególnie wartościowe, gdy zasady bezpieczeństwa są widoczne w Compose, a nie zapamiętane z poleceń powłoki.
Dedykowany kontener LXC sprawia, że środowisko operacyjne można wymienić jako jeden gość Proxmox. Jego baza pakietów, pliki usług, użytkownicy i mapowania urządzeń mogą być kopiowane zapasowo razem. Odzyskiwanie przebiega sprawnie, gdy montowania bind, mapowania UID, urządzenia hosta i reguły sieciowe są udokumentowane poza kontenerem.
Porównanie ZimaSpace dotyczące granic odzyskiwania maszyny wirtualnej Docker i kontenera LXC dla każdej aplikacji przedstawia powiązany test operacyjny. Mniejsza granica bezpieczeństwa jest przydatna tylko wtedy, gdy można ją odtworzyć bez ręcznego ponownego nadawania szerokich uprawnień.
Przeprowadź test redukcji uprawnień przed wyborem Dockera lub LXC
- Wymień każde urządzenie, ścieżkę hosta, capability, sieć, API i funkcję jądra, których żąda usługa.
- Usuń pełny tryb uprzywilejowany i dodawaj wymagane uprawnienia pojedynczo.
- Uruchamiaj aplikację jako użytkownik inny niż root albo, jeśli to możliwe, wewnątrz nieuprzywilejowanego kontenera LXC.
- Zastąp szerokie punkty montowania węższymi ścieżkami tylko do odczytu lub ścieżkami właściwymi dla danego zbioru danych.
- Usuń dostęp do gniazda Dockera albo umieść między usługą a demonem ograniczony serwer proxy.
- Przetestuj założenia dotyczące naruszenia bezpieczeństwa, sprawdzając, do których plików hosta, urządzeń i sieci nadal można uzyskać dostęp.
- Przywróć usługę na czystym hoście Docker lub LXC, używając wyłącznie wersjonowanej konfiguracji.
Nie oceniaj bezpieczeństwa wyłącznie na podstawie liczby warstw. Oceniaj faktycznie dostępne uprawnienia po dodaniu wszystkich wymaganych urządzeń, punktów montowania, możliwości, gniazd i sieci. Prosty kontener z wąskim zakresem dostępu może być bezpieczniejszy niż złożony zagnieżdżony projekt z kilkoma wyjątkami.
Która granica izolacji pasuje do uprzywilejowanej usługi domowej?
Kiedy wybrać kontener aplikacji Docker
Wybierz Dockera, gdy usługa jest dystrybuowana jako obraz, potrzebuje jednego lub dwóch jawnie określonych urządzeń lub punktów montowania i może działać bez --privileged, nieograniczonego dostępu do gniazda Dockera ani szerokiego dostępu do sieci hosta. Przypinaj wersje, odbieraj możliwości, gdy to możliwe używaj systemów plików tylko do odczytu i jawnie określaj dane trwałe.
Kiedy wybrać dedykowany nieuprzywilejowany LXC
Wybierz LXC, gdy usługa potrzebuje pełniejszego środowiska Linux, kilku powiązanych demonów, bezpośredniej integracji z systemd lub złożonych uprawnień grup urządzeń. Zachowaj mapowanie przestrzeni nazw użytkowników, utrzymuj ograniczenia AppArmor i seccomp oraz dokumentuj każde montowanie hosta i mapowanie urządzeń.
Kiedy zamiast tego wybrać maszynę wirtualną
Wybierz maszynę wirtualną, gdy obciążenie wymaga kontroli równoważnej uprawnieniom roota hosta, ładuje nietypowe sterowniki, administruje innymi obciążeniami, przyjmuje niezaufane dane publiczne lub nie może działać bez szerokich uprawnień do systemu plików i sieci. Oddzielne jądro tworzy silniejszą granicę niż dodawanie kolejnych wyjątków do kontenera współdzielącego jądro.
Najczęstsze pytania
Czy uprzywilejowany LXC jest bezpieczniejszy niż uprzywilejowany kontener Dockera?
Nie jako ogólna zasada. W obu przypadkach osłabiono ważne mechanizmy izolacji, ale zakres ujawnianych uprawnień jest inny. Należy ocenić mapowanie UID, urządzenia, punkty montowania, możliwości, dostęp sieciowy, AppArmor, seccomp i interfejsy API demonów, zamiast polegać na samej etykiecie kontenera.
Czy uruchamianie Dockera wewnątrz nieuprzywilejowanego LXC dodaje kolejną warstwę bezpieczeństwa?
Może dodać mapowanie identyfikatorów UID między LXC a hostem Proxmox, ale zagnieżdżony Docker może wymagać funkcji nesting, dodatkowych możliwości, wyjątków systemu plików lub mapowań urządzeń. Te zmiany mogą zniwelować korzyści. Maszyna wirtualna jest bardziej przejrzystym rozwiązaniem, gdy wymagana jest silna separacja od hosta.
Czy usługi domowe działające wyłącznie w sieci LAN potrzebują nieuprzywilejowanych kontenerów?
Tak, gdy naruszenie bezpieczeństwa może nastąpić za pośrednictwem innego urządzenia w sieci LAN, podatnego interfejsu WWW, złośliwych plików multimedialnych lub dokumentów, obrazów z łańcucha dostaw albo ujawnionych danych uwierzytelniających. Umieszczenie usługi wyłącznie w sieci LAN ogranicza część zagrożeń, ale nie sprawia, że dostęp do roota hosta staje się nieszkodliwy.
Ostateczny werdykt
Używaj Dockera, gdy spakowana aplikacja może działać z wąsko określonymi uprawnieniami i bez administracyjnych interfejsów hosta. Używaj nieuprzywilejowanego LXC, gdy usługa potrzebuje pełniejszego systemu Linux przy zachowaniu mapowania roota i kontrolowanego dostępu do urządzeń. Jeśli którykolwiek z tych projektów wymaga szerokich uprawnień roota hosta, nieograniczonego dostępu do gniazd lub zapisu do krytycznych danych, przestań porównywać kontenery i umieść usługę za silniejszą granicą w postaci maszyny wirtualnej lub oddzielnego komputera.
Porównania produktów
Więcej do przeczytania

Tunel VPS a przekierowanie portów w domu dla publicznie dostępnych usług hostowanych samodzielnie: którą ścieżką ruchu przychodzącego łatwiej zarządzać?
Użyj przekierowania portów, aby uzyskać najprostsze połączenie bezpośrednie; skorzystaj z tunelu VPS, gdy znaczenie mają CGNAT, prywatność adresu, scentralizowany punkt wejścia lub możliwość przenoszenia...

Router konsumencki czy dedykowana zapora sieciowa w segmentowanym domowym laboratorium: kiedy warto rozdzielić bramę?
Pozostań przy routerze konsumenckim, dopóki segmentacja jest prosta; przejdź na dedykowaną zaporę sieciową, gdy zasady, widoczność, interfejsy lub możliwości odzyskiwania danych przekroczą jego możliwości.

Laboratorium warstwy 2 a routowane sieci VLAN w miarę rozwoju domowego laboratorium: kiedy brama powinna znaleźć się bliżej krawędzi sieci?
Zachowaj warstwę 2, gdy jedna brama i kilka trunków pozostają przejrzyste; kieruj ruch bliżej brzegu sieci, gdy zakres VLAN-ów, obszar awarii i zasady stają...

