Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

Pozn. přek.: Autor článku — Reuven Harrison — má více než 20 let zkušeností ve vývoji softwaru a v současné době je technickým ředitelem a spoluzakladatelem společnosti Tufin, která vytváří řešení pro správu bezpečnostních politik. Při zvažování síťových politik Kubernetes jako dostatečně mocného nástroje pro segmentaci sítě v clusteru zároveň tvrdí, že jejich praktické uplatnění není tak jednoduché. Tento materiál (poměrně obsáhlý) má zlepšit povědomí odborníků v této oblasti a pomoci jim při vytváření potřebných konfigurací.

Dnes mnoho společností stále častěji vybírá Kubernetes pro nasazení svých aplikací. Zájem o tento software je tak vysoký, že někteří nazývají Kubernetes „novým operačním systémem pro datová centra“. Postupně je Kubernetes (nebo k8s) vnímán jako kritická součást podnikání, která vyžaduje organizaci zralých obchodních procesů, včetně zajištění síťové bezpečnosti.

Pro bezpečnostní specialisty, kteří jsou zmatení prací s Kubernetes, může být překvapením výchozí politika této platformy: povolit vše.

Tato příručka pomůže pochopit vnitřní fungování síťových politik; poznat, jak se liší od pravidel běžných brán firewall. Také se podíváme na některé úskalí a poskytneme doporučení, která pomohou chránit aplikace v Kubernetes.

Síťové politiky Kubernetes

Mechanismus síťových politik Kubernetes umožňuje řídit vzájemné interakce aplikací nasazených na platformě na síťové úrovni (třetí úroveň modelu OSI). Síťové politiky postrádají některé pokročilé funkce moderních brán firewall, jako je řízení na 7. úrovni OSI a detekce hrozeb, nicméně zajišťují základní úroveň síťové bezpečnosti, což je dobrý výchozí bod.

Síťové politiky ovládají komunikaci mezi pod'y

Pracovní zátěže v Kubernetes jsou rozděleny mezi pod’y, které se skládají z jednoho nebo více kontejnerů, nasazených společně. Kubernetes každému pod’u přiřazuje IP adresu, která je dostupná z jiných pod’ů. Síťové politiky Kubernetes určují přístupová práva pro skupiny pod’ů podobným způsobem, jakým se bezpečnostní skupiny v cloudu používají k řízení přístupu k instancím virtuálních strojů.

Definice síťových politik

Jako všechny ostatní zdroje Kubernetes se síťové politiky definují v jazyce YAML. V následujícím příkladu je aplikaci balance přístup otevřen k 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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

(Pozn. přek.: tento snímek obrazovky, stejně jako všechny následující podobné, byl vytvořen pomocí nástroje Tufin Orca, jehož vývoj stojí za autorem původního článku, který je zmíněn na konci materiálu.

Pro definici vlastní síťové politiky budete potřebovat základní znalosti YAML. Tento jazyk je založen na odsazeních (určených mezerami, nikoli tabulátory). Element s odsazením náleží nejbližšímu prvku s odsazením nad ním. Nový prvek seznamu začíná pomlčkou, všechny ostatní prvky mají podobu klíč-hodnota.

Po popisu politiky v YAML použijte kubectl, abyste ji vytvořili v klastru:

kubectl create -f policy.yaml

Specifikace síťové politiky

Specifikace síťové politiky Kubernetes zahrnuje čtyři prvky:

  1. podSelector: určuje pod’y, které jsou touto politikou dotčeny (cíle) — povinné;
  2. policyTypes: uvádí, jaké typy politik jsou zahrnuty v této: ingress a/nebo egress — nepovinné, doporučuji však jej jasně uvádět ve všech případech;
  3. ingress: určuje povolený příchozí provoz do cílových pod’ů — nepovinné;
  4. egress: určuje povolený odchozí provoz z cílových pod’ů — nepovinné.

Příklad převzatý z webu Kubernetes (nahradil jsem role na app), ukazuje, jak jsou používány všechny čtyři prvky:

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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení
Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

Všimněte si, že není nutné zahrnout všechny čtyři prvky. Povinný je pouze podSelector, ostatní parametry mohou být použity dle potřeby.

Pokud se vynechá policyTypes, bude politiku interpretovat následovně:

  • Ve výchozím nastavení se předpokládá, že definuje ingress stranu. Pokud politika neobsahuje žádné jasné pokyny v tomto smyslu, systém bude považovat, že veškerý provoz je zakázán.
  • Chování na egress straně bude určeno přítomností nebo nepřítomností odpovídajícího egress parametru.

Abychom se vyhnuli chybám, doporučuji vždy jasně uvést policyTypes.

V souladu s výše uvedenou logikou, pokud jsou parametry ingress a/nebo egress vynechány, politika bude zakazovat veškerý provoz (viz „Pravidlo čištění“ níže).

Výchozí politika — povolit

Pokud nejsou politiky definovány, Kubernetes ve výchozím nastavení povoluje veškerý provoz. Všechny pod jednotky si mohou volně vyměňovat informace. Z pohledu bezpečnosti se to může zdát nelogické, ale pamatujte, že Kubernetes byl původně navržen vývojáři s cílem umožnit interakci aplikací. Síťové politiky byly přidány později.

Prostor jmen

Prostory jmen (Namespaces) jsou mechanismem kolektivní práce Kubernetes. Jsou určeny k izolaci logických prostředí od sebe, přičemž výměna dat mezi prostory je ve výchozím nastavení povolena.

Stejně jako většina komponent Kubernetes, síťové politiky se nacházejí v určitém prostoru jmen. V bloku metadata můžete uvést, kterému prostoru náleží politika:

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

Pokud není prostor jmen v metadatech jasně uveden, systém použije namespace uvedené v kubectl (ve výchozím nastavení namespace=default):

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

Doporučuji jasně uvést namespace, pokud nepíšete politiku určenou pro více prostorů názvů současně.

Hlavní prvek podSelector v politice bude vybírat pod’y z prostoru názvů, k němuž politika patří (nema přístup k pod’y z jiného prostoru názvů).

Podobně podSelector’y v blocích ingress a egress mohou vybírat pod’y pouze ze svého prostoru názvů, pokud je samozřejmě nesdružíte pomocí namespaceSelector (o tom bude řeč v části „Filtr podle prostorů názvů a pod’y“).

Pravidla pojmenování politik

Názvy politik jsou jedinečné v rámci jednoho prostoru názvů. Dvě politiky se stejným názvem v jednom prostoru nemohou existovat, ale mohou existovat politiky se stejnými názvy v různých prostorech. Je to užitečné, když chcete znovu použít jednu a tutéž politiku na několika prostorech.

Zvlášť se mi líbí jeden z návrhů pojmenování. Spočívá v tom, že se spojuje název prostoru názvů s cílovými pod’y. Například:

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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

Štítky

K objektům Kubernetes, jako jsou pod’y a prostory názvů, lze připojovat vlastní štítky. Štítky (labels — značky) jsou ekvivalentem tagů v cloudu. Síťové politiky Kubernetes používají štítky k výběru pod’y, na které se vztahují:

podSelector:
  matchLabels:
    role: db

… nebo prostorů názvů, na které se vztahují. V tomto příkladu se vybírají všechny pod’y v prostorech názvů se shodnými štítky:

namespaceSelector:
  matchLabels:
    project: myproject

Jedno varování: při použití namespaceSelector se ujistěte, že vybrané prostory názvů obsahují požadovaný štítek. Mějte na paměti, že vestavěné prostory názvů, jako je default a kube-system, ve výchozím nastavení neobsahují štítky.

Štítek k prostoru se dá přidat následujícím způsobem:

kubectl label namespace default namespace=default

Přitom namespace v části metadata by měl odkazovat na skutečné jméno prostoru, a ne na štítek:

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

Zdroj a adresát

Politiky pro firewally se skládají z pravidel s původci a příjemci. Síťové politiky Kubernetes jsou definovány pro cílový soubor podů, na které se vztahují, a nastavují pravidla pro příchozí (ingress) a/nebo odchozí (egress) provoz. V našem příkladu cílem politiky budou všechny pody v prostoru názvů default s označením s klíčem app a hodnotou 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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení
Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

Podrobnost ingress v této politice otevírá příchozí provoz pro cílové pody. Jinými slovy, ingress je zdrojem, zatímco cíl je příslušným příjemcem. Podobně egress je příjemcem, zatímco cíl je jeho zdrojem.

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

To odpovídá dvěma pravidlům pro firewall: Ingress → Cíl; Cíl → Egress.

Egress a DNS (důležité!)

Omezením odchozího provozu, věnujte zvláštní pozornost DNS — Kubernetes používá tuto službu pro mapování služeb na IP adresy. Například následující politika nebude fungovat, protože jste nepovolili aplikaci balance přístup k 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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

Opravit to lze otevřením přístupu k DNS službě:

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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

Poslední prvek to — prázdný, a proto nepřímo vybírá všechny pody ve všech prostorech názvů, což umožňuje balance odesílat DNS dotazy na příslušnou službu Kubernetes (obvykle běží v prostoru kube-system).

Tento přístup funguje, nicméně je příliš povolující a nebezpečný, protože umožňuje, aby DNS dotazy směřovaly mimo cluster.

Vylepšit to lze třemi po sobě jdoucími kroky.

1. Povolte DNS dotazy pouze uvnitř na cluster přidáním 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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

2. Umožněte DNS dotazy pouze v rámci jmenného prostoru kube-system.

K tomu je potřeba přidat štítek do jmenného prostoru kube-system: kubectl label namespace kube-system namespace=kube-system — a zapsat ho do politiky prostřednictvím 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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

3. Paranoici mohou jít ještě dál a omezit DNS dotazy na konkrétní DNS službu v kube-system. V části „Filtr podle jmenných prostorů a podů“ bude popsáno, jak toho dosáhnout.

Další možností je povolit DNS na úrovni jmenného prostoru. V tomto případě ho nebude nutné otevírat pro každou službu:

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

Prázdný podSelector vybírá všechny pody v jmenném prostoru.

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

První zápas a pořadí pravidel

Ve standardních firewallech se akce („Povolit“ nebo „Zamezit“) na paket určuje prvním pravidlem, které vyhovuje. V Kubernetes nemá pořadí politik žádný význam.

Ve výchozím nastavení, když nejsou určeny politiky, je komunikace mezi podmi povolena a mohou si volně vyměňovat informace. Jakmile začnete formulovat politiky, každý pod, který je ovlivněn alespoň jednou z nich, se stává izolovaným podle disjunkce (logického NEBO) všech politik, které je vybraly. Pody, které nejsou dotčeny žádnou politikou, zůstávají otevřené.

Toto chování lze změnit pomocí pravidla vyřazení.

Pravidlo vyřazení („Zamezit“)

Politiky firewallu obvykle zamezují jakémukoli výslovně nepovolenému provozu.

V Kubernetes neexistuje akce „zamezit“ (deny),ale podobného efektu lze dosáhnout s běžnou (povolující) politikou, pokud zvolíte prázdnou skupinu podů zdrojů (ingress):

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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

Tato politika vybere všechny podů v prostorách jmen a ponechá ingress neurčený, což zakazuje veškerý příchozí provoz.

Podobným způsobem lze omezit veškerý odchozí provoz z prostorů jmen:

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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

Mějte na paměti, že jakákoli další politika, která povoluje provoz k podům v prostoru jmen, bude mít prioritu před tímto pravidlem (analogicky k přidání povolujícího pravidla před zakázající v konfiguraci firewallu).

Povolit vše (Any-Any-Any-Allow)

Chcete-li vytvořit politiku „Povolit vše“, musíte doplnit uvedenou zakazující politiku prázdným prvkem ingress:

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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

Otevírá přístup ze všech podů ve všech prostorech jmen (a všech IP) k libovolnému podu v prostoru jmen default. Takové chování je ve výchozím nastavení povoleno, takže obvykle není potřeba ho dodatečně určovat. Nicméně někdy může být potřeba dočasně zakázat některá konkrétní povolení pro diagnostiku problému.

Pravidlo lze zúžit a povolit přístup pouze k určitému souboru podů (app:balance) v prostoru jmen default:

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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

Následující politika povoluje veškerý příchozí (ingress) a odchozí (egress) provoz, včetně přístupu k libovolné IP mimo cluster:

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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení
Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

Kombinace několika politik

Politiky se kombinují logickým OR na třech úrovních; povolení každého podu jsou nastavena podle disjunkce všech politik, které se ho dotýkají:

1. V polích from a to můžete definovat tři typy prvků (všechny se kombinují pomocí OR):

  • namespaceSelector — vybírá celé jméno prostoru;
  • podSelector — vybírá pody;
  • ipBlock — vybírá podsíť.

Přitom počet prvků (i stejných) v podřízených from/to není omezen. Všechny budou sloučeny logickým 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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

2. Uvnitř politiky oddíl ingress může mít mnoho prvků from (kombinují se logickým NEBO). Podobně oddíl egress může zahrnovat mnoho prvků to (také se kombinují disjunktivně):

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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

3. Různé politiky se také kombinují logickým NEBO

Ale při jejich kombinaci existuje jedno omezení, na které uvedl Chris Cooney: Kubernetes může kombinovat politiky pouze s různými policyTypes (Ingress nebo Egress). Politiky definující ingress (nebo egress) si vzájemně přeepisují.

Spojení mezi pracovními prostory

Ve výchozím nastavení je komunikace mezi pracovními prostory povolena. To lze změnit pomocí restriktivní politiky, která omezuje odchozí a/nebo příchozí provoz do pracovního prostoru (viz "Čistící pravidlo" výše).

Zablokováním přístupu do pracovního prostoru (viz "Čistící pravidlo" výše) můžete udělat výjimku v restriktivní politice, povolením připojení z určitého pracovního prostoru 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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

V důsledku toho budou všechny pod’y v pracovním prostoru default mít přístup k pod’m Postgres v jmenném prostoru database. Ale co když chcete otevřít přístup pouze konkrétním pod’m v pracovním prostoru Postgres Filtr podle pracovních prostorů a pod’ů default?

Kubernetes verze 1.11 a výše umožňuje kombinovat operátory

pomocí logického A. Vypadá to následovně: namespaceSelector a podSelector 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

Proč je to interpretováno jako A místo obvyklého NEBO?

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

nezačíná pomlčkou. V YAML to znamená, že

Všimněte si, že podSelector a to, co je před ním podSelector se vztahují na stejný prvek seznamu. Proto se kombinují logickým A. namespaceSelector Přidání pomlčky před

Přidání pomlčky před podSelector povede k vytvoření nového prvku seznamu, který se bude kombinovat s předchozím namespaceSelector pomocí logického NEBO.

Chcete-li vybrat pod’y s určitou značkou ve všech prostorách názvů, zadejte prázdný 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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

Vícenásobné značky se kombinují s A

Pravidla pro firewall se spoustou objektů (hostitelé, sítě, skupiny) se kombinují pomocí logického NEBO. Následující pravidlo se spustí, pokud zdroj paketu odpovídá Host_1 NEBO Host_2:

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

Naopak, v Kubernetes se různé značky v podSelector nebo namespaceSelector kombinují logickým A. Například následující pravidlo vybere pod’y, které mají obě značky, role=db A version=v2:

podSelector:
  matchLabels:
    role: db
    version: v2

Stejná logika platí pro všechny typy operátorů: selektory cílů politiky, selektory pod’ů a selektory prostorů názvů.

Podniky a IP adresy (IPBlocks)

Pro segmentaci sítě firewally používají VLAN, IP adresy a podsítě.

V Kubernetes jsou IP adresy automaticky přidělovány pod’am a mohou se často měnit, proto se pro výběr pod’ů a prostorů názvů v síťových politikách používají značky.

Podsítě (ipBlocks) se používají při řízení příchozích (ingress) nebo odchozích (egress) externích (Sever-Jih) připojení. Například tato politika otevírá přístup všem pod’am z prostoru názvů default k DNS službě Google:

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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

Prázdný selektor pod’ů v tomto příkladu znamená „vybrat všechny pod’y v prostoru názvů“.

Tato politika otevírá přístup pouze k 8.8.8.8; přístup k jakékoli jiné IP je zakázán. Tímto způsobem jste v podstatě zablokovali přístup k interní službě DNS Kubernetes. Pokud ji však chcete otevřít, uveďte to výslovně.

Obvykle ipBlocks a podSelectors jsou vzájemně se vylučující, protože interní IP adresy pod’ů se nepoužívají v ipBlocks. Uvedením interní IP pod’ů, skutečně povolíte připojení k/od podů z těchto adres. V praxi nebudete vědět, kterou IP adresu použít, proto je nejlepší je nepoužívat pro výběr podů.

Jako kontra příklad následující politika zahrnuje všechny IP a tudíž povoluje přístup ke všem ostatním podům:

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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

Můžete povolit přístup pouze k externím IP, vyloučením interních IP adres podů. Například, pokud je podsíť vašeho podu 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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

Porty a protokoly

Obvykle pady naslouchají na jednom portu. To znamená, že můžete jednoduše neuveřejňovat čísla portů v politikách a nechat všechno na výchozím nastavení. Nicméně doporučuje se, aby politiky byly co nejvíce restriktivní, proto je v některých případech možné uvést 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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

Všimněte si, že selektor ports se aplikuje na všechny prvky v bloku to nebo from, ve kterém se nachází. Abyste uvedli různé porty pro různé sady prvků, rozdělte ingress nebo egress na několik podoblastí s to nebo from a v každé uveďte své 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

Úvod do síťových politik Kubernetes pro odborníky na zabezpečení

Funkce portů podle výchozího nastavení:

  • Pokud zcela vynecháte definici portů (ports), znamená to všechny protokoly a všechny porty;
  • Pokud vynecháte definici protokolu (protocol), znamená to TCP;
  • Pokud vynecháte definici portu (port), znamená to všechny porty.

Nejlepší praxe: nespolehejte se na výchozí hodnoty, zadejte, co potřebujete, jasně.

Všimněte si, že je třeba používat porty podů, nikoli služeb (více o tom v dalším odstavci).

Jsou politiky definovány pro pody nebo služby?

Obvykle se pody v Kubernetes vzájemně komunikují přes službu — virtuální vyrovnávač zatížení, který směruje provoz k podům, které službu realizují. Můžete si myslet, že síťové politiky kontrolují přístup ke službám, ale to není pravda. Síťové politiky Kubernetes fungují s porty podů, nikoli služeb.

Například pokud služba naslouchá na portu 80, ale směruje provoz na port 8080 svých podů, je nutné v síťové politice specifikovat právě 8080.

Takový mechanismus je třeba považovat za suboptimální: při změně vnitřní struktury služby (porty, na kterých naslouchají pody) bude nutné aktualizovat síťové politiky.

Nový architektonický přístup pomocí Service Mesh (například viz Istio níže — pozn. překl.) umožňuje tuto problematiku vyřešit.

Je třeba specifikovat jak Ingress, tak Egress?

Krátká odpověď — ano, aby se pod A mohl spojit s pod B, je třeba mu povolit vytváření výstupního spojení (k tomu je nutné nastavit egress politiku), a pod B musí mít možnost přijímat příchozí spojení (k tomu je zapotřebí ingress politika).

V praxi se však můžete spolehnout na výchozí politiku, která povoluje spojení v jednom nebo obou směrech.

Pokud je určitý podzdroj vybrán jednou nebo více egress-politiky, budou omezení na něj uvalená určena jejich disjunkcí. V tomto případě je třeba explicitně povolit připojení k podu-adresátovi. Pokud pod není vybrán žádnou politikou, jeho výstupní (egress) provoz je ve výchozím nastavení povolen.

Podobně osud podu-adresáta, vybraného jednou nebo více ingress-politiky, bude určen jejich disjunkcí. V tomto případě je potřeba mu explicitně povolit přijímat provoz od podu-zdroje. Pokud pod není vybrán žádnou politikou, celý příchozí (ingress) provoz pro něj je ve výchozím nastavení povolen.

Viz bod „Stateful nebo Stateless“ níže.

Logy

Síťové politiky Kubernetes neumí logovat provoz. To komplikuje určení, zda politika funguje správně, a značně ztěžuje analýzu v oblasti bezpečnosti.

Kontrola nad provozem k externím službám

Kubernetes síťové politiky neumožňují uvést plnohodnotné doménové jméno (DNS) v sekcích egress. Tento fakt způsobuje značné potíže při pokusu o omezení provozu na externí adresáty bez pevné IP adresy (například aws.com).

Kontrola politiky

Firewall vás upozorní nebo dokonce odmítne přijmout chybovou politiku. Kubernetes také provádí určitou verifikaci. Při zadávání síťové politiky přes kubectl může Kubernetes prohlásit, že je špatná, a odmítnout ji přijmout. V jiných případech Kubernetes politiku přijme a doplní ji o chybějící detaily. Ty lze zobrazit pomocí příkazu:

kubernetes get networkpolicy  -o yaml

Mějte na paměti, že systém kontroly Kubernetes není neomylný a může propustit některé typy chyb.

Provádění

Kubernetes sama síťové politiky neimplementuje, ale slouží jako API brána, která přenáší náročnou práci na řízení na podkladový systém zvaný Container Networking Interface (CNI). Nastavení politik v clusterech Kubernetes bez přiřazení odpovídajícího CNI je podobné jako vytváření politik na správce firewallu bez jejich následné instalace do firewallů. Musíte se sami ujistit o přítomnosti kvalitního CNI nebo, v případě cloudových Kubernetes platforem, (se seznamem poskytovatelů můžete seznámit zde — pozn. př.), aktivovat síťové politiky, které CNI nastaví za vás.

Všimněte si, že Kubernetes vás neupozorní, pokud nastavíte síťovou politiku bez odpovídajícího pomocného CNI.

Stavový nebo stateless?

Všechny CNI Kubernetes, se kterými jsem se setkal, uchovávají stav (například Calico používá Linux conntrack). To umožňuje podu získávat odpovědi na TCP spojení, které inicioval, aniž by bylo nutné jej znovu navazovat. Přitom nevím o žádném standardu Kubernetes, který by zaručoval uchovávání stavu.

Pokročilé řízení bezpečnostní politiky

Zde je několik způsobů, jak zvýšit efektivitu provádění bezpečnostní politiky v Kubernetes:

  1. Architektonický vzor Service Mesh využívá sidecar kontejnery k zajištění podrobné telemetrie a kontroly provozu na úrovni služeb. Příkladem může být Istio.
  2. Někteří poskytovatelé CNI rozšířili své nástroje tak, aby přesáhly rámec síťových politik Kubernetes.
  3. Tufin Orca zaručuje transparentnost a automatizaci síťových politik Kubernetes.

Balíček Tufin Orca spravuje síťové politiky Kubernetes (a slouží jako zdroj obrazovek, které byly uvedeny výše).

Další informace

Závěr

Síťové politiky Kubernetes nabízejí slušnou sadu nástrojů pro segmentaci clusterů, ale jsou intuitivně nesrozumitelné a mají mnoho nuancí. Domnívám se, že kvůli této složitosti obsahuje mnoho existujících clusterů chyby. Možnými řešeními této situace jsou automatizace definic politik nebo použití jiných prostředků segmentace.

Doufám, že tato příručka pomůže objasnit některé otázky a vyřešit problémy, se kterými se můžete setkat.

P.S. od překladatele

Přečtěte si také náš blog:

Zdroj: habr.com

Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery 🔥 Koupit spolehlivý hosting pro webové stránky s ochranou proti DDoS, VPS VDS servery | ProHoster