Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Notatka. przeł.: Autor artykułu, Reuven Harrison, ma ponad 20-letnie doświadczenie w tworzeniu oprogramowania, a dziś jest CTO i współzałożycielem Tufin, firmy tworzącej rozwiązania do zarządzania polityką bezpieczeństwa. Choć postrzega polityki sieciowe Kubernetesa jako dość potężne narzędzie segmentacji sieci w klastrze, uważa też, że nie są one tak łatwe do wdrożenia w praktyce. Materiał ten (dość obszerny) ma za zadanie zwiększyć świadomość specjalistów w tym zakresie i pomóc im w stworzeniu niezbędnych konfiguracji.

Obecnie wiele firm coraz częściej wybiera Kubernetes do uruchamiania swoich aplikacji. Zainteresowanie tym oprogramowaniem jest tak duże, że niektórzy nazywają Kubernetes „nowym systemem operacyjnym dla centrum danych”. Stopniowo Kubernetes (czyli k8s) zaczyna być postrzegany jako krytyczna część biznesu, wymagająca organizacji dojrzałych procesów biznesowych, w tym bezpieczeństwa sieci.

Dla specjalistów ds. bezpieczeństwa, których dziwi praca z Kubernetesem, prawdziwą rewelacją może być domyślna polityka platformy: zezwalaj na wszystko.

Ten przewodnik pomoże Ci zrozumieć wewnętrzną strukturę zasad sieciowych; zrozumieć, czym różnią się one od zasad zwykłych zapór sieciowych. Omówi także niektóre pułapki i przedstawi zalecenia, które pomogą zabezpieczyć aplikacje na Kubernetesie.

Zasady sieciowe Kubernetes

Mechanizm polityki sieciowej Kubernetes pozwala zarządzać interakcją aplikacji wdrożonych na platformie w warstwie sieciowej (trzecia w modelu OSI). W zasadach sieciowych brakuje niektórych zaawansowanych funkcji nowoczesnych zapór sieciowych, takich jak egzekwowanie warstwy 7 OSI i wykrywanie zagrożeń, ale zapewniają podstawowy poziom bezpieczeństwa sieci, który jest dobrym punktem wyjścia.

Zasady sieciowe kontrolują komunikację między zasobnikami

Obciążenia w Kubernetes są dystrybuowane pomiędzy podami, które składają się z jednego lub większej liczby wdrożonych razem kontenerów. Kubernetes przypisuje każdemu podowi adres IP, do którego można uzyskać dostęp z innych podów. Zasady sieciowe Kubernetes ustawiają prawa dostępu dla grup podów w taki sam sposób, w jaki grupy zabezpieczeń w chmurze służą do kontrolowania dostępu do instancji maszyn wirtualnych.

Definiowanie zasad sieciowych

Podobnie jak inne zasoby Kubernetes, zasady sieciowe są określone w formacie YAML. W poniższym przykładzie aplikacja balance dostęp do postgres:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.postgres
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: postgres
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: balance
  policyTypes:
  - Ingress

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

(Notatka. przeł.: ten zrzut ekranu, jak wszystkie kolejne podobne, powstał nie przy użyciu natywnych narzędzi Kubernetes, ale przy użyciu narzędzia Tufin Orca, które zostało opracowane przez firmę autora oryginalnego artykułu i o którym mowa na końcu materiału.)

Aby zdefiniować własną politykę sieciową, będziesz potrzebować podstawowej znajomości YAML. Język ten opiera się na wcięciach (określanych spacjami, a nie tabulatorami). Wcięty element należy do najbliższego wciętego elementu znajdującego się nad nim. Nowy element listy zaczyna się od łącznika, wszystkie pozostałe elementy mają formę kluczowa wartość.

Po opisaniu polityki w YAML użyj kubectlaby utworzyć go w klastrze:

kubectl create -f policy.yaml

Specyfikacja zasad sieciowych

Specyfikacja zasad sieciowych Kubernetes obejmuje cztery elementy:

  1. podSelector: definiuje pody, których dotyczy ta polityka (cele) - wymagane;
  2. policyTypes: wskazuje, jakie typy polityk są objęte tą polityką: ingres i/lub out - opcjonalne, ale zalecam wyraźne określenie tego we wszystkich przypadkach;
  3. ingress: określa dozwolone przychodzące ruch do docelowych podów jest opcjonalny;
  4. egress: określa dozwolone towarzyski ruch z docelowych zasobników jest opcjonalny.

Przykład wzięty ze strony Kubernetes (zastąpiłem role na app), pokazuje, w jaki sposób wykorzystywane są wszystkie cztery elementy:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:    # <<<
    matchLabels:
      app: db
  policyTypes:    # <<<
  - Ingress
  - Egress
  ingress:        # <<<
  - from:
    - ipBlock:
        cidr: 172.17.0.0/16
        except:
        - 172.17.1.0/24
    - namespaceSelector:
        matchLabels:
          project: myproject
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 6379
  egress:         # <<<
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      port: 5978

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa
Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Należy pamiętać, że wszystkie cztery elementy nie muszą być uwzględnione. Jest to jedynie obowiązkowe podSelector, można zastosować inne parametry według potrzeb.

Jeśli pominiesz policyTypes, polityka będzie interpretowana w następujący sposób:

  • Domyślnie przyjmuje się, że definiuje stronę wejściową. Jeśli polityka nie określa tego wyraźnie, system przyjmie, że cały ruch jest zabroniony.
  • Zachowanie po stronie wyjścia zostanie określone przez obecność lub brak odpowiedniego parametru wyjścia.

Aby uniknąć błędów, polecam zawsze wyrażaj to wyraźnie policyTypes.

Zgodnie z powyższą logiką, jeśli parametry ingress i / lub egress pominięty, zasada odrzuci cały ruch (patrz „Reguła usuwania” poniżej).

Domyślna zasada to Zezwalaj

Jeśli nie zdefiniowano żadnych zasad, Kubernetes domyślnie zezwala na cały ruch. Wszystkie kapsuły mogą swobodnie wymieniać między sobą informacje. Może się to wydawać sprzeczne z intuicją z punktu widzenia bezpieczeństwa, należy jednak pamiętać, że Kubernetes został pierwotnie zaprojektowany przez programistów w celu umożliwienia interoperacyjności aplikacji. Zasady sieciowe zostały dodane później.

Przestrzenie nazw

Przestrzenie nazw to mechanizm współpracy Kubernetes. Mają za zadanie izolować od siebie środowiska logiczne, przy czym domyślnie dozwolona jest komunikacja pomiędzy przestrzeniami.

Podobnie jak większość komponentów Kubernetes, zasady sieciowe znajdują się w określonej przestrzeni nazw. W bloku metadata możesz określić, do której przestrzeni należy polisa:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: my-namespace  # <<<
spec:
...

Jeśli przestrzeń nazw nie jest wyraźnie określona w metadanych, system użyje przestrzeni nazw określonej w kubectl (domyślnie namespace=default):

kubectl apply -n my-namespace -f namespace.yaml

polecam określ jawnie przestrzeń nazw, chyba że piszesz politykę ukierunkowaną na wiele przestrzeni nazw jednocześnie.

Podstawowy element podSelector w profilu wybierze pody z przestrzeni nazw, do której należy profil (odmówiono dostępu do podów z innej przestrzeni nazw).

Podobnie podSelectors w blokach wejściowych i wyjściowych może wybierać tylko pody z ich własnej przestrzeni nazw, chyba że oczywiście je połączysz namespaceSelector (zostanie to omówione w sekcji „Filtrowanie według przestrzeni nazw i podów”).

Zasady nazewnictwa zasad

Nazwy zasad są unikalne w tej samej przestrzeni nazw. W tej samej przestrzeni nie mogą znajdować się dwie polityki o tej samej nazwie, ale mogą istnieć polityki o tej samej nazwie w różnych przestrzeniach. Jest to przydatne, gdy chcesz ponownie zastosować tę samą politykę w wielu przestrzeniach.

Szczególnie podoba mi się jeden ze sposobów nazewnictwa. Polega na połączeniu nazwy przestrzeni nazw z docelowymi zasobnikami. Na przykład:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.postgres  # <<<
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: postgres
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: admin
  policyTypes:
  - Ingress

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Etykiety

Możesz dołączać niestandardowe etykiety do obiektów Kubernetes, takich jak pody i przestrzenie nazw. Etykiety (Etykiety - tagi) są odpowiednikiem tagów w chmurze. Zasady sieciowe Kubernetes korzystają z etykiet do wyboru strąkido których mają zastosowanie:

podSelector:
  matchLabels:
    role: db

… lub przestrzenie nazwktórego dotyczą. Ten przykład wybiera wszystkie pody w przestrzeniach nazw z odpowiednimi etykietami:

namespaceSelector:
  matchLabels:
    project: myproject

Jedna uwaga: podczas używania namespaceSelector upewnij się, że wybrane przestrzenie nazw zawierają poprawną etykietę. Należy pamiętać, że wbudowane przestrzenie nazw, takie jak default и kube-system, domyślnie nie zawierają etykiet.

Możesz dodać etykietę do przestrzeni w następujący sposób:

kubectl label namespace default namespace=default

Jednocześnie przestrzeń nazw w sekcji metadata powinien odnosić się do rzeczywistej nazwy przestrzeni, a nie do etykiety:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default   # <<<
spec:
...

Źródło i miejsce docelowe

Zasady zapory sieciowej składają się z reguł ze źródłami i miejscami docelowymi. Zasady sieciowe Kubernetes są definiowane dla celu – zestawu podów, do których mają zastosowanie – a następnie ustalają reguły dla ruchu przychodzącego i/lub wychodzącego. W naszym przykładzie celem polityki będą wszystkie pody w przestrzeni nazw default z etykietą i kluczem app i znaczenie db:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: db   # <<<
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - ipBlock:
        cidr: 172.17.0.0/16
        except:
        - 172.17.1.0/24
    - namespaceSelector:
        matchLabels:
          project: myproject
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 6379
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      port: 5978

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa
Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Podrozdział ingress w tej zasadzie otwiera ruch przychodzący do zasobników docelowych. Innymi słowy, ingres jest źródłem, a cel odpowiednim miejscem docelowym. Podobnie wyjście jest celem, a cel jego źródłem.

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Jest to równoważne dwóm regułom zapory sieciowej: Ingress → Target; Cel → Wyjście.

Wyjście i DNS (ważne!)

Ograniczając ruch wychodzący, zwróć szczególną uwagę na DNS - Kubernetes używa tej usługi do mapowania usług na adresy IP. Na przykład poniższe zasady nie będą działać, ponieważ nie zezwoliłeś na aplikację balance dostęp do DNS:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.balance
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: balance
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: postgres
  policyTypes:
  - Egress

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Możesz to naprawić otwierając dostęp do usługi DNS:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.balance
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: balance
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: postgres
  - to:               # <<<
    ports:            # <<<
    - protocol: UDP   # <<<
      port: 53        # <<<
  policyTypes:
  - Egress

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Ostatni element to jest pusty i dlatego pośrednio dokonuje selekcji wszystkie pody we wszystkich przestrzeniach nazw, pozwalać balance wysyłaj zapytania DNS do odpowiedniej usługi Kubernetes (zwykle działającej w przestrzeni kube-system).

To podejście działa, jednak zbyt liberalny i niepewny, ponieważ umożliwia kierowanie zapytań DNS poza klaster.

Możesz go ulepszyć w trzech kolejnych krokach.

1. Zezwalaj tylko na zapytania DNS wewnątrz klastruj, dodając namespaceSelector:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.balance
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: balance
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: postgres
  - to:
    - namespaceSelector: {} # <<<
    ports:
    - protocol: UDP
      port: 53
  policyTypes:
  - Egress

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

2. Zezwalaj na zapytania DNS tylko w obrębie przestrzeni nazw kube-system.

Aby to zrobić, musisz dodać etykietę do przestrzeni nazw kube-system: kubectl label namespace kube-system namespace=kube-system - i zapisz to w polityce za pomocą namespaceSelector:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.balance
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: balance
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: postgres
  - to:
    - namespaceSelector:         # <<<
        matchLabels:             # <<<
          namespace: kube-system # <<<
    ports:
    - protocol: UDP
      port: 53
  policyTypes:
  - Egress

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

3. Osoby z paranoją mogą pójść jeszcze dalej i ograniczyć zapytania DNS do konkretnej usługi DNS kube-system. W sekcji „Filtruj według przestrzeni nazw i podów” dowiesz się, jak to osiągnąć.

Inną opcją jest rozwiązanie DNS na poziomie przestrzeni nazw. W takim przypadku nie będzie trzeba otwierać dla każdej usługi:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.dns
  namespace: default
spec:
  podSelector: {} # <<<
  egress:
  - to:
    - namespaceSelector: {}
    ports:
    - protocol: UDP
      port: 53
  policyTypes:
  - Egress

Pusty podSelector wybiera wszystkie pody w przestrzeni nazw.

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Pierwszy mecz i kolejność zasad

W konwencjonalnych zaporach ogniowych akcja (Zezwól lub Odmów) na pakiecie jest określana na podstawie pierwszej reguły, którą pakiet spełnia. W Kubernetesie kolejność polityk nie ma znaczenia.

Domyślnie, gdy nie są ustawione żadne zasady, komunikacja między podami jest dozwolona i mogą swobodnie wymieniać informacje. Gdy zaczniesz formułować zasady, każdy pod, na który wpływa co najmniej jedna z nich, zostanie odizolowany zgodnie z rozłączeniem (logicznym OR) wszystkich polityk, które go wybrały. Pody, na które nie mają wpływu żadne zasady, pozostają otwarte.

Możesz zmienić to zachowanie za pomocą reguły usuwania.

Reguła usuwania („Odmów”)

Zasady zapory zazwyczaj odrzucają wszelki ruch, który nie jest jawnie dozwolony.

W Kubernetesie nie ma akcji odmowy, jednakże podobny efekt można osiągnąć przy zastosowaniu zwykłej (zezwalającej) polityki poprzez wybranie pustej grupy podów źródłowych (ingres):

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Ingress

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Ta zasada wybiera wszystkie pody w przestrzeni nazw i pozostawia niezdefiniowany ruch przychodzący, blokując cały ruch przychodzący.

W podobny sposób możesz ograniczyć cały ruch wychodzący z przestrzeni nazw:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-egress
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Egress

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Pamiętaj, że wszelkie dodatkowe zasady zezwalające na ruch do podów w przestrzeni nazw będą miały pierwszeństwo przed tą regułą (podobnie jak dodanie reguły zezwalającej przed regułą odmowy w konfiguracji zapory).

Zezwalaj na wszystko (Jakikolwiek, Dowolny, Zezwalaj)

Aby utworzyć zasadę Zezwalaj na wszystko, należy uzupełnić powyższą zasadę Odmów pustym elementem ingress:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all
  namespace: default
spec:
  podSelector: {}
  ingress: # <<<
  - {}     # <<<
  policyTypes:
  - Ingress

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Umożliwia dostęp z wszystkie pody we wszystkich przestrzeniach nazw (i wszystkie adresy IP) do dowolnego poda w przestrzeni nazw default. To zachowanie jest domyślnie włączone, więc zwykle nie trzeba go dalej definiować. Czasami jednak może być konieczne tymczasowe wyłączenie niektórych określonych uprawnień w celu zdiagnozowania problemu.

Regułę można zawęzić, aby umożliwić dostęp tylko do konkretny zestaw strąków (app:balance) w przestrzeni nazw default:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-to-balance
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: balance
  ingress: 
  - {}
  policyTypes:
  - Ingress

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Poniższa polityka zezwala na cały ruch przychodzący i wychodzący, w tym na dostęp do dowolnego adresu IP poza klastrem:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all
spec:
  podSelector: {}
  ingress:
  - {}
  egress:
  - {}
  policyTypes:
  - Ingress
  - Egress

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa
Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Łączenie wielu zasad

Polityki są łączone przy użyciu logicznego OR na trzech poziomach; Uprawnienia każdego poda są ustawiane zgodnie z rozłączeniem wszystkich polityk, które go dotyczą:

1. Na polach from и to Można zdefiniować trzy typy elementów (wszystkie można łączyć za pomocą OR):

  • namespaceSelector — wybiera całą przestrzeń nazw;
  • podSelector — wybiera strąki;
  • ipBlock — wybiera podsieć.

Ponadto ilość elementów (nawet identycznych) w podrozdziałach from/to bez limitu. Wszystkie zostaną połączone logicznym OR.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.postgres
  namespace: default
spec:
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: indexer
    - podSelector:
        matchLabels:
          app: admin
  podSelector:
    matchLabels:
      app: postgres
  policyTypes:
  - Ingress

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

2. Wewnątrz sekcji zasad ingress może mieć wiele elementów from (połączone za pomocą logicznego OR). Podobnie sekcja egress może zawierać wiele elementów to (również połączone przez dysjunkcję):

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.postgres
  namespace: default
spec:
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: indexer
  - from:
    - podSelector:
        matchLabels:
          app: admin
  podSelector:
    matchLabels:
      app: postgres
  policyTypes:
  - Ingress

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

3. Różne polityki są również łączone za pomocą logicznego OR

Ale łącząc je, istnieje jedno ograniczenie wskazał Chrisa Cooneya: Kubernetes może łączyć zasady tylko z różnymi policyTypes (Ingress lub Egress). Zasady definiujące wejście (lub wyjście) będą się wzajemnie zastępować.

Relacje pomiędzy przestrzeniami nazw

Domyślnie dozwolone jest udostępnianie informacji pomiędzy przestrzeniami nazw. Można to zmienić, używając polityki odmowy, która ograniczy ruch wychodzący i/lub przychodzący do przestrzeni nazw (patrz „Reguła usuwania” powyżej).

Po zablokowaniu dostępu do przestrzeni nazw (patrz „Reguła usuwania” powyżej) możesz zrobić wyjątek od zasady odmowy, zezwalając na połączenia z określonej przestrzeni nazw za pomocą namespaceSelector:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: database.postgres
  namespace: database
spec:
  podSelector:
    matchLabels:
      app: postgres
  ingress:
  - from:
    - namespaceSelector: # <<<
        matchLabels:
          namespace: default
  policyTypes:
  - Ingress

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

W rezultacie wszystkie pody w przestrzeni nazw default będzie miał dostęp do kapsuł postgres w przestrzeni nazw database. Ale co, jeśli chcesz otworzyć dostęp do postgres tylko określone pody w przestrzeni nazw default?

Filtruj według przestrzeni nazw i podów

Kubernetes w wersji 1.11 i wyższej umożliwia łączenie operatorów namespaceSelector и podSelector używając logicznego AND. Wygląda to tak:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: database.postgres
  namespace: database
spec:
  podSelector:
    matchLabels:
      app: postgres
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          namespace: default
      podSelector: # <<<
        matchLabels:
          app: admin
  policyTypes:
  - Ingress

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Dlaczego jest to interpretowane jako AND zamiast zwykłego OR?

Uwaga! podSelector nie zaczyna się od łącznika. W YAML to oznacza podSelector i stojąc przed nim namespaceSelector odnoszą się do tego samego elementu listy. Dlatego są one łączone za pomocą logicznego AND.

Dodanie łącznika wcześniej podSelector spowoduje pojawienie się nowego elementu listy, który zostanie połączony z poprzednim namespaceSelector używając logicznego OR.

Aby wybrać kapsuły z określoną etykietą we wszystkich przestrzeniach nazw, wpisz puste namespaceSelector:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: database.postgres
  namespace: database
spec:
  podSelector:
    matchLabels:
      app: postgres
  ingress:
  - from:
    - namespaceSelector: {}
      podSelector:
        matchLabels:
          app: admin
  policyTypes:
  - Ingress

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Wiele wytwórni współpracuje z I

Reguły zapory sieciowej z wieloma obiektami (hostami, sieciami, grupami) są łączone za pomocą logicznego OR. Poniższa reguła zadziała, jeśli źródło pakietu będzie zgodne Host_1 Or Host_2:

| Source | Destination | Service | Action |
| ----------------------------------------|
| Host_1 | Subnet_A    | HTTPS   | Allow  |
| Host_2 |             |         |        |
| ----------------------------------------|

Wręcz przeciwnie, w Kubernetesie różne etykiety podSelector lub namespaceSelector są łączone za pomocą logicznego AND. Na przykład poniższa reguła wybierze pody posiadające obie etykiety, role=db И version=v2:

podSelector:
  matchLabels:
    role: db
    version: v2

Ta sama logika dotyczy wszystkich typów operatorów: selektorów celów zasad, selektorów pod i selektorów przestrzeni nazw.

Podsieci i adresy IP (bloki IP)

Zapory sieciowe wykorzystują sieci VLAN, adresy IP i podsieci do segmentowania sieci.

W Kubernetes adresy IP są przypisywane do podów automatycznie i mogą się często zmieniać, dlatego etykiety służą do wybierania podów i przestrzeni nazw w zasadach sieciowych.

Podsieci (ipBlocks) są używane podczas zarządzania połączeniami przychodzącymi (wchodzącymi) lub wychodzącymi (wychodzącymi) zewnętrznymi (północ-południe). Na przykład ta zasada jest otwierana dla wszystkich podów z przestrzeni nazw default dostęp do usługi Google DNS:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: egress-dns
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 8.8.8.8/32
    ports:
    - protocol: UDP
      port: 53

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Pusty selektor podów w tym przykładzie oznacza „wybierz wszystkie pody w przestrzeni nazw”.

Ta polityka umożliwia dostęp tylko do wersji 8.8.8.8; dostęp do innego adresu IP jest zabroniony. Zasadniczo zablokowałeś dostęp do wewnętrznej usługi DNS Kubernetes. Jeśli nadal chcesz go otworzyć, zaznacz to wyraźnie.

zwykle ipBlocks и podSelectors wzajemnie się wykluczają, ponieważ wewnętrzne adresy IP podów nie są używane ipBlocks. Wskazując wewnętrzne moduły IP, w rzeczywistości zezwolisz na połączenia do/z kapsuł z tymi adresami. W praktyce nie będziesz wiedział, jakiego adresu IP użyć, dlatego nie należy ich używać do wybierania podów.

Jako kontrprzykład, poniższa polityka obejmuje wszystkie adresy IP i dlatego umożliwia dostęp do wszystkich innych podów:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: egress-any
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Możesz otworzyć dostęp tylko do zewnętrznych adresów IP, z wyłączeniem wewnętrznych adresów IP podów. Na przykład, jeśli podsieć Twojego kapsuły to 10.16.0.0/14:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: egress-any
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0
        except:
        - 10.16.0.0/14

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Porty i protokoły

Zazwyczaj pody nasłuchują jednego portu. Oznacza to, że nie można po prostu określać numerów portów w zasadach i pozostawić wszystko jako domyślne. Zaleca się jednak, aby zasady były jak najbardziej restrykcyjne, więc w niektórych przypadkach nadal można określić porty:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.postgres
  namespace: default
spec:
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: indexer
    - podSelector:
        matchLabels:
          app: admin
    ports:             # <<<
      - port: 443      # <<<
        protocol: TCP  # <<<
      - port: 80       # <<<
        protocol: TCP  # <<<
  podSelector:
    matchLabels:
      app: postgres
  policyTypes:
  - Ingress

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Należy pamiętać, że selektor ports dotyczy wszystkich elementów w bloku to lub from, który zawiera. Aby określić różne porty dla różnych zestawów elementów, należy dokonać podziału ingress lub egress na kilka podrozdziałów z to lub from i w każdym rejestrze swoje porty:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.postgres
  namespace: default
spec:
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: indexer
    ports:             # <<<
     - port: 443       # <<<
       protocol: TCP   # <<<
  - from:
    - podSelector:
        matchLabels:
          app: admin
    ports:             # <<<
     - port: 80        # <<<
       protocol: TCP   # <<<
  podSelector:
    matchLabels:
      app: postgres
  policyTypes:
  - Ingress

Wprowadzenie do zasad sieci Kubernetes dla specjalistów ds. bezpieczeństwa

Domyślna operacja portu:

  • Jeśli całkowicie pominiesz definicję portu (ports), oznacza to wszystkie protokoły i wszystkie porty;
  • Jeśli pominiesz definicję protokołu (protocol), oznacza to TCP;
  • Jeśli pominiesz definicję portu (port), oznacza to wszystkie porty.

Najlepsza praktyka: nie polegaj na wartościach domyślnych, określ wyraźnie, czego potrzebujesz.

Pamiętaj, że musisz używać portów pod, a nie portów serwisowych (więcej na ten temat w następnym akapicie).

Czy zdefiniowano zasady dla podów lub usług?

Zwykle pody w Kubernetes łączą się ze sobą za pośrednictwem usługi — wirtualnego modułu równoważenia obciążenia, który przekierowuje ruch do podów implementujących usługę. Można by pomyśleć, że zasady sieciowe kontrolują dostęp do usług, ale tak nie jest. Zasady sieciowe Kubernetes działają na portach pod, a nie na portach usług.

Na przykład, jeśli usługa nasłuchuje na porcie 80, ale przekierowuje ruch na port 8080 swoich podów, w zasadach sieciowych należy określić dokładnie 8080.

Taki mechanizm należy uznać za nieoptymalny: jeśli zmieni się wewnętrzna struktura usługi (porty, na których nasłuchują pody), konieczna będzie aktualizacja polityk sieciowych.

Nowe podejście architektoniczne wykorzystujące Service Mesh (na przykład o Istio poniżej – ok. przeł.) pozwala uporać się z tym problemem.

Czy konieczna jest rejestracja zarówno wejścia, jak i wyjścia?

Krótka odpowiedź brzmi: tak, aby pod A mógł komunikować się z podem B, musi mieć możliwość utworzenia połączenia wychodzącego (w tym celu należy skonfigurować politykę ruchu wychodzącego), a pod B musi mieć możliwość akceptowania połączenia przychodzącego ( w tym celu potrzebna jest polityka dotycząca ingresu).

Jednak w praktyce można polegać na domyślnej polityce zezwalającej na połączenia w jednym lub obu kierunkach.

Jeśli jakiś pod-źródło zostanie wybrany przez jednego lub więcej wyjście-polityków, nałożone na nie ograniczenia zostaną określone przez ich rozłączenie. W takim przypadku będziesz musiał jawnie zezwolić na połączenie z kapsułą -do adresata. Jeśli pod nie jest wybrany przez żadną zasadę, jego ruch wychodzący (wychodzący) jest domyślnie dozwolony.

Podobnie los kapsułyadres, wybrane przez jednego lub więcej ingres-politycy, zostaną określone na podstawie ich alternatywy. W takim przypadku musisz jawnie zezwolić mu na odbieranie ruchu z zasobnika źródłowego. Jeśli pod nie jest wybrany przez żadną zasadę, cały ruch przychodzący do niego jest domyślnie dozwolony.

Zobacz Stanowy lub Bezstanowy poniżej.

Dzienniki

Zasady sieciowe Kubernetes nie mogą rejestrować ruchu. Utrudnia to określenie, czy polityka działa zgodnie z oczekiwaniami i znacznie komplikuje analizę bezpieczeństwa.

Kontrola ruchu do usług zewnętrznych

Zasady sieciowe Kubernetes nie pozwalają na określenie w pełni kwalifikowanej nazwy domeny (DNS) w sekcjach ruchu wychodzącego. Fakt ten prowadzi do znacznych niedogodności przy próbie ograniczenia ruchu do zewnętrznych miejsc docelowych, które nie mają stałego adresu IP (takich jak aws.com).

Kontrola zasad

Zapory sieciowe ostrzegą Cię lub nawet odmówią przyjęcia niewłaściwej polityki. Kubernetes również przeprowadza pewną weryfikację. Ustawiając politykę sieciową poprzez kubectl, Kubernetes może zadeklarować, że jest ona błędna i odmówić jej przyjęcia. W pozostałych przypadkach Kubernetes pobierze polisę i uzupełni ją o brakujące szczegóły. Można je zobaczyć za pomocą polecenia:

kubernetes get networkpolicy <policy-name> -o yaml

Należy pamiętać, że system walidacji Kubernetes nie jest nieomylny i może przeoczyć niektóre typy błędów.

Egzekucja

Kubernetes sam w sobie nie implementuje zasad sieciowych, lecz jest jedynie bramą API, która deleguje ciężar kontroli na podstawowy system zwany interfejsem sieciowym kontenerów (CNI). Ustawianie polityk w klastrze Kubernetes bez przypisania odpowiedniego CNI jest równoznaczne z tworzeniem polityk na serwerze zarządzania zaporami sieciowymi bez ich późniejszego instalowania na zaporach ogniowych. Od Ciebie zależy, czy będziesz mieć przyzwoite CNI lub, w przypadku platform Kubernetes, hostowane w chmurze (możesz zobaczyć listę dostawców tutaj - około. przeł.), włącz zasady sieciowe, które ustawią CNI za Ciebie.

Pamiętaj, że Kubernetes nie ostrzeże Cię, jeśli ustawisz politykę sieciową bez odpowiedniego pomocniczego CNI.

Stanowy czy bezpaństwowy?

Wszystkie CNI Kubernetes, z którymi się spotkałem, są stanowe (na przykład Calico używa Linux Conntrack). Dzięki temu moduł może odbierać odpowiedzi na zainicjowane połączenie TCP bez konieczności jego ponownego nawiązywania. Nie znam jednak standardu Kubernetes, który gwarantowałby stanowość.

Zaawansowane zarządzanie polityką bezpieczeństwa

Oto kilka sposobów na poprawę egzekwowania zasad bezpieczeństwa w Kubernetes:

  1. Wzorzec architektoniczny Service Mesh korzysta z kontenerów przyczepek w celu zapewnienia szczegółowej telemetrii i kontroli ruchu na poziomie usługi. Jako przykład możemy wziąć Podobnie.
  2. Niektórzy dostawcy CNI rozszerzyli swoje narzędzia tak, aby wykraczały poza zasady sieciowe Kubernetes.
  3. Tufin Orka Zapewnia widoczność i automatyzację zasad sieciowych Kubernetes.

Pakiet Tufin Orca zarządza politykami sieciowymi Kubernetes (i jest źródłem powyższych zrzutów ekranu).

informacje dodatkowe

wniosek

Polityki sieciowe Kubernetes oferują dobry zestaw narzędzi do segmentacji klastrów, ale nie są intuicyjne i mają wiele subtelności. Uważam, że z powodu tej złożoności wiele istniejących polityk klastrowych zawiera błędy. Możliwe rozwiązania tego problemu obejmują automatyzację definicji zasad lub użycie innych narzędzi do segmentacji.

Mam nadzieję, że ten przewodnik pomoże wyjaśnić niektóre pytania i rozwiązać problemy, które możesz napotkać.

PS od tłumacza

Przeczytaj także na naszym blogu:

Źródło: www.habr.com

Dodaj komentarz