Powrot do wpisow

Wpis techniczny

Docker i dynamiczny firewall: jak żyją reguły po publikacji portów

Reguły Dockera pojawiają się i znikają razem z kontenerami. To zmienia audyt bezpieczeństwa, utrudnia kontrolę ekspozycji usług i wymaga patrzenia na runtime, nie tylko na konfigurację.

W poprzednim wpisie opisałem, dlaczego publikacja portów przez Dockera potrafi ominąć systemowy firewall. Tym razem skoncentruję się na mniej oczywistym elemencie: na tym, jak te reguły zachowują się w czasie.

To właśnie tutaj Docker najmocniej odchodzi od klasycznego modelu pracy z firewallem.

Seria: Docker i firewall

  1. Mechanizm: dlaczego publikacja portów może ominąć firewall
  2. Runtime: jak reguły pojawiają się i znikają razem z kontenerami
  3. Praktyka: jak odzyskać kontrolę nad ekspozycją usług

Firewall, który żyje razem z kontenerami

W tradycyjnym podejściu konfigurujesz firewall, zapisujesz reguły i traktujesz je jako dość stabilny element systemu. Możesz je audytować, porównywać i utrzymywać jako świadomą politykę dostępu.

Docker działa inaczej. Gdy publikujesz port kontenera, reguły nie są tylko trwałą konfiguracją hosta. Stają się częścią bieżącego stanu runtime.

Przykład:

docker run -d -p 8080:80 nginx

Po uruchomieniu kontenera reguły pojawiają się natychmiast, a port zaczyna być osiągalny.

Kiedy zatrzymasz kontener:

docker stop <container>

reguły znikają razem z nim, a wystawiony port przestaje istnieć.

W praktyce oznacza to prostą zmianę modelu: firewall przestaje być wyłącznie konfiguracją i zaczyna być efektem ubocznym działania kontenerów.

Dlaczego to komplikuje pracę operacyjną

Sam fakt, że reguły są dynamiczne, nie musi jeszcze być problemem. Problem zaczyna się wtedy, gdy próbujesz na tej podstawie prowadzić audyt, kontrolować ekspozycję usług albo zbudować przewidywalny standard pracy zespołu.

Audyt pokazuje tylko chwilowy stan

Polecenie:

ufw status

nie daje pełnego obrazu sytuacji.

Nawet jeśli sprawdzisz bezpośrednio iptables:

iptables -t nat -L -n

to nadal widzisz tylko snapshot z konkretnego momentu. Jeżeli kontenery są regularnie uruchamiane, restartowane albo usuwane, taki odczyt szybko przestaje być aktualny.

Każde docker run -p może wystawić usługę na świat

W środowisku zespołowym to szczególnie istotne. Jedno polecenie uruchomienia kontenera może w praktyce oznaczać natychmiastową zmianę ekspozycji usługi.

Jeżeli nie ma centralnej warstwy wejściowej ani prostych zasad, publikacja portów staje się rozproszona. To zwykle kończy się tym, że nikt nie ma pełnego obrazu, co naprawdę jest dostępne z zewnątrz.

Trudno wskazać jedno źródło prawdy

W modelu deklaratywnym oczekujesz jednego miejsca, które opisuje stan systemu. Przy Dockerze część tego stanu żyje po prostu w runtime.

To oznacza, że pełny obraz wymaga jednoczesnego spojrzenia na:

  • konfigurację hosta
  • aktualny stan kontenerów
  • sposób publikacji portów

Lepszy model mentalny

Żeby ograniczyć pomyłki, warto przyjąć kilka prostych założeń.

Kontener to także zmiana polityki ruchu

Uruchomienie kontenera z -p nie jest wyłącznie wdrożeniem aplikacji. To równocześnie zmiana sposobu, w jaki host obsługuje ruch przychodzący.

-p to publikacja, nie zwykłe mapowanie

To drobna różnica językowa, ale praktycznie bardzo użyteczna. Jeśli myślisz o -p jako o publikacji usługi, łatwiej wychwycić skutki bezpieczeństwa niż wtedy, gdy traktujesz to tylko jako techniczne mapowanie portu.

Najpierw patrz na runtime

Jeżeli chcesz wiedzieć, co faktycznie jest wystawione, zacznij od sprawdzenia bieżącego stanu kontenerów:

docker ps --format "table {{.Names}}\t{{.Ports}}"

To często daje bardziej użyteczny obraz niż sama analiza konfiguracji firewalla bez kontekstu uruchomionych usług.

Rootless nie usuwa całego problemu

Rootless Docker nie ingeruje w hostowe iptables, więc odpada część problemów związanych z ukrytymi zmianami w firewallu. Nie znika jednak sam temat ekspozycji usług.

Zmienia się mechanizm, ale nadal trzeba wiedzieć:

  • które usługi są publikowane
  • na jakich interfejsach
  • kto w zespole może to robić

Rootless poprawia przewidywalność, ale nie zastępuje sensownych zasad operacyjnych.

Jak odzyskać kontrolę

Najlepiej działa ograniczenie liczby miejsc, w których w ogóle może dojść do publikacji portu.

Ogranicz bezpośrednie -p

Jeżeli nie ma wyraźnej potrzeby, trzymaj usługi w sieci wewnętrznej Dockera i wystawiaj ruch przez jedną warstwę wejściową, na przykład reverse proxy.

Ustal prosty standard zespołowy

W praktyce wystarczy kilka zasad:

  • -p tylko dla usług brzegowych
  • pozostałe usługi bez bezpośredniej publikacji portów
  • jedna kontrolowana warstwa ingressu

Monitoruj runtime

Nawet przy dobrych zasadach warto regularnie sprawdzać, co faktycznie działa:

docker ps --format "table {{.Names}}\t{{.Ports}}"

To prosty nawyk, ale bardzo skuteczny.

Wniosek

Docker nie tylko zmienia reguły firewalla. On sprawia też, że ich obecność zależy od bieżącego stanu kontenerów.

Właśnie dlatego bezpieczeństwa nie da się tu ocenić wyłącznie na podstawie statycznej konfiguracji hosta. Trzeba patrzeć również na runtime i traktować publikację portów jako świadomą decyzję architektoniczną.

Jeżeli chcesz dobrze zrozumieć sam mechanizm dodawania reguł, wróć też do artykułu o tym, dlaczego porty Dockera omijają systemowy firewall.