En introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

En introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Merk. overs.: Forfatteren av artikkelen, Reuven Harrison, har over 20 års erfaring innen programvareutvikling, og er i dag CTO og medgründer av Tufin, et selskap som lager løsninger for styring av sikkerhetspolitikk. Mens han ser på Kubernetes nettverkspolicyer som et ganske kraftig verktøy for nettverkssegmentering i en klynge, mener han også at de ikke er så enkle å implementere i praksis. Dette materialet (ganske omfangsrikt) er ment å forbedre spesialistenes bevissthet om dette problemet og hjelpe dem med å lage de nødvendige konfigurasjonene.

I dag velger mange selskaper i økende grad Kubernetes for å kjøre applikasjonene sine. Interessen for denne programvaren er så stor at noen kaller Kubernetes «det nye operativsystemet for datasenteret». Gradvis begynner Kubernetes (eller k8s) å bli oppfattet som en kritisk del av virksomheten, noe som krever organisering av modne forretningsprosesser, inkludert nettverkssikkerhet.

For sikkerhetseksperter som er forvirret over å jobbe med Kubernetes, kan den virkelige avsløringen være plattformens standardpolicy: tillat alt.

Denne veiledningen vil hjelpe deg å forstå den interne strukturen til nettverkspolicyer; forstå hvordan de skiller seg fra reglene for vanlige brannmurer. Den vil også dekke noen fallgruver og gi anbefalinger for å sikre applikasjoner på Kubernetes.

Kubernetes nettverkspolicyer

Kubernetes-nettverkspolicymekanismen lar deg administrere samspillet mellom applikasjoner som er distribuert på plattformen på nettverkslaget (det tredje i OSI-modellen). Nettverkspolicyer mangler noen av de avanserte funksjonene til moderne brannmurer, som OSI Layer 7-håndhevelse og trusseldeteksjon, men de gir et grunnleggende nivå av nettverkssikkerhet som er et godt utgangspunkt.

Nettverkspolicyer kontrollerer kommunikasjon mellom pods

Arbeidsbelastninger i Kubernetes er fordelt på tvers av pods, som består av én eller flere containere som er distribuert sammen. Kubernetes tildeler hver pod en IP-adresse som er tilgjengelig fra andre pods. Kubernetes nettverkspolicyer angir tilgangsrettigheter for grupper av pods på samme måte som sikkerhetsgrupper i skyen brukes til å kontrollere tilgang til virtuelle maskinforekomster.

Definere nettverkspolicyer

Som andre Kubernetes-ressurser er nettverkspolicyer spesifisert i YAML. I eksemplet nedenfor, applikasjonen balance tilgang 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 introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

(Merk. overs.: dette skjermbildet, som alle påfølgende lignende, ble ikke laget ved å bruke innfødte Kubernetes-verktøy, men ved å bruke Tufin Orca-verktøyet, som ble utviklet av selskapet til forfatteren av den originale artikkelen og som er nevnt på slutten av materialet.)

For å definere din egen nettverkspolicy, trenger du grunnleggende kunnskap om YAML. Dette språket er basert på innrykk (spesifisert med mellomrom i stedet for tabulatorer). Et innrykket element tilhører det nærmeste innrykkede elementet over det. Et nytt listeelement begynner med en bindestrek, alle andre elementer har formen nøkkelverdi.

Etter å ha beskrevet retningslinjene i YAML, bruk kubectlfor å lage den i klyngen:

kubectl create -f policy.yaml

Nettverkspolicyspesifikasjon

Kubernetes-nettverkspolicyspesifikasjonen inkluderer fire elementer:

  1. podSelector: definerer pods som er berørt av denne policyen (mål) - obligatorisk;
  2. policyTypes: indikerer hvilke typer retningslinjer som er inkludert i dette: inn- og/eller utgang - valgfritt, men jeg anbefaler at du spesifiserer det eksplisitt i alle tilfeller;
  3. ingress: definerer tillatt innkommende trafikk til målkapsler – valgfritt;
  4. egress: definerer tillatt utgående trafikk fra målpods er valgfritt.

Eksempel hentet fra Kubernetes-nettstedet (jeg erstattet roleapp), viser hvordan alle fire elementene brukes:

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 introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter
En introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Vær oppmerksom på at alle fire elementene ikke trenger å være inkludert. Det er bare obligatorisk podSelector, kan andre parametere brukes etter ønske.

Hvis du utelater policyTypes, vil policyen bli tolket som følger:

  • Som standard antas det at den definerer inngangssiden. Dersom policyen ikke uttrykkelig sier dette, vil systemet anta at all trafikk er forbudt.
  • Oppførselen på utgangssiden vil bli bestemt av tilstedeværelsen eller fraværet av den tilsvarende utgangsparameteren.

For å unngå feil anbefaler jeg alltid gjøre det eksplisitt policyTypes.

I henhold til logikken ovenfor, hvis parametrene ingress og / eller egress utelatt, vil policyen nekte all trafikk (se "Stripningsregel" nedenfor).

Standard policy er Tillat

Hvis ingen policyer er definert, tillater Kubernetes all trafikk som standard. Alle poder kan fritt utveksle informasjon seg imellom. Dette kan virke motintuitivt fra et sikkerhetsperspektiv, men husk at Kubernetes opprinnelig ble designet av utviklere for å muliggjøre applikasjonsinteroperabilitet. Nettverkspolicyer ble lagt til senere.

Navneområder

Navneområder er Kubernetes samarbeidsmekanisme. De er designet for å isolere logiske miljøer fra hverandre, mens kommunikasjon mellom rom er tillatt som standard.

Som de fleste Kubernetes-komponenter, lever nettverkspolicyer i et bestemt navneområde. I blokken metadata du kan spesifisere hvilket område policyen tilhører:

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

Hvis navneområdet ikke er eksplisitt spesifisert i metadataene, vil systemet bruke navneområdet spesifisert i kubectl (som standard namespace=default):

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

jeg anbefaler spesifiser navneområdet eksplisitt, med mindre du skriver en policy som målretter mot flere navneområder samtidig.

Primære element podSelector i policyen vil du velge pods fra navneområdet som policyen tilhører (den nektes tilgang til pods fra et annet navneområde).

Tilsvarende podSelectors i inn- og utgangsblokker kan bare velge poder fra sitt eget navneområde, med mindre du selvfølgelig kombinerer dem med namespaceSelector (dette vil bli diskutert i avsnittet "Filtrer etter navnerom og pods").

Regler for navn på retningslinjer

Policynavn er unike innenfor samme navneområde. Det kan ikke være to policyer med samme navn på samme plass, men det kan være policyer med samme navn på forskjellige områder. Dette er nyttig når du vil bruke den samme policyen på nytt på flere områder.

Jeg liker spesielt godt en av navnemetodene. Den består av å kombinere navneromsnavnet med målpodene. 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 introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Etiketter

Du kan feste egendefinerte etiketter til Kubernetes-objekter, for eksempel pods og navneområder. Etiketter (etiketter - tags) tilsvarer tagger i skyen. Kubernetes nettverkspolicyer bruker etiketter for å velge belgersom de gjelder for:

podSelector:
  matchLabels:
    role: db

… eller navneområdersom de gjelder for. Dette eksemplet velger alle pods i navneområder med de tilsvarende etikettene:

namespaceSelector:
  matchLabels:
    project: myproject

En forsiktighet: ved bruk namespaceSelector sørg for at navneområdene du velger inneholder riktig etikett. Vær oppmerksom på at innebygde navnerom som f.eks default и kube-system, inneholder som standard ikke etiketter.

Du kan legge til en etikett på et mellomrom som dette:

kubectl label namespace default namespace=default

Samtidig navneområde i seksjonen metadata skal referere til det faktiske plassnavnet, ikke etiketten:

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

Kilde og destinasjon

Brannmurpolicyer består av regler med kilder og destinasjoner. Kubernetes nettverkspolicyer er definert for et mål - et sett med pods som de gjelder for - og setter deretter regler for inngående og/eller utgående trafikk. I vårt eksempel vil målet for policyen være alle pods i navneområdet default med etikett med nøkkel 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 introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter
En introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Underseksjon ingress i denne policyen åpner innkommende trafikk til målgruppene. Med andre ord er ingress kilden og målet er den tilsvarende destinasjonen. På samme måte er utgang målet og målet er kilden.

En introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Dette tilsvarer to brannmurregler: Ingress → Target; Mål → Utgang.

Egress og DNS (viktig!)

Ved å begrense utgående trafikk, vær spesielt oppmerksom på DNS - Kubernetes bruker denne tjenesten til å kartlegge tjenester til IP-adresser. Følgende policy vil for eksempel ikke fungere fordi du ikke har tillatt applikasjonen balance tilgang 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 introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Du kan fikse det ved å åpne tilgang 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 introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Siste element to er tom, og derfor velger den indirekte alle pods i alle navneområder, tillater balance send DNS-spørringer til den aktuelle Kubernetes-tjenesten (kjører vanligvis i området kube-system).

Denne tilnærmingen fungerer uansett altfor ettergivende og usikker, fordi det lar DNS-spørringer sendes utenfor klyngen.

Du kan forbedre den i tre påfølgende trinn.

1. Tillat kun DNS-spørringer innenfor klynge ved å legge til 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 introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

2. Tillat kun DNS-spørringer innenfor navneområdet kube-system.

For å gjøre dette må du legge til en etikett i navneområdet kube-system: kubectl label namespace kube-system namespace=kube-system - og skriv det ned i policy ved hjelp av 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 introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

3. Paranoide mennesker kan gå enda lenger og begrense DNS-søk til en spesifikk DNS-tjeneste i kube-system. Avsnittet "Filtrer etter navnerom OG pods" vil fortelle deg hvordan du oppnår dette.

Et annet alternativ er å løse DNS på navneområdenivå. I dette tilfellet trenger den ikke å åpnes 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

Tømme podSelector velger alle pods i navneområdet.

En introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Første kamp og regelrekkefølge

I konvensjonelle brannmurer bestemmes handlingen (Tillat eller avslå) på en pakke av den første regelen den tilfredsstiller. I Kubernetes spiller ikke rekkefølgen på retningslinjene noen rolle.

Som standard, når ingen retningslinjer er angitt, er kommunikasjon mellom pods tillatt, og de kan fritt utveksle informasjon. Når du begynner å formulere policyer, blir hver pod påvirket av minst én av dem isolert i henhold til disjunksjonen (logisk ELLER) av alle policyene som valgte den. Pods som ikke er berørt av noen retningslinjer forblir åpne.

Du kan endre denne virkemåten ved å bruke en stripperegel.

Strippingsregel («Nekt»)

Brannmurpolicyer nekter vanligvis all trafikk som ikke er eksplisitt tillatt.

Det er ingen nektet handling i Kubernetes, imidlertid kan en lignende effekt oppnås med en vanlig (tillatende) policy ved å velge en tom gruppe med kildepoder (inngang):

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

En introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Denne policyen velger alle pods i navneområdet og lar ingress være udefinert, og nekter all innkommende trafikk.

På lignende måte kan du begrense all utgående trafikk fra et navneområde:

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

En introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Vær oppmerksom på at eventuelle ytterligere retningslinjer som tillater trafikk til pods i navneområdet, vil ha forrang over denne regelen (ligner på å legge til en tillat-regel før en avvisningsregel i en brannmurkonfigurasjon).

Tillat alt (Any-Any-Any-Allow)

For å opprette en Allow All-policy, må du supplere Nekt-policyen ovenfor med et tomt element ingress:

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

En introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Den gir tilgang fra alle poder i alle navneområder (og all IP) til en hvilken som helst pod i navneområdet default. Denne virkemåten er aktivert som standard, så den trenger vanligvis ikke å defineres nærmere. Noen ganger kan det imidlertid hende du må deaktivere noen spesifikke tillatelser midlertidig for å diagnostisere problemet.

Regelen kan begrenses for kun å tillate tilgang til et spesifikt sett med pods (app:balance) i navneområdet 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 introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Følgende policy tillater all inngående og utgående trafikk, inkludert tilgang til enhver IP utenfor klyngen:

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

En introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter
En introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Kombinere flere retningslinjer

Retningslinjer kombineres ved å bruke logisk ELLER på tre nivåer; Hver pods tillatelser er satt i samsvar med disjunksjonen av alle retningslinjer som påvirker den:

1. I feltene from и to Tre typer elementer kan defineres (som alle er kombinert med OR):

  • namespaceSelector — velger hele navneområdet;
  • podSelector — velger pods;
  • ipBlock — velger et undernett.

Dessuten, antall elementer (selv identiske) i underseksjoner from/to Ikke begrenset. Alle vil bli kombinert med logisk ELLER.

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 introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

2. Inne i policydelen ingress kan ha mange elementer from (kombinert med logisk ELLER). Tilsvarende seksjon egress kan inneholde mange elementer to (også kombinert med disjunksjon):

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 introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

3. Ulike policyer kombineres også med logisk OR

Men når du kombinerer dem, er det en begrensning på hvilken påpekte Chris Cooney: Kubernetes kan bare kombinere policyer med forskjellige policyTypes (Ingress eller Egress). Retningslinjer som definerer ingress (eller egress) vil overskrive hverandre.

Forholdet mellom navnerom

Som standard er informasjonsdeling mellom navneområder tillatt. Dette kan endres ved å bruke en avvisningspolicy som vil begrense utgående og/eller innkommende trafikk til navneområdet (se "Stripningsregel" ovenfor).

Når du har blokkert tilgangen til et navneområde (se "strippingsregelen" ovenfor), kan du gjøre unntak fra avvisningspolicyen ved å tillate tilkoblinger fra et spesifikt navneområde ved å bruke 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 introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Som et resultat, alle pods i navneområdet default vil ha tilgang til pods postgres i navneområdet database. Men hva om du vil åpne tilgang til postgres bare spesifikke pods i navneområdet default?

Filtrer etter navneområder og pods

Kubernetes versjon 1.11 og høyere lar deg kombinere operatører namespaceSelector и podSelector bruker logisk OG. Det ser slik ut:

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 introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Hvorfor tolkes dette som OG i stedet for det vanlige ELLER?

Vær oppmerksom på det podSelector starter ikke med bindestrek. I YAML betyr dette det podSelector og står foran ham namespaceSelector referer til samme listeelement. Derfor er de kombinert med logisk OG.

Legger til en bindestrek før podSelector vil resultere i fremveksten av et nytt listeelement, som vil bli kombinert med det forrige namespaceSelector ved å bruke logisk ELLER.

For å velge pods med en bestemt etikett i alle navneområder, skriv inn blank 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 introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Flere etiketter slår seg sammen med I

Regler for en brannmur med flere objekter (verter, nettverk, grupper) kombineres med logisk ELLER. Følgende regel vil fungere hvis pakkekilden samsvarer Host_1 ELLER Host_2:

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

Tvert imot, i Kubernetes de forskjellige etikettene i podSelector eller namespaceSelector er kombinert med logisk OG. For eksempel vil følgende regel velge pods som har begge etikettene, role=db И version=v2:

podSelector:
  matchLabels:
    role: db
    version: v2

Den samme logikken gjelder for alle typer operatører: policymålvelgere, podvelgere og navneområdevelgere.

Subnett og IP-adresser (IPBlocks)

Brannmurer bruker VLAN, IP-adresser og subnett for å segmentere et nettverk.

I Kubernetes blir IP-adresser tilordnet pods automatisk og kan endres ofte, så etiketter brukes til å velge pods og navneområder i nettverkspolicyer.

Subnett (ipBlocks) brukes når du administrerer innkommende (inngående) eller utgående (utgående) eksterne (nord-sør) forbindelser. For eksempel åpnes denne policyen for alle pods fra navneområdet default tilgang 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 introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Den tomme pod-velgeren i dette eksemplet betyr "velg alle pods i navneområdet."

Denne policyen tillater kun tilgang til 8.8.8.8; tilgang til annen IP er forbudt. Så i hovedsak har du blokkert tilgang til den interne Kubernetes DNS-tjenesten. Hvis du fortsatt vil åpne den, angi dette eksplisitt.

Vanligvis ipBlocks и podSelectors er gjensidig utelukkende, siden de interne IP-adressene til pods ikke brukes i ipBlocks. Ved å indikere interne IP-poder, vil du faktisk tillate tilkoblinger til/fra pods med disse adressene. I praksis vil du ikke vite hvilken IP-adresse du skal bruke, og derfor bør de ikke brukes til å velge poder.

Som et moteksempel inkluderer følgende policy alle IP-er og gir derfor tilgang 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 introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Du kan bare åpne tilgang til eksterne IP-er, unntatt de interne IP-adressene til pods. For eksempel, hvis poden's subnett 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 introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Porter og protokoller

Vanligvis lytter pods til én port. Dette betyr at du rett og slett ikke kan spesifisere portnumre i policyer og la alt stå som standard. Det anbefales imidlertid å gjøre retningslinjer så restriktive som mulig, så i noen tilfeller kan du fortsatt spesifisere porter:

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 introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Merk at velgeren ports gjelder for alle elementer i blokken to eller from, som inneholder. For å spesifisere forskjellige porter for forskjellige sett med elementer, del ingress eller egress i flere underseksjoner med to eller from og i hvert register dine porter:

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 introduksjon til Kubernetes nettverkspolicyer for sikkerhetseksperter

Standard portoperasjon:

  • Hvis du utelater portdefinisjonen helt (ports), dette betyr alle protokoller og alle porter;
  • Hvis du utelater protokolldefinisjonen (protocol), betyr dette TCP;
  • Hvis du utelater portdefinisjonen (port), dette betyr alle porter.

Beste praksis: Ikke stol på standardverdier, spesifiser hva du trenger eksplisitt.

Vær oppmerksom på at du må bruke pod-porter, ikke serviceporter (mer om dette i neste avsnitt).

Er retningslinjer definert for pods eller tjenester?

Vanligvis har pods i Kubernetes tilgang til hverandre gjennom en tjeneste – en virtuell lastbalanser som omdirigerer trafikk til podene som implementerer tjenesten. Du tror kanskje at nettverkspolicyer styrer tilgangen til tjenester, men dette er ikke tilfelle. Kubernetes nettverkspolicyer fungerer på pod-porter, ikke serviceporter.

For eksempel, hvis en tjeneste lytter til port 80, men omdirigerer trafikk til port 8080 av podene, må du spesifisere nøyaktig 8080 i nettverkspolicyen.

En slik mekanisme bør betraktes som suboptimal: hvis den interne strukturen til tjenesten (portene som pods lytter til) endres, må nettverkspolicyer oppdateres.

Ny arkitektonisk tilnærming ved hjelp av Service Mesh (se for eksempel om Istio nedenfor - ca. overs.) lar deg takle dette problemet.

Er det nødvendig å registrere både Ingress og Egress?

Det korte svaret er ja, for at pod A skal kommunisere med pod B, må det være tillatt å opprette en utgående tilkobling (for dette må du konfigurere en utgående policy), og pod B må kunne akseptere en innkommende tilkobling ( for dette trenger du derfor en inntrengningspolicy).

I praksis kan du imidlertid stole på standardpolicyen for å tillate tilkoblinger i én eller begge retninger.

Hvis noen pod-kilde vil bli valgt av en eller flere egress-politikere, restriksjonene som pålegges det vil bli bestemt av deres disjunksjon. I dette tilfellet må du eksplisitt tillate tilkobling til poden -til adressaten. Hvis en pod ikke er valgt av noen policy, er dens utgående (utgående) trafikk tillatt som standard.

På samme måte er skjebnen til podenadressat, valgt av en eller flere ingress-politikere, vil bli bestemt av deres disjunksjon. I dette tilfellet må du eksplisitt tillate at den mottar trafikk fra kildepoden. Hvis en pod ikke er valgt av noen policy, tillates all inngående trafikk for den som standard.

Se Stateful eller Stateless nedenfor.

Tømmerstokker

Kubernetes nettverkspolicyer kan ikke logge trafikk. Dette gjør det vanskelig å avgjøre om en policy fungerer etter hensikten og kompliserer sikkerhetsanalysen i stor grad.

Kontroll av trafikk til eksterne tjenester

Kubernetes nettverkspolicyer tillater ikke at du spesifiserer et fullstendig kvalifisert domenenavn (DNS) i utgangsseksjoner. Dette faktum fører til betydelige ulemper når man prøver å begrense trafikk til eksterne destinasjoner som ikke har en fast IP-adresse (som aws.com).

Politikksjekk

Brannmurer vil advare deg eller til og med nekte å godta feil policy. Kubernetes gjør også en del verifisering. Når du setter en nettverkspolicy gjennom kubectl, kan Kubernetes erklære at den er feil og nekte å akseptere den. I andre tilfeller vil Kubernetes ta policyen og fylle den ut med de manglende detaljene. De kan sees ved hjelp av kommandoen:

kubernetes get networkpolicy <policy-name> -o yaml

Husk at Kubernetes-valideringssystemet ikke er ufeilbarlig og kan gå glipp av noen typer feil.

utførelse

Kubernetes implementerer ikke nettverkspolicyer selv, men er bare en API-gateway som delegerer kontrollbyrden til et underliggende system kalt Container Networking Interface (CNI). Å angi policyer på en Kubernetes-klynge uten å tilordne riktig CNI er det samme som å lage policyer på en brannmuradministrasjonsserver uten deretter å installere dem på brannmurer. Det er opp til deg å sikre at du har en anstendig CNI eller, i tilfelle av Kubernetes-plattformer, vert i skyen (du kan se listen over leverandører her — ca. overs.), aktiver nettverkspolicyer som vil angi CNI for deg.

Vær oppmerksom på at Kubernetes ikke vil advare deg hvis du angir en nettverkspolicy uten riktig hjelpe-CNI.

Statslig eller statsløs?

Alle Kubernetes CNI-er jeg har møtt er stateful (Calico bruker for eksempel Linux conntrack). Dette gjør at poden kan motta svar på TCP-tilkoblingen den startet uten å måtte reetablere den. Jeg er imidlertid ikke klar over en Kubernetes-standard som vil garantere statefulness.

Avansert administrasjon av sikkerhetspolitikk

Her er noen måter å forbedre håndhevelsen av sikkerhetspolitikk i Kubernetes:

  1. Service Mesh-arkitektoniske mønster bruker sidevognscontainere for å gi detaljert telemetri og trafikkkontroll på tjenestenivå. Som et eksempel kan vi ta Samme.
  2. Noen av CNI-leverandørene har utvidet verktøyene sine til å gå utover Kubernetes nettverkspolicyer.
  3. Tufin Orca Gir synlighet og automatisering av Kubernetes nettverkspolicyer.

Tufin Orca-pakken administrerer Kubernetes nettverkspolicyer (og er kilden til skjermbildene ovenfor).

mer informasjon

Konklusjon

Kubernetes nettverkspolicyer tilbyr et godt sett med verktøy for å segmentere klynger, men de er ikke intuitive og har mange finesser. På grunn av denne kompleksiteten tror jeg mange eksisterende klyngepolicyer er buggy. Mulige løsninger på dette problemet inkluderer automatisering av policydefinisjoner eller bruk av andre segmenteringsverktøy.

Jeg håper denne veiledningen hjelper deg med å oppklare noen spørsmål og løse problemer du kan støte på.

PS fra oversetter

Les også på bloggen vår:

Kilde: www.habr.com

Legg til en kommentar