En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Bemærk. overs.: Forfatteren af ​​artiklen - Reuven Harrison - har over 20 års erfaring med softwareudvikling, og er i dag CTO og medstifter af Tufin, en virksomhed med løsninger til styring af sikkerhedspolitik. Selvom han anser Kubernetes netværkspolitikker for at være kraftfulde nok til at segmentere netværket i en klynge, mener han også, at de ikke er så nemme at implementere i praksis. Dette materiale (temmelig omfangsrigt) er beregnet til at forbedre specialisternes bevidsthed i denne sag og hjælpe dem med at skabe de nødvendige konfigurationer.

I dag vælger mange virksomheder i stigende grad Kubernetes til at køre deres applikationer. Interessen for denne software er så stor, at nogle kalder Kubernetes "det nye styresystem til datacentre." Efterhånden begynder Kubernetes (eller k8s) at blive opfattet som en kritisk del af virksomheden, der kræver organisering af modne forretningsprocesser, herunder netværkssikkerhed.

For sikkerhedsprofessionelle, der har været forvirrede over at arbejde med Kubernetes, kan standardpolitikken for denne platform være en reel opdagelse: tillad alt.

Denne guide vil hjælpe dig med at forstå netværkspolitikkernes indre funktion; forstå, hvordan de adskiller sig fra reglerne for almindelige firewalls. Den vil også tale om nogle af faldgruberne og give anbefalinger, der vil hjælpe med at beskytte applikationer i Kubernetes.

Kubernetes netværkspolitikker

Kubernetes-netværkspolitikmekanismen giver dig mulighed for at styre interaktionen mellem applikationer, der er implementeret på platformen på netværkslaget (det tredje i OSI-modellen). Netværkspolitikker mangler nogle af de avancerede funktioner i moderne firewalls, såsom OSI lag 7-kontrol og trusselsdetektion, men de giver et grundlæggende lag af netværkssikkerhed, der er et godt udgangspunkt.

Netværkspolitikker styrer kommunikation mellem pods

Arbejdsbelastninger i Kubernetes er fordelt på tværs af pods, som består af en eller flere containere, der er installeret sammen. Kubernetes tildeler hver pod en IP-adresse, der er tilgængelig fra andre pods. Kubernetes-netværkspolitikker angiver adgangstilladelser for grupper af pods på samme måde, som sikkerhedsgrupper i skyen bruges til at kontrollere adgangen til virtuelle maskiner.

Definition af netværkspolitikker

Ligesom andre Kubernetes-ressourcer er netværkspolitikker angivet i YAML. I eksemplet nedenfor er applikationen balance åbner adgang til 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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

(Bemærk. overs.: dette skærmbillede, ligesom alle efterfølgende lignende skærmbilleder, blev ikke oprettet ved hjælp af native Kubernetes-værktøjer, men ved hjælp af Tufin Orca-værktøjet, som blev udviklet af firmaet til forfatteren af ​​den originale artikel, og som er nævnt i slutningen af ​​materialet.)

Grundlæggende viden om YAML er nødvendig for at definere din egen netværkspolitik. Dette sprog er baseret på indrykning (specificeret med mellemrum, ikke tabulatorer). Det indrykkede element hører til det nærmeste indrykkede element over det. Det nye element på listen starter med en bindestreg, alle andre elementer er af formen nøgleværdi.

Efter at have beskrevet politikken i YAML, brug kubectlfor at oprette det i klyngen:

kubectl create -f policy.yaml

Netværkspolitikspecifikation

Kubernetes netværkspolitikspecifikation omfatter fire elementer:

  1. podSelector: definerer de pods, der er berørt af denne politik (mål) - påkrævet;
  2. policyTypes: angiver, hvilke typer politikker der er inkluderet i denne: indgang og/eller udgang - valgfri, men jeg anbefaler, at du udtrykkeligt specificerer det i alle tilfælde;
  3. ingress: definerer tilladt indgående trafik til målpods - valgfrit;
  4. egress: definerer tilladt udgående trafik fra target pods er valgfrit.

Et eksempel lånt fra Kubernetes-webstedet (jeg erstattede roleapp), viser, hvordan alle fire elementer bruges:

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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle
En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Bemærk, at det ikke er nødvendigt at inkludere alle fire elementer. Det er kun påkrævet podSelector, kan resten af ​​parametrene bruges efter ønske.

Hvis du undlader policyTypes, vil politikken blive fortolket som følger:

  • Det antages som standard at definere indgangssiden. Hvis politikken ikke udtrykkeligt angiver dette, vil systemet antage, at al trafik er forbudt.
  • Opførslen på udgangssiden vil blive bestemt af tilstedeværelsen eller fraværet af den tilsvarende udgangsparameter.

For at undgå fejl, anbefaler jeg altid være eksplicit policyTypes.

Ifølge logikken ovenfor, i tilfælde af parametrene ingress og / eller egress udeladt, vil politikken afvise al trafik (se "Sweep Rule" nedenfor).

Standardpolitik - tillad

Hvis der ikke er defineret nogen politikker, tillader Kubernetes al trafik som standard. Alle pods kan frit udveksle information med hinanden. Fra et sikkerhedssynspunkt kan dette virke kontraintuitivt, men husk at Kubernetes oprindeligt blev skabt af udviklere med det formål at gøre applikationer interoperable. Netværkspolitikker blev tilføjet senere.

Navneområder

Navneområder er Kubernetes-samarbejdsmekanismen. De er designet til at isolere logiske miljøer fra hinanden, mens de som standard tillader kommunikation mellem rum.

Som de fleste Kubernetes-komponenter lever netværkspolitikker i et specifikt navneområde. I blokken metadata du kan angive, hvilket rum politikken tilhører:

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

Hvis navneområdet ikke er eksplicit angivet i metadataene, vil systemet bruge det navneområde, der er angivet i kubectl (standard namespace=default):

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

jeg anbefaler angiv navneområde eksplicit, medmindre du skriver en politik, der er målrettet mod flere navneområder på én gang.

Primær element podSelector i politikken vil vælge pods fra det navneområde, som politikken tilhører (den har ikke adgang til pods fra et andet navneområde).

Tilsvarende podSelectors i ind- og udgangsblokke kan kun vælge pods fra deres eget navneområde, medmindre du selvfølgelig kombinerer dem med namespaceSelector (Dette vil blive diskuteret i afsnittet "Filtrer efter navnerum og pods").

Regler for navngivning af politik

Politiknavne er unikke inden for det samme navneområde. Der kan ikke være to politikker med samme navn i samme rum, men der kan være politikker med samme navn i forskellige rum. Dette er nyttigt, når du vil genanvende den samme politik på tværs af flere områder.

Jeg kan især godt lide en af ​​navngivningsmetoderne. Det består af at sammenkæde navnerummets navn med målpods. For eksempel:

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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Etiketter

Brugerdefinerede etiketter kan knyttes til Kubernetes-objekter såsom pods og navnerum. Etiketter (etiketter tags) svarer til tags i skyen. Kubernetes netværkspolitikker bruger etiketter til at vælge bælgsom de gælder for:

podSelector:
  matchLabels:
    role: db

… eller navnerumsom de gælder for. Dette eksempel vælger alle pods i navneområder med matchende etiketter:

namespaceSelector:
  matchLabels:
    project: myproject

En advarsel: ved brug namespaceSelector sørg for, at de navneområder, du vælger, indeholder den korrekte etiket. Vær opmærksom på, at indbyggede navnerum som f.eks default и kube-system, indeholder ikke etiketter som standard.

Du kan tilføje en etiket til et mellemrum som dette:

kubectl label namespace default namespace=default

I dette tilfælde navnerummet i sektionen metadata skal referere til det faktiske navn på rummet, ikke etiketten:

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

Kilde og destination

Firewall-politikker består af kilde- og destinationsregler. Kubernetes netværkspolitikker defineres pr. mål, det sæt af pods, de gælder for, og sætter derefter regler for indgående og/eller udgående trafik. I vores eksempel vil politikmålet være alle pods i navneområdet default med nøglelabel app og mening 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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle
En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Underafsnit ingress i denne politik åbner indgående trafik til målpods. Med andre ord er indgangen kilden, og målet er den tilsvarende destination. Tilsvarende er udgang destinationen, og målet er dets kilde.

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Dette svarer til to firewall-regler: Ingress → Target; Mål → Udgang.

Egress og DNS (vigtigt!)

Begrænsning af udgående trafik være særlig opmærksom på DNS - Kubernetes bruger denne service til at kortlægge tjenester til IP-adresser. For eksempel vil følgende politik ikke fungere, fordi du ikke har tilladt applikationen balance få adgang til 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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Du kan rette det ved at åbne adgang til DNS-tjenesten:

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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Sidste element to er tom, og så vælger den indirekte alle pods i alle navneområder, tillader balance send DNS-forespørgsler til den relevante Kubernetes-tjeneste (normalt kører den i rummet kube-system).

Denne tilgang virker dog alt for eftergivende og usikker, fordi det giver dig mulighed for at dirigere DNS-forespørgsler uden for klyngen.

Du kan forbedre det i tre på hinanden følgende trin.

1. Tillad kun DNS-forespørgsler inden klynge ved at tilføje 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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

2. Tillad kun DNS-forespørgsler i navneområdet kube-system.

For at gøre dette skal du tilføje en etiket til navneområdet kube-system: kubectl label namespace kube-system namespace=kube-system - og registrere det i politikken vha 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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

3. Paranoider kan gå endnu længere og begrænse DNS-anmodninger til en specifik DNS-tjeneste i kube-system. Afsnittet "Filtrer efter navnerum OG Pods" viser dig, hvordan du opnår dette.

En anden mulighed er at løse DNS på navnerumsniveau. I dette tilfælde behøver det ikke at blive åbnet for hver tjeneste:

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

Tom podSelector vælger alle pods i navneområdet.

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Første match og regelrækkefølge

I konventionelle firewalls bestemmes handlingen (Allow or Deny) på en pakke af den første regel, den opfylder. I Kubernetes er rækkefølgen af ​​politikker ligegyldig.

Som standard, når der ikke er angivet nogen politikker, er kommunikation mellem pods tilladt, og de kan frit udveksle oplysninger. Så snart du begynder at formulere politikker, bliver hver pod, der er påvirket af mindst én af dem, isoleret i henhold til adskillelsen (logisk ELLER) af alle de politikker, der har valgt den. Pods, der ikke er påvirket af nogen politik, forbliver åbne.

Du kan ændre denne adfærd med en sweep-regel.

Oprydningsregel ("Forbyd")

Firewallpolitikker afviser normalt enhver trafik, der ikke udtrykkeligt er tilladt.

Kubernetes har ikke en "afvis"-handling, men den samme effekt kan opnås med en normal (tilladende) politik ved at vælge en tom gruppe af kildepods (indgang):

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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Denne politik vælger alle pods i navneområdet og efterlader indgang udefineret, hvilket afviser al indgående trafik.

På samme måde kan du begrænse al udgående trafik fra navneområdet:

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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Bemærk venligst eventuelle yderligere politikker, der tillader trafik til pods i navneområdet, har forrang over denne regel (svarende til at tilføje en tillad-regel før en afvisningsregel i firewall-konfigurationen).

Tillad alle (Any-Any-Any-Allow)

For at oprette en "Tillad alle"-politik skal du supplere ovenstående afvisningspolitik med et tomt element ingress:

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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Det giver adgang til alle pods i alle navneområder (og alle IP'er) til enhver pod i navneområdet default. Denne adfærd er aktiveret som standard, så den behøver normalt ikke at blive defineret yderligere. Nogle gange kan det dog være nødvendigt midlertidigt at deaktivere visse specifikke tilladelser for at diagnosticere problemet.

Reglen kan indsnævres til kun at tillade adgang til et bestemt sæt bælg (app:balance) i navnerummet default:

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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Følgende politik tillader al indgående (indgående) OG udgående (udgående) trafik, inklusive adgang til enhver IP uden for klyngen:

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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle
En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Kombination af flere politikker

Politikker er logisk opdelt på tre niveauer; Hver pods tilladelser er indstillet i henhold til adskillelsen af ​​alle de politikker, der påvirker den:

1. I felterne from и to tre typer elementer kan defineres (alle kombineret med OR):

  • namespaceSelector - vælger hele navneområdet;
  • podSelector - vælger bælg;
  • ipBlock - vælger et undernet.

Samtidig er antallet af elementer (selv de samme) i underafsnit from/to ikke begrænset. Alle vil blive kombineret med en logisk 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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

2. Inside politik afsnit ingress kan have mange elementer from (kombineret med logisk ELLER). Tilsvarende afsnit egress kan indeholde mange elementer to (også kombineret med disjunktion):

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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

3. Forskellige politikker kombineres også med en logisk OR

Men når de kombineres, er der én begrænsning for hvilken påpegede Chris Cooney: Kubernetes kan kun kombinere politikker med forskellige policyTypes (Ingress eller Egress). Politikker, der definerer indgang (eller udgang), vil overskrive hinanden.

Relation mellem navnerum

Som standard er udveksling af information mellem navneområder tilladt. Dette kan ændres med en restriktiv politik, der begrænser udgående og/eller indgående trafik til navneområdet (se "Sweep-regel" ovenfor).

Ved at blokere adgangen til et navneområde (se "Sweep Rule" ovenfor), kan du gøre undtagelser fra afvisningspolitikken ved at tillade forbindelser fra et specifikt navneområde med 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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Som et resultat, alle pods i navneområdet default få adgang til pods postgres i navnerummet database. Men hvad nu hvis du vil åbne adgang til postgres kun specifikke pods i navnerummet default?

Filtrer efter navnerum OG pods

Kubernetes version 1.11 og nyere giver dig mulighed for at kombinere operatører namespaceSelector и podSelector bruger logisk OG. Det ser sådan ud:

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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Hvorfor tolkes det som OG i stedet for det sædvanlige ELLER?

Bemærk, at podSelector starter ikke med en bindestreg. I YAML betyder det det podSelector og står foran ham namespaceSelector henvise til det samme listeelement. Derfor er de kombineret med et logisk OG.

Tilføjelse af en tankestreg før podSelector vil resultere i et nyt listeelement, der vil blive kombineret med det forrige namespaceSelector ved hjælp af logisk ELLER.

For at vælge pods med en bestemt etiket i alle navneområder, indtast tom 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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Flere etiketter kombineres med OG

Firewall-regler med flere enheder (værter, netværk, grupper) kombineres ved hjælp af en logisk OR. Følgende regel udløses, hvis pakkekilden matcher Host_1 OR Host_2:

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

Tværtimod, i Kubernetes forskellige etiketter i podSelector eller namespaceSelector kombineres med et logisk OG. For eksempel vil følgende regel vælge pods, der har begge etiketter, role=db И version=v2:

podSelector:
  matchLabels:
    role: db
    version: v2

Den samme logik gælder for alle typer udsagn: politikmålvælgere, podvælgere og navneområdevælgere.

Undernet og IP-adresser (IPBlocks)

Firewalls bruger VLAN'er, IP-adresser og undernet til at segmentere et netværk.

I Kubernetes tildeles IP-adresser automatisk til pods og kan ændres ofte, så etiketter bruges til at vælge pods og navneområder i netværkspolitikker.

Undernet (ipBlocks) bruges til håndtering af indgående (indgående) eller udgående (udgående) eksterne (nord-syd) forbindelser. For eksempel åbner denne politik alle pods fra navneområdet default adgang til Google DNS-tjeneste:

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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Den tomme pod-vælger i dette eksempel betyder "vælg alle pods i navneområdet".

Denne politik tillader kun adgang til 8.8.8.8; adgang til enhver anden IP er forbudt. Så i det væsentlige har du blokeret adgangen til den interne Kubernetes DNS-tjeneste. Hvis du stadig vil åbne det, skal du angive det eksplicit.

Normalt ipBlocks и podSelectors udelukker hinanden, da de interne IP-adresser på pod'erne ikke bruges i ipBlocks. Påpege interne IP-pods, vil du faktisk tillade forbindelser til/fra pods med disse adresser. I praksis vil du ikke vide, hvilken IP-adresse du skal bruge, hvorfor du ikke bør bruge dem til at vælge pods.

Som et modeksempel inkluderer følgende politik alle IP'er og giver derfor adgang til alle andre pods:

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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Du kan kun åbne adgang til eksterne IP'er, undtagen pod'ernes interne IP-adresser. For eksempel, hvis din pods undernet er 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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Havne og protokoller

Normalt lytter pods på én port. Det betyder, at du blot kan udelade portnumrene i dine politikker og lade alt stå som standard. Det anbefales dog at gøre politikker så restriktive som muligt, så i nogle tilfælde kan du stadig angive porte:

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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Bemærk, at vælgeren ports gælder for alle elementer i blokken to eller from, som indeholder. For at angive forskellige porte for forskellige varesæt, skal du bryde ingress eller egress i flere underafsnit to eller from og i hver skriv dine porte ned:

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

En introduktion til Kubernetes netværkspolitikker for sikkerhedsprofessionelle

Standard porte virker:

  • Hvis du helt udelader definitionen af ​​porte (ports), hvilket betyder alle protokoller og alle porte;
  • Hvis du udelader protokoldefinitionen (protocol), hvilket betyder TCP;
  • Hvis du udelader portdefinitionen (port), hvilket betyder alle porte.

Bedste praksis: Stol ikke på standardværdier, angiv eksplicit, hvad du har brug for.

Bemærk, at du skal bruge pod-porte, ikke tjenester (mere om dette i næste afsnit).

Politikker defineret for pods eller tjenester?

Normalt kommunikerer pods i Kubernetes med hinanden gennem en tjeneste – en virtuel load balancer, der omdirigerer trafik til de pods, der implementerer tjenesten. Du tror måske, at netværkspolitikker styrer adgangen til tjenester, men det er ikke tilfældet. Kubernetes netværkspolitikker fungerer med pod-porte, ikke tjenester.

For eksempel, hvis en tjeneste lytter på port 80, men omdirigerer trafik til port 8080 af dens pods, skal du angive 8080 i netværkspolitikken.

En sådan mekanisme bør anerkendes som suboptimal: Hvis tjenestens interne enhed (hvis portene lytter til pods) ændres, skal netværkspolitikker opdateres.

Ny arkitektonisk tilgang ved hjælp af Service Mesh (se f.eks. om Istio nedenfor - ca. oversættelse) giver dig mulighed for at håndtere dette problem.

Er det nødvendigt at skrive både Ingress og Egress?

Det korte svar er ja, for at pod A kan kommunikere med pod B, skal du give den mulighed for at oprette en udgående forbindelse (for dette skal du konfigurere udgående politik), og pod B skal kunne acceptere en indgående forbindelse (til dette har du derfor brug for indgangspolitik).

I praksis kan du dog stole på, at standardpolitikken tillader forbindelser i en eller begge retninger.

Hvis nogle pod-kilde vil blive valgt af en eller flere egress-politikere, de begrænsninger, der pålægges det, vil blive bestemt af deres disjunktion. I dette tilfælde skal du udtrykkeligt tillade forbindelsen til podenadressat. Hvis en pod ikke er valgt af nogen politik, er dens udgående (udgående) trafik tilladt som standard.

På samme måde, skæbnen for pod'a-adressatvalgt af en eller flere indtrængen-politikker vil blive bestemt af deres adskillelse. I dette tilfælde skal du udtrykkeligt tillade, at den modtager trafik fra kildepoden. Hvis en pod ikke er valgt af nogen politik, er al indgående trafik til den som standard tilladt.

Se "Statsfuld eller statsløs" nedenfor.

Logs

Kubernetes netværkspolitikker ved ikke, hvordan man logger trafik. Dette gør det svært at afgøre, om en politik fungerer som forventet, og gør sikkerhedsanalyse meget vanskelig.

Trafikkontrol til eksterne tjenester

Kubernetes netværkspolitikker tillader ikke, at du angiver et fuldt kvalificeret domænenavn (DNS) i udgående sektioner. Denne kendsgerning fører til en betydelig ulempe, når man forsøger at begrænse trafik til eksterne destinationer, der ikke har en fast IP-adresse (såsom aws.com).

Politikcheck

Firewalls vil advare dig eller endda nægte at acceptere en fejlagtig politik. Kubernetes udfører også en vis kontrol. Når du sætter en netværkspolitik via kubectl, kan Kubernetes erklære, at politikken er forkert og nægte at acceptere den. I andre tilfælde vil Kubernetes tage politikken og udfylde den med de manglende detaljer. Du kan se dem med kommandoen:

kubernetes get networkpolicy <policy-name> -o yaml

Husk, at Kubernetes-valideringssystemet ikke er ufejlbarligt og kan gå glip af nogle typer fejl.

Udførelse

Kubernetes håndhæver ikke netværkspolitikker alene, men er blot en API-gateway, der placerer kontrolbyrden på et underliggende system kaldet Container Networking Interface (CNI). At indstille politikker på en Kubernetes-klynge uden at tildele en passende CNI svarer til at indstille politikker på en firewall-administrationsserver uden efterfølgende at indstille dem på firewalls. Det er op til dig at sikre dig, at du har en anstændig CNI eller, i tilfælde af Kubernetes-platforme, hostet i skyen (Se en liste over udbydere her - ca. oversættelse), aktiver netværkspolitikker, der indstiller CNI for dig.

Bemærk, at Kubernetes ikke vil advare dig, hvis du indstiller en netværkspolitik uden den relevante hjælpe-CNI.

Statsfuld eller statsløs?

Alle Kubernetes CNI'er, jeg er stødt på, er stateful (f.eks. bruger Calico Linux conntrack). Dette gør det muligt for poden at modtage svar på den TCP-forbindelse, den startede, uden at skulle genetablere den. Jeg er dog ikke bekendt med en Kubernetes-standard, der ville garantere statefulness.

Avanceret sikkerhedspolitikstyring

Her er nogle måder at forbedre effektiviteten af ​​håndhævelsen af ​​sikkerhedspolitik i Kubernetes:

  1. Service Mesh arkitektoniske mønster bruger sidevogne til at levere detaljeret telemetri og trafikkontrol på serviceniveau. Som eksempel kan man tage Samme.
  2. Nogle af CNI-leverandørerne har udvidet deres værktøjer til at gå ud over Kubernetes netværkspolitikker.
  3. Tufin spækhugger giver gennemsigtighed og automatisering af Kubernetes netværkspolitikker.

Tufin Orca-pakken administrerer Kubernetes netværkspolitikker (og er kilden til skærmbillederne ovenfor).

yderligere oplysninger

Konklusion

Kubernetes netværkspolitikker tilbyder et godt sæt værktøjer til at segmentere klynger, men de er ikke intuitive og har mange finesser. Jeg mener, at på grund af denne kompleksitet er politikkerne for mange eksisterende klynger uklare. Mulige løsninger på dette problem er at automatisere politikdefinitioner eller bruge andre segmenteringsværktøjer.

Jeg håber, at denne vejledning vil hjælpe med at afklare nogle spørgsmål og løse problemer, du måtte støde på.

PS fra oversætteren

Læs også på vores blog:

Kilde: www.habr.com

Tilføj en kommentar