19 Sposobów Na Bezpieczniejszego Dockera

securitybeztabu.pl 2 lat temu

Jak zadbać o bezpieczeństwo naszych kontenerów?

Docker od dłuższego czasu stał się oprogramowaniem używanym bardzo często do uruchamiania wszelkiego rodzaju aplikacji. Wpływ na to mają jego możliwości czy też funkcjonalność. Zwróćmy uwagę, bez większego nakładu sił jak i czasu jesteśmy w stanie uruchomić aplikację w odizolowanym środowisku. Co ciekawsze każde z narzędzi które musi łącznie z aplikacją uruchamiamy w oddzielnych kontenerach czyli w odizolowanym środowisku.

Choć wizja izolacji szczególnie osobom dopiero rozpoczynającym swoją przygodę z dockerem może wydawać się wystarczająca pod względem bezpieczeństwa to jednak chcę na samym początku poświadczyć, iż tak nie jest. Ta izolacja jest świetna, ale nie jest wystarczającym zabezpieczeniem.

W tym materiale chcę Ci pokazać kilka najlepszych praktyk jakie należy stosować, aby zwiększyć bezpieczeństwo uruchomionej aplikacji. Wymienię możliwości zarówno te bardziej skomplikowane jak i takie które mogą wydawać się banalne, ale niestety przez cały czas występują. Uważam, iż bez nich prezentowany poradnik byłby niekompletny.

1. Wybierz odpowiedni system

Jednym z podstawowych zagadnień jest wybór odpowiedniego systemu na jakim będziemy chcieli uruchomić nasze kontenery dockerowe. Otóż nie zawsze najnowsza wersja systemu operacyjnego jest najlepszym wyborem. Ma to związek z jego tak zwaną świeżością, przez którą może zawierać wiele błędów.

Większość serwisów chmurowych jak na przykład digitalocean oferuje kilka dystrybucji Linuksowych oraz dla każdej z dystrybucji możliwość wersji systemu. Przed podjęciem decyzji należy przeanalizować wszystkie możliwości. Musisz zwrócić uwagę na to jak długo prowadzone będą jeszcze aktualizacje do wybranej wersji, ponieważ może się zdarzyć, iż za niedługi czas wybrana wersja systemu nie będzie aktualizowana i zostaniemy zmuszeni do przeniesienia naszych kontenerów na inny.

Dobrym rozwiązaniem jest wybranie systemu dedykowanemu dla kontenerów dockera. Takim jest np. Bottle Rocket proponowany przez amazon.

Niezależnie od decyzji musisz pamiętać, iż system na którym uruchamiać będziesz swoje kontenery dockerowe powinien robić tylko to. Wszystkie usługi które nie będą wykorzystywane by wszystko sprawnie działało powinny być wyłączone, ze względów bezpieczeństwa. Wiadomo, im mniej masz uruchomione, tym mniejsze prawdopodobieństwo, iż któraś z usług będzie miała jakiś błąd lub lukę bezpieczeństwa.

2. Nie zapomnij o aktualizacjach

Bardzo ważnym aspektem funkcjonowania zarówno kontenerów jak też uogólniając całego środowiska, jest aktualizacja. Tutaj jednak warto wspomnieć, iż aktualizację możemy podzielić na dwa rodzaje.

Pierwsza z nich dotyczy dodania jakiejś dodatkowej funkcji do systemu operacyjnego lub samego dockera. W przypadku tego typu aktualizacji zawsze poddawałbym to analizie ponieważ może wyrządzić to nieraz więcej szkód niż korzyści. Przed podjęciem decyzji o wykonaniu takiej aktualizacji należy zadać sobie pytanie, czy funkcja jest nam potrzebna.

Drugim rodzajem jest aktualizacja bezpieczeństwa lub poprawy funkcjonowania systemu bądź aplikacji. Takie aktualizację są tak zwanym Must Have. O takie musisz zadbać zawsze. Dzięki temu zmniejszysz ryzyko dostępu przez osoby niepowołane do twojego serwera.

Wskazane informacje dotyczą zarówno aktualizacji bazowego hosta jak i również systemu bazowego zainstalowanego w kontenerze.

3. Uważaj przy uruchomieniu kontenerów

Pamiętaj aby zawsze uruchamiać wszystkie swoje kontenery jako użytkownik bez uprawnień administracyjnych, czyli nie jako root. Zapewni to bezpieczeństwo twoim kontenerom i dzięki temu o ile ktoś pobierze twój kontener nie będzie miał dostęp do twojego serwera. Natomiast pamiętaj, iż potrzebujesz jedynie uprawnień do uruchamiania kontenerów, a nie prawa własności które zawsze powinno należeć do konta root.

Aby uruchomić kontener w trybie tylko do odczytu należy posłużyć się poleceniem:

$ docker run -it --read-only debian /bin/sh

4. Przypilnuj podstaw

Ważnym aspektem jest również zapewnienie odpowiedniego systemu zabezpieczeń. Zapora jest podstawowym elementem jaki musisz skonfigurować jak i również prowadzenie oraz monitorowanie dzienników.

Szczególnie dzienniki powinny być często przeglądane ponieważ choćby posiadając zaporę zawsze istnieje ryzyko, iż komuś uda się ją obejść, ale zostanie to zapisane przez IDS w dziennikach systemowych.

5. Loguj zdarzenia

Jak wspomniałem wszystko powinno być odnotowywane w dziennikach systemowym w tym również logowania użytkowników. Ważna jest sama konfiguracja możliwości logowania która powinna być z użyciem kluczy, a nie hasła. Tak samo firewall powinien być skonfigurowany w sposób umożliwiający logowanie tylko w zaufanych sieciach. Natomiast o ile VPS administruje kilku użytkowników to pamiętaj aby osoby które nie uruchamiają kontenerów, nie miały takiej możliwości, czyli nie powinny znajdować się w grupie docker czy też innej grupie z funkcjonalnością z której nie będą korzystały.

6. Dostęp do zasobów

Każdy z kontenerów powinien mieć ograniczy dostęp do zasobów. Ma to duże znaczenie pod względem bezpieczeństwa ponieważ o ile dobrze zrównoważysz danym kontenerom przydział to choćby o ile jeden z nich zostanie zainfekowany, ograniczenia zasobowe uniemożliwią, zatrzymają lub spowolnią wykonanie się takiego kodu. Więcej informacji jak to zrobić znajdziesz TUTAJ.

7. Minimalizuj i dbaj o porządek

Musisz dbać o to by obrazy pochodziły z zweryfikowanych źródeł. Główna strona z obrazami dockera znajduje się pod adresem https://hub.docker.com/, na której odnajdziesz bardzo dużą liczbę obrazów. o ile są to obrazy oficjalne oznacza to, iż zostały wprowadzone przez samych autorów dockera, stąd też nie ma obawy w korzystaniu z nich. Natomiast o ile nie jest to obraz oficjalny istotna przy nim informacją jest aby wydawca był zweryfikowany. Stosując się do zasady instalowania tylko takich obrazów istnieje małe ryzyko, iż będą zawierały specjalnie dołożone złośliwe oprogramowanie.

Warto jeszcze pamiętać o ilości uruchomionych obrazów. o ile jest Ci jakiś niepotrzebny to go usuń, i kontenery z nim związane. Zapewni to porządek oraz może wpłynąć na lepszą funkcjonalność całego systemu.

Kolejnym ważnym aspektem jest porządek w samym kontenerze. o ile wiesz, iż zainstalowałeś jakąś funkcję która nie jest potrzebna to ją odinstaluj. o ile znajdują się w nim zbyteczne pliki to powinny być również usunięte. Docker polega na minimalizacji oraz izolacji dlatego jest uważany, za genialne narzędzie. W związku z tym nie psuj tego.

8. Używaj adekwatnych etykiet

Choć banalnym, ale bardzo ważnym elementem wpływającym na wygodę jak i również bezpieczeństwo jest odpowiednie nazywanie obrazów oraz kontenerów. o ile nazwa będzie wygenerowana automatycznie przez dockera nie będzie wyjaśniała jaką funkcjonalność dany kontener posiada, a przy sporej ich ilości może się okazać problemem. Szczególnie gdy musimy gwałtownie zareagować a nie wiemy na którym kontenerze.

Przykład:

$ docker create --name nazwa obraz

9. Skanuj kontenery

Docker posiada wbudowane narzędzie do skanowania obrazów pod względem luk. Korzystaj z niego, a może pomóc wykryć błędy. Warto jeszcze wspomnieć, iż samo pojedyncze skanowanie od czasu do czasu nie wystarczy. Sprawdzanie zabezpieczeń czy to obrazów czy też samych kontenerów powinno odbywać się dość często, a już na pewno po wprowadzeniu w nich jakichkolwiek zmian. Najlepiej jest zaplanować proces skanowania który co jakiś czas będziemy wykonywali.

Przykład:

$ docker scan nazwaObrazu

Więcej informacji na temat skanowania i dostępnym oprogramowaniu znajdziesz TUTAJ.

Tego typu rozwiązanie można porównać do aktualizacji o których pisałem w jednym z poprzednich paragrafów. Każda zmiana szczególnie dodająca nową funkcję naraża naszą aplikację, dlatego o ile chcemy wprowadzać jakiekolwiek zmiany, musimy stworzyć proces który sprawdzi czy wszystko należycie działa.

10. Odpowiednio skonfiguruj sieć

Pamiętaj aby odpowiednio skonfigurować sieć w jakiej znajdują się twoje kontenery. o ile nie utworzysz własnej sieci wszystkie kontenery zostaną dodane do automatycznie wygenerowanej sieci przez dockera. Nie posiada ona takiej funkcjonalności oraz możliwości konfiguracji jak własna sieć dlatego nie jest zalecane w realnym środowisku. o ile tworzysz kilka kontenerów które posiadają jakieś zależności z sobą to nie bój się tworzyć własnych sieci. Pamiętaj, iż w hierarchii nie każdy kontener jest powiązany z każdym dlatego niech dostęp do na przykład bazy danych ma kontener na którym uruchamiasz aplikację, a inne niech nie wiedzą, o jego istnieniu, o ile do swojego działania tego nie potrzebują.

11. Zadbaj o adekwatne porty

Tak samo jak w przypadku uruchomionych usług tak i portów powinny być udostępnione tylko te niezbędne. Tutaj nikogo nie powinno to dziwić ponieważ sprawa ta nie dotyczy tylko i wyłącznie samego dockera. Na każdym z serwerów ten minimalizm powinien być stosowany zarówno do jednego czy tez drugiego tematu. Otwarty port daje osobie niepowołanej odnalezienie lub wykorzystanie istniejącej luki. Dlatego porty mogą być otwarte tylko te porty których wymaga uruchomiona aplikacja do prawidłowego działania.

W Dockerfile możemy użyć instrukcji EXPOSE, ale musisz pamiętać, iż jest to tylko informacja o tym jakie porty muszą być udostępnione aby aplikacja działała.

Przykład:

EXPOSE 80/tcp

Pamiętaj jednak, iż ta dyrektywa nie udostępnia portu tylko informuje osobę korzystającego z pliku o tym jaki musi być udostępniony. Więcej informacji o tym znajdziesz TUTAJ.

12. Używaj funkcji zabezpieczających

Zabezpieczenie kontenerów nie różnią się bardzo od zabezpieczania systemu operacyjnego. Kontenery można porównać do procesów działających w tle które działają na podobnej zasadzie, są uruchomione w głównym systemie. W związku z tym tak samo jak robi się z procesami tak samo należy zrobić z kontenerami czyli odpowiednio je zabezpieczyć. Do tego celu możemy użyć kilku narzędzi jak prezentuje na poniżej liście:

  • Przestrzeń nazw Linuksa – standardowy system zabezpieczeń występujący w kontenerach. Polega na tym, iż wszystko w kontenerze wydaje się działać tak jakby był to główny system operacyjny;
  • Cgroups – ogranicza wykorzystanie zasobów sprzętowych jak i również daje możliwość zablokowania dostępu do kontenera przez inne kontenery na hoście;
  • Capabilities – systemy z rodziny Linux umożliwiają nadanie lub odebranie uprawnień na każdy z procesów. Przy tworzeniu kontenerów możesz skorzystać z tej możliwości blokując niektóre z nich, bez utraty funkcjonalności uruchomionej aplikacji;
  • Seccomp – bezpiecznie uruchamia procesu umożliwiając im wykonanie poleceń tylko z zakresu bezpiecznych;
  • AppArmor – przeznaczony dla systemu Debian Linux który jest ulepszeniem jądra systemu za pomocą którego ogranicza programom dostęp do zasobów systemowych;
  • SELinux – jedno z bardziej znanych zabezpieczeń wśród systemów Linux. Przeznaczony jest dla dystrybucji RedHat. Izoluje kontenery od siebie jak i od głównego hosta. Posiada ogromną liczbę funkcji jak kontrolę dostępu dla użytkowników i wszystkiego co znajduje się w systemie. System ten nazywany jest drugą linią obrony.

Od podstawowych zasobów po bardziej rozbudowane możliwości. Jak widać po powyższej liście jest w czym przebierać i co ważniejsze jest czym zabezpieczyć naszą aplikację uruchomioną przy pomocy dockera.

13. Używaj DTR – Docker Trusted Registry

Zaufany rejestr dockera jest to aplikacja przeznaczona do przechowywania obrazów z których korzystasz. Jest instalowany za zaporą przez co możesz bezpiecznie korzystać z jego zasobów. Więcej informacji znajdziesz TUTAJ.

14. Pamiętaj o HEALTHCHECK

Dobrą praktyką jest dodanie tytułowej opcji do plików Dockerfile. Ta dyrektywa określa dockerowi stan kontenera. Można to określić jako sprawdzenie kondycji danego kontenera. W przypadku gdy docker otrzyma informacje o złym stanie kontenera powinien utworzyć nowy z prawidłowym statusem. Więcej informacji znajdziesz TUTAJ.

15. Pamiętaj aby nie naruszyć poufności

Jednym z dość częstych błędów popełnianych przez administratorów jest umieszczenie poufnych w pliku Dockerfile. Zdarza się w nich spotkać takie informacje jak klucze SSH czy choćby nazwy i hasła do baz danych. Myślę, iż nie muszę tłumaczyć dlaczego bardzo ważne jest aby sprawdzić czy czasami my takiego błędu nie popełniliśmy.

16. Zastanów się co i dlaczego aktualizujesz

Pamiętaj aby w pliku Dockerfile nie przeprowadzać samej aktualizacji systemu tylko połączyć to z instalacją potrzebnego oprogramowania. Natomiast o ile chodzi o oprogramowanie wiesz, iż to co zawiera kontener powinno być jak najbardziej minimalistyczne, jaki i musi pochodzić z pewnego źródła.

17. Miej plan reagowania w razie awarii

Warto ustawić zasady ponownego uruchomienia kontenera w przypadku napotkania awarii. W tym wypadku masz całkowitą kontrolę kontenerami i co się z nimi dzieje. Oznacza to, iż kontener uruchomi się ponownie tylko w sytuacji gdy mu to określimy. Wykona tą czynność, a nie zawiesi działanie kontenera zamiast go uruchomić ponownie.

18. Ustal dyrektywy dla plików

Jeżeli chcesz przekopiować pliki ze swojego lokalnego hosta to nie używaj dyrektywy ADD tylko COPY. Przyczyną tego jest sposób działania samego ADD. Może działać zdalnie czyli pobierać i przekazywać pliki co wiąże się z dużym ryzykiem przesłania plików ze złośliwym oprogramowaniem.

19. Nie rozwiązuj problemów przez SSH

Bardzo dużym błędem jest udostępnić możliwość logowania do kontenera przy pomocy SSH w celu rozwiązania z nim problemów. Najlepiej w tej sytuacji jest udostępnić dzienniki poza niego i po weryfikacji najwyżej wprowadzić nowe.

Podsumowanie

Samo uruchomienie aplikacji przy zastosowaniu dockera może okazać się nie tak bezpiecznym rozwiązaniem jak nam się niektórym wydaje. Wielokrotnie spotykałem się z opinią, iż wystarczy jedynie skorzystać z dockera i już wszystko będzie dobrze. Niestety tak łatwo nie jest. o ile nie zastosujemy się do kilku prostych zasad lub niektórych nie wdrożymy to samo to, iż aplikacja działa w kontenerze lub na zasadzie multi kontenerów nie wystarczy. Jak we wszystkim związanym z bezpieczeństwem nie istniej tak zwane zabezpieczenie idealne, a jedynie takie które utrudni nieupoważnionym dostęp.

Idź do oryginalnego materiału