Uruchamianie kontenerów jako root jest jedną z najczęstszych — i najbardziej niebezpiecznych — błędnych konfiguracji w środowiskach produkcyjnych. Cicho powiększa powierzchnię ataku każdego obciążenia, a większość zespołów nie zdaje sobie z tego sprawy, dopóki incydent nie wymusi rozwiązania problemu.
Co naprawdę oznacza „uruchamianie jako root"
Domyślnie wiele obrazów kontenerów (zwłaszcza minimalne lub starsze) wykonuje swój główny proces jako UID 0 wewnątrz kontenera. Ponieważ kontenery współdzielą jądro hosta z innymi kontenerami i samym hostem, root wewnątrz kontenera to nie to samo co root na w pełni izolowanej maszynie wirtualnej — ale nadal jest znacznie bardziej potężny niż powinien być. Jeśli osoba atakująca uzyska wykonanie kodu wewnątrz kontenera należącego do roota, dziedziczy:
- Pełny dostęp do odczytu/zapisu do dowolnych plików zamontowanych w kontenerze, niezależnie od zamierzonych uprawnień
- Możliwość instalacji pakietów, modyfikacji plików binarnych lub ingerencji w stan aplikacji
- Znacznie łatwiejszą ścieżkę do ucieczki z kontenera, jeśli podatność jądra lub runtime jest exploitowalna
- Podwyższoną dźwignię w połączeniu z błędnie skonfigurowanymi wolumenami, takimi jak zamontowany Docker socket lub ścieżka do systemu plików hosta
Nawet bez exploita na poziomie jądra, dostęp roota wewnątrz kontenera dramatycznie zwiększa promień wybuchowy każdej podatności na poziomie aplikacji (SSRF, błędy deserializacji, arbitralne zapisywanie plików itp.).
Dlaczego to ważniejsze w środowiskach skoordynowanych
W klastrach Kubernetes, kontener roota w połączeniu z nadmiarowymi możliwościami Linux lub permisywnym kontekstem bezpieczeństwa może pozwolić atakującemu:
- Modyfikować
/proclub/sysw sposób wpływający na host - Podnieść uprawnienia, jeśli włączone są
hostPID,hostNetworklubhostIPC - Nadużywać zamontowanego tokenu konta usługi do lateralnego poruszania się po klastrze
- Uciec na węzeł, jeśli ustawione jest
privileged: truelub przyznane są niebezpieczne możliwości, takie jakSYS_ADMIN
Sam użytkownik root niekoniecznie jest podatnością — to połączenie roota wraz z nadmiernie hojnymi możliwościami jądra, montażami hosta lub udostępnianiem przestrzeni nazw, które zamieniają kompromis w kontenerze na kompromis w całym klastrze.
Praktyczne kroki hartowania
1. Ustaw użytkownika niebędącego rootem w obrazie
Jawnie zdefiniuj użytkownika niebędącego rootem w Dockerfile, zamiast polegać na domyślnych ustawieniach:
FROM node:20-slim
RUN useradd --uid 10001 --shell /usr/sbin/nologin appuser
USER appuser
2. Wymuś to na poziomie orkiestratora
Nie polegaj tylko na obrazie — wymuś politykę w czasie wykonywania. W Kubernetes użyj securityContext:
securityContext:
runAsNonRoot: true
runAsUser: 10001
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
runAsNonRoot: true powoduje, że pod nie powiedzie się przy przyjęciu, jeśli obraz spróbuje uruchomić się jako UID 0, dając ci gwarancję, a nie konwencję najlepszych wysiłków.
3. Zrzuć niepotrzebne możliwości
Więksość aplikacji nie potrzebuje żadnych domyślnych możliwości Linux przyznanych kontenerom. Zrzuć wszystko i dodaj z powrotem tylko to, co jest absolutnie wymagane (rzadkie przypadki, takie jak powiązanie z niskimi portami, mogą wymagać NET_BIND_SERVICE).
4. Unikaj trybu uprzywilejowanego i udostępniania przestrzeni nazw hosta
privileged: true, hostNetwork: true i hostPID: true powinny być zarezerwowane dla bardzo specyficznych obciążeń infrastrukturalnych (takich jak określone agenty CNI lub monitorowania) — nigdy dla ogólnych kontenerów aplikacji.
5. Skanuj i wymuszaj za pomocą narzędzi polityki
Używaj kontrolerów wejścia lub aparatów polityki (np. Kyverno, OPA/Gatekeeper) do automatycznego odrzucania wdrożeń, które naruszają te reguły, zamiast polegać na ręcznym przeglądzie kodu. Połącz to ze skanowaniem obrazów w CI, aby wyłapać obrazy użytkownika root, zanim dotrą do klastra.
Warstwowa, ale nie doskonała obrona
Uruchamianie jako non-root nie eliminuje całkowicie ryzyka — na poziomie jądra istnieją ucieczki kontenerów niezależne od użytkownika wewnątrz kontenera — ale usuwa ogromną klasę technik eskalacji uprawnień i lateralnego poruszania się z niskim wysiłkiem. W połączeniu z systemami plików tylko do odczytu, upuszczonymi możliwościami i ograniczającymi politykami sieciowymi, tworzy jedną z najtańszych i najskuteczniejszych warstw w strategii obrony wgłąb bezpieczeństwa kontenerów.
Chcesz zagłębić się w hartowanie obciążeń cloud-native? Zapoznaj się z powiązanymi segmentami Korra Studio dotyczącymi bezpieczeństwa chmury i hartowania potoku DevOps, aby zbudować resztę swojej strategii obrony wgłąb.