En introduktion till Kubernetes nätverkspolicyer för säkerhetspersonal

En introduktion till Kubernetes nätverkspolicyer för säkerhetspersonal

Notera. transl.: Författaren till artikeln, Reuven Harrison, har över 20 års erfarenhet av mjukvaruutveckling, och är idag CTO och medgrundare av Tufin, ett företag som skapar lösningar för säkerhetspolicyhantering. Samtidigt som han ser Kubernetes nätverkspolicyer som ett ganska kraftfullt verktyg för nätverkssegmentering i ett kluster, menar han också att de inte är så lätta att implementera i praktiken. Detta material (ganska omfattande) är avsett att förbättra specialisternas medvetenhet om detta problem och hjälpa dem att skapa de nödvändiga konfigurationerna.

Idag är det många företag som i allt högre grad väljer Kubernetes för att köra sina applikationer. Intresset för denna programvara är så stort att vissa kallar Kubernetes "det nya operativsystemet för datacentret." Gradvis börjar Kubernetes (eller k8s) att uppfattas som en kritisk del av verksamheten, vilket kräver organisation av mogna affärsprocesser, inklusive nätverkssäkerhet.

För säkerhetspersonal som är förbryllad över att arbeta med Kubernetes kan den verkliga avslöjandet vara plattformens standardpolicy: tillåt allt.

Den här guiden hjälper dig att förstå den interna strukturen för nätverkspolicyer; förstå hur de skiljer sig från reglerna för vanliga brandväggar. Den kommer också att täcka några fallgropar och ge rekommendationer för att säkra applikationer på Kubernetes.

Kubernetes nätverkspolicyer

Kubernetes nätverkspolicymekanism låter dig hantera interaktionen mellan applikationer som distribueras på plattformen i nätverkslagret (det tredje i OSI-modellen). Nätverkspolicyer saknar några av de avancerade funktionerna i moderna brandväggar, såsom OSI Layer 7-tillämpning och hotdetektion, men de ger en grundläggande nivå av nätverkssäkerhet som är en bra utgångspunkt.

Nätverkspolicyer styr kommunikation mellan poddar

Arbetsbelastningar i Kubernetes är fördelade över pods, som består av en eller flera behållare som distribueras tillsammans. Kubernetes tilldelar varje pod en IP-adress som är tillgänglig från andra pods. Kubernetes nätverkspolicyer anger åtkomsträttigheter för grupper av pods på samma sätt som säkerhetsgrupper i molnet används för att kontrollera åtkomst till virtuella maskininstanser.

Definiera nätverkspolicyer

Precis som andra Kubernetes-resurser specificeras nätverkspolicyer i YAML. I exemplet nedan, applikationen balance tillgång till 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 till Kubernetes nätverkspolicyer för säkerhetspersonal

(Notera. transl.: den här skärmdumpen, liksom alla efterföljande liknande, skapades inte med inbyggda Kubernetes-verktyg, utan med verktyget Tufin Orca, som utvecklades av företaget till författaren till den ursprungliga artikeln och som nämns i slutet av materialet.)

För att definiera din egen nätverkspolicy behöver du grundläggande kunskaper om YAML. Det här språket är baserat på indrag (specificeras av blanksteg snarare än tabbar). Ett indraget element tillhör det närmaste indragna elementet ovanför det. Ett nytt listelement börjar med ett bindestreck, alla andra element har formen nyckelvärde.

Efter att ha beskrivit policyn i YAML, använd kubectlför att skapa det i klustret:

kubectl create -f policy.yaml

Nätverkspolicyspecifikation

Kubernetes nätverkspolicyspecifikation innehåller fyra element:

  1. podSelector: definierar de pods som påverkas av denna policy (mål) - krävs;
  2. policyTypes: indikerar vilka typer av policyer som ingår i detta: inträde och/eller utträde - valfritt, men jag rekommenderar att du uttryckligen specificerar det i alla fall;
  3. ingress: definierar tillåtna inkommande trafik till målpods - valfritt;
  4. egress: definierar tillåtna utgående trafik från målpods är valfritt.

Exempel taget från Kubernetes webbplats (jag ersatte roleapp), visar hur alla fyra elementen används:

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 till Kubernetes nätverkspolicyer för säkerhetspersonal
En introduktion till Kubernetes nätverkspolicyer för säkerhetspersonal

Observera att alla fyra delarna inte behöver inkluderas. Det är bara obligatoriskt podSelector, kan andra parametrar användas efter önskemål.

Om du utelämnar policyTypes, kommer policyn att tolkas enligt följande:

  • Som standard antas det att den definierar ingångssidan. Om policyn inte uttryckligen anger detta, kommer systemet att anta att all trafik är förbjuden.
  • Beteendet på utgångssidan kommer att bestämmas av närvaron eller frånvaron av motsvarande utgångsparameter.

För att undvika misstag rekommenderar jag gör det alltid tydligt policyTypes.

Enligt ovanstående logik, om parametrarna ingress och / eller egress utelämnas, kommer policyn att neka all trafik (se "Stripningsregel" nedan).

Standardpolicyn är Tillåt

Om inga policyer har definierats tillåter Kubernetes all trafik som standard. Alla poddar kan fritt utbyta information sinsemellan. Detta kan verka kontraintuitivt ur ett säkerhetsperspektiv, men kom ihåg att Kubernetes ursprungligen designades av utvecklare för att möjliggöra applikationskompatibilitet. Nätverkspolicyer lades till senare.

Namnutrymmen

Namnutrymmen är Kubernetes samarbetsmekanism. De är utformade för att isolera logiska miljöer från varandra, medan kommunikation mellan utrymmen är tillåten som standard.

Liksom de flesta Kubernetes-komponenter finns nätverkspolicyer i ett specifikt namnområde. I blocket metadata du kan ange vilket utrymme policyn tillhör:

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

Om namnutrymmet inte är explicit specificerat i metadatan kommer systemet att använda namnområdet som anges i kubectl (som standard namespace=default):

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

jag rekomenderar ange namnutrymme uttryckligen, såvida du inte skriver en policy som är inriktad på flera namnområden samtidigt.

Primär elementet podSelector i policyn kommer att välja poddar från namnområdet som policyn tillhör (den nekas åtkomst till pods från ett annat namnområde).

På samma sätt, podSelectors i in- och utgångsblock kan bara välja poddar från sitt eget namnområde, såvida du inte kombinerar dem med namespaceSelector (detta kommer att diskuteras i avsnittet "Filtrera efter namnutrymmen och poddar").

Regler för policynamn

Policynamn är unika inom samma namnområde. Det kan inte finnas två policyer med samma namn i samma utrymme, men det kan finnas policyer med samma namn i olika utrymmen. Detta är användbart när du vill använda samma policy igen på flera utrymmen.

Jag gillar särskilt en av namngivningsmetoderna. Det består av att kombinera namnområdets namn med målpodarna. Till exempel:

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 till Kubernetes nätverkspolicyer för säkerhetspersonal

Etiketter

Du kan bifoga anpassade etiketter till Kubernetes-objekt, till exempel poddar och namnområden. Etiketter (etiketter - taggar) är motsvarigheten till taggar i molnet. Kubernetes nätverkspolicyer använder etiketter för att välja baljorsom de gäller för:

podSelector:
  matchLabels:
    role: db

… eller namnrymdersom de gäller. Det här exemplet väljer alla poddar i namnutrymmen med motsvarande etiketter:

namespaceSelector:
  matchLabels:
    project: myproject

En försiktighet: vid användning namespaceSelector se till att namnrymden du väljer innehåller rätt etikett. Var medveten om att inbyggda namnrymder som t.ex default и kube-system, som standard inte innehåller etiketter.

Du kan lägga till en etikett till ett utrymme så här:

kubectl label namespace default namespace=default

Samtidigt namnutrymme i avsnittet metadata bör referera till det faktiska utrymmets namn, inte etiketten:

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

Källa och destination

Brandväggspolicyer består av regler med källor och destinationer. Kubernetes nätverkspolicyer definieras för ett mål - en uppsättning pods som de gäller för - och sätter sedan regler för inkommande och/eller utgående trafik. I vårt exempel kommer policyns mål att vara alla poddar i namnområdet default med etikett med nyckel app och 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 till Kubernetes nätverkspolicyer för säkerhetspersonal
En introduktion till Kubernetes nätverkspolicyer för säkerhetspersonal

Underavsnitt ingress i den här policyn öppnar inkommande trafik till målpodarna. Ingress är med andra ord källan och målet är motsvarande destination. På samma sätt är utgången destinationen och målet är dess källa.

En introduktion till Kubernetes nätverkspolicyer för säkerhetspersonal

Detta motsvarar två brandväggsregler: Ingress → Target; Mål → Utgång.

Egress och DNS (viktigt!)

Genom att begränsa utgående trafik, ägna särskild uppmärksamhet åt DNS - Kubernetes använder den här tjänsten för att mappa tjänster till IP-adresser. Till exempel kommer följande policy inte att fungera eftersom du inte har tillåtit applikationen balance åtkomst till 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 till Kubernetes nätverkspolicyer för säkerhetspersonal

Du kan fixa det genom att öppna åtkomst till DNS-tjänsten:

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 till Kubernetes nätverkspolicyer för säkerhetspersonal

Sista elementet to är tom, och därför väljer den indirekt alla poddar i alla namnutrymmen, tillåter balance skicka DNS-frågor till lämplig Kubernetes-tjänst (körs vanligtvis i utrymmet kube-system).

Detta tillvägagångssätt fungerar, hur det än är alltför tillåtande och osäker, eftersom det tillåter att DNS-frågor riktas utanför klustret.

Du kan förbättra det i tre på varandra följande steg.

1. Tillåt endast DNS-frågor inom kluster genom att lägga till 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 till Kubernetes nätverkspolicyer för säkerhetspersonal

2. Tillåt endast DNS-frågor inom namnområdet kube-system.

För att göra detta måste du lägga till en etikett i namnområdet kube-system: kubectl label namespace kube-system namespace=kube-system - och skriv ner det i policy med hjälp 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 introduktion till Kubernetes nätverkspolicyer för säkerhetspersonal

3. Paranoida människor kan gå ännu längre och begränsa DNS-förfrågningar till en specifik DNS-tjänst i kube-system. Avsnittet "Filtrera efter namnrymder OCH poddar" kommer att berätta hur du uppnår detta.

Ett annat alternativ är att lösa DNS på namnområdesnivå. I det här fallet behöver den inte öppnas för varje tjänst:

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ömma podSelector väljer alla poddar i namnområdet.

En introduktion till Kubernetes nätverkspolicyer för säkerhetspersonal

Första match och regelordning

I konventionella brandväggar bestäms åtgärden (tillåt eller neka) på ett paket av den första regeln som det uppfyller. I Kubernetes spelar ordningen på policyerna ingen roll.

Som standard, när inga policyer är inställda, tillåts kommunikation mellan poddar och de kan fritt utbyta information. När du väl börjar formulera policyer, blir varje pod som påverkas av minst en av dem isolerad enligt disjunktionen (logiskt ELLER) för alla policyer som valde den. Pods som inte påverkas av någon policy förblir öppna.

Du kan ändra detta beteende med hjälp av en strippningsregel.

Avlägsningsregel ("Neka")

Brandväggspolicyer nekar vanligtvis all trafik som inte är uttryckligen tillåten.

Det finns ingen förnekaråtgärd i Kubernetes, dock kan en liknande effekt uppnås med en vanlig (tillåtande) policy genom att välja en tom grupp av källpoddar (ingång):

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

En introduktion till Kubernetes nätverkspolicyer för säkerhetspersonal

Den här policyn väljer alla poddar i namnområdet och lämnar ingång odefinierad, vilket nekar all inkommande trafik.

På liknande sätt kan du begränsa all utgående trafik från ett namnområde:

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

En introduktion till Kubernetes nätverkspolicyer för säkerhetspersonal

Observera att alla ytterligare policyer som tillåter trafik till pods i namnområdet kommer att ha företräde framför denna regel (liknar att lägga till en tillåt-regel före en neka-regel i en brandväggskonfiguration).

Tillåt allt (Any-Any-Any-Allow)

För att skapa en Allow All-policy måste du komplettera Neka-policyn ovan med ett tomt element ingress:

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

En introduktion till Kubernetes nätverkspolicyer för säkerhetspersonal

Den tillåter åtkomst från alla poddar i alla namnutrymmen (och alla IP) till valfri pod i namnområdet default. Detta beteende är aktiverat som standard, så det behöver vanligtvis inte definieras ytterligare. Men ibland kan du behöva tillfälligt inaktivera vissa specifika behörigheter för att diagnostisera problemet.

Regeln kan begränsas för att endast tillåta åtkomst till en specifik uppsättning kapslar (app:balance) i namnutrymmet 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 till Kubernetes nätverkspolicyer för säkerhetspersonal

Följande policy tillåter all inkommande och utgående trafik, inklusive åtkomst till alla IP-adresser utanför klustret:

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

En introduktion till Kubernetes nätverkspolicyer för säkerhetspersonal
En introduktion till Kubernetes nätverkspolicyer för säkerhetspersonal

Kombinera flera policyer

Policyer kombineras med logiska ELLER på tre nivåer; Varje pods behörigheter ställs in i enlighet med uppdelningen av alla policyer som påverkar den:

1. I fälten from и to Tre typer av element kan definieras (som alla kombineras med ELLER):

  • namespaceSelector — väljer hela namnområdet;
  • podSelector — väljer baljor;
  • ipBlock — väljer ett undernät.

Dessutom, antalet element (även identiska) i underavsnitt from/to inte begränsad. Alla kommer att kombineras med logiska 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 introduktion till Kubernetes nätverkspolicyer för säkerhetspersonal

2. Inuti policysektionen ingress kan ha många element from (kombinerat med logiskt ELLER). Likaså avsnitt egress kan innehålla många element to (även kombinerat 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 till Kubernetes nätverkspolicyer för säkerhetspersonal

3. Olika policyer kombineras också med logiska ELLER

Men när man kombinerar dem finns det en begränsning för vilken påpekade Chris Cooney: Kubernetes kan bara kombinera policyer med olika policyTypes (Ingress eller Egress). Policyer som definierar ingång (eller utgående) kommer att skriva över varandra.

Relation mellan namnutrymmen

Som standard är informationsdelning mellan namnområden tillåten. Detta kan ändras genom att använda en neka-policy som begränsar utgående och/eller inkommande trafik till namnområdet (se "Strippningsregel" ovan).

När du har blockerat åtkomst till ett namnområde (se "Strippningsregeln" ovan) kan du göra undantag från den nekande policyn genom att tillåta anslutningar från ett specifikt namnområ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 till Kubernetes nätverkspolicyer för säkerhetspersonal

Som ett resultat, alla poddar i namnområdet default kommer att ha tillgång till poddar postgres i namnutrymmet database. Men vad händer om du vill öppna åtkomst till postgres endast specifika poddar i namnområdet default?

Filtrera efter namnrymder och poddar

Kubernetes version 1.11 och högre låter dig kombinera operatörer namespaceSelector и podSelector med logiskt AND. Det ser ut så här:

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 till Kubernetes nätverkspolicyer för säkerhetspersonal

Varför tolkas detta som OCH istället för det vanliga ELLER?

Observera att podSelector börjar inte med ett bindestreck. I YAML betyder detta det podSelector och står framför honom namespaceSelector hänvisa till samma listelement. Därför kombineras de med logiska OCH.

Lägger till ett bindestreck innan podSelector kommer att resultera i uppkomsten av ett nytt listelement, som kommer att kombineras med det föregående namespaceSelector med logiskt ELLER.

För att välja pods med en specifik etikett i alla namnutrymmen, ange tomt 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 till Kubernetes nätverkspolicyer för säkerhetspersonal

Flera etiketter samarbetar med I

Regler för en brandvägg med flera objekt (värdar, nätverk, grupper) kombineras med logiskt ELLER. Följande regel fungerar om paketkällan matchar Host_1 ELLER Host_2:

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

Tvärtom, i Kubernetes de olika etiketterna i podSelector eller namespaceSelector kombineras med logiska OCH. Till exempel kommer följande regel att välja pods som har båda etiketterna, role=db И version=v2:

podSelector:
  matchLabels:
    role: db
    version: v2

Samma logik gäller för alla typer av operatörer: policymålväljare, podväljare och namnområdesväljare.

Subnät och IP-adresser (IPBlocks)

Brandväggar använder VLAN, IP-adresser och subnät för att segmentera ett nätverk.

I Kubernetes tilldelas IP-adresser till pods automatiskt och kan ändras ofta, så etiketter används för att välja pods och namnområden i nätverkspolicyer.

Subnät (ipBlocks) används vid hantering av inkommande (inkommande) eller utgående (utgående) externa (nord-sydlig) anslutningar. Till exempel öppnas den här policyn för alla poddar från namnområdet default åtkomst till Googles DNS-tjänst:

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 till Kubernetes nätverkspolicyer för säkerhetspersonal

Den tomma podväljaren i det här exemplet betyder "välj alla pods i namnområdet."

Denna policy tillåter endast åtkomst till 8.8.8.8; åtkomst till någon annan IP är förbjuden. Så i huvudsak har du blockerat åtkomsten till den interna Kubernetes DNS-tjänsten. Om du fortfarande vill öppna den, ange detta uttryckligen.

Vanligtvis ipBlocks и podSelectors utesluter varandra, eftersom de interna IP-adresserna för pods inte används i ipBlocks. Genom att indikera interna IP-pods, kommer du faktiskt att tillåta anslutningar till/från pods med dessa adresser. I praktiken vet du inte vilken IP-adress du ska använda, varför de inte bör användas för att välja pods.

Som ett motexempel inkluderar följande policy alla IP:er och tillåter därför åtkomst till alla andra poddar:

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 till Kubernetes nätverkspolicyer för säkerhetspersonal

Du kan endast öppna åtkomst till externa IP-adresser, exklusive poddarnas interna IP-adresser. Till exempel, om din pods undernät är 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 till Kubernetes nätverkspolicyer för säkerhetspersonal

Portar och protokoll

Vanligtvis lyssnar pods på en port. Det betyder att du helt enkelt inte kan ange portnummer i policyer och lämna allt som standard. Det rekommenderas dock att göra policyer så restriktiva som möjligt, så i vissa fall kan du fortfarande ange portar:

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 till Kubernetes nätverkspolicyer för säkerhetspersonal

Observera att väljaren ports gäller alla element i blocket to eller from, vilket innehåller. För att ange olika portar för olika uppsättningar av element, dela ingress eller egress i flera underavdelningar med to eller from och i varje register dina portar:

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 till Kubernetes nätverkspolicyer för säkerhetspersonal

Standardportfunktion:

  • Om du utelämnar portdefinitionen helt (ports), detta betyder alla protokoll och alla portar;
  • Om du utelämnar protokolldefinitionen (protocol), detta betyder TCP;
  • Om du utelämnar portdefinitionen (port), detta betyder alla portar.

Bästa praxis: Lita inte på standardvärden, ange vad du behöver uttryckligen.

Observera att du måste använda pod-portar, inte serviceportar (mer om detta i nästa stycke).

Finns policyer definierade för pods eller tjänster?

Vanligtvis har pods i Kubernetes åtkomst till varandra via en tjänst - en virtuell lastbalanserare som omdirigerar trafik till podarna som implementerar tjänsten. Du kanske tror att nätverkspolicyer styr åtkomst till tjänster, men så är inte fallet. Kubernetes nätverkspolicyer fungerar på pod-portar, inte serviceportar.

Till exempel, om en tjänst lyssnar på port 80, men omdirigerar trafik till port 8080 av sina pods, måste du ange exakt 8080 i nätverkspolicyn.

En sådan mekanism bör anses vara suboptimal: om tjänstens interna struktur (portarna som poddarna lyssnar på) ändras, måste nätverkspolicyerna uppdateras.

Nytt arkitektoniskt tillvägagångssätt med Service Mesh (se till exempel om Istio nedan - ca översättning) låter dig hantera detta problem.

Är det nödvändigt att registrera både Ingress och Egress?

Det korta svaret är ja, för att pod A ska kunna kommunicera med pod B måste den vara tillåten att skapa en utgående anslutning (för detta måste du konfigurera en utgående policy), och pod B måste kunna acceptera en inkommande anslutning ( för detta behöver du följaktligen en ingresspolicy).

Men i praktiken kan du lita på standardpolicyn för att tillåta anslutningar i en eller båda riktningarna.

Om någon pod-källa kommer att väljas av en eller flera utträde-politiker, de restriktioner som åläggs det kommer att bestämmas av deras disjunktion. I det här fallet måste du uttryckligen tillåta anslutning till podden -till adressaten. Om en pod inte väljs av någon policy, tillåts dess utgående (utgående) trafik som standard.

På samma sätt är poddens ödeadressat, vald av en eller flera inträde-politiker, kommer att bestämmas av deras disjunktion. I det här fallet måste du uttryckligen tillåta att den tar emot trafik från källpodden. Om en pod inte väljs av någon policy, tillåts all inkommande trafik för den som standard.

Se Stateful eller Stateless nedan.

Loggar

Kubernetes nätverkspolicyer kan inte logga trafik. Detta gör det svårt att avgöra om en policy fungerar som avsett och komplicerar säkerhetsanalysen avsevärt.

Styrning av trafik till externa tjänster

Kubernetes nätverkspolicyer tillåter dig inte att ange ett fullständigt kvalificerat domännamn (DNS) i utgående sektioner. Detta faktum leder till betydande olägenheter när man försöker begränsa trafik till externa destinationer som inte har en fast IP-adress (som aws.com).

Policykontroll

Brandväggar kommer att varna dig eller till och med vägra acceptera fel policy. Kubernetes gör också viss verifiering. När du ställer in en nätverkspolicy genom kubectl kan Kubernetes förklara att den är felaktig och vägra acceptera den. I andra fall kommer Kubernetes att ta policyn och fylla i den med de uppgifter som saknas. De kan ses med kommandot:

kubernetes get networkpolicy <policy-name> -o yaml

Tänk på att Kubernetes valideringssystem inte är ofelbart och kan missa vissa typer av fel.

Utförande

Kubernetes implementerar inte nätverkspolicyer själv, utan är bara en API-gateway som delegerar bördan av kontroll till ett underliggande system som kallas Container Networking Interface (CNI). Att ställa in policyer på ett Kubernetes-kluster utan att tilldela lämplig CNI är detsamma som att skapa policyer på en brandväggshanteringsserver utan att sedan installera dem på brandväggar. Det är upp till dig att se till att du har en anständig CNI eller, i fallet med Kubernetes-plattformar, värd i molnet (du kan se listan över leverantörer här - cirka. trans.), aktivera nätverkspolicyer som ställer in CNI för dig.

Observera att Kubernetes inte kommer att varna dig om du ställer in en nätverkspolicy utan lämplig hjälp-CNI.

Statlig eller statslös?

Alla Kubernetes CNI:er jag har stött på är tillståndsbestämda (till exempel använder Calico Linux conntrack). Detta gör att podden kan ta emot svar på TCP-anslutningen den initierade utan att behöva återupprätta den. Jag är dock inte medveten om en Kubernetes-standard som skulle garantera status.

Avancerad säkerhetspolicyhantering

Här är några sätt att förbättra efterlevnaden av säkerhetspolicyn i Kubernetes:

  1. Det arkitektoniska mönstret för Service Mesh använder sidovagnscontainrar för att tillhandahålla detaljerad telemetri och trafikkontroll på servicenivå. Som exempel kan vi ta Samma.
  2. Några av CNI-leverantörerna har utökat sina verktyg till att gå längre än Kubernetes nätverkspolicyer.
  3. Tufin späckhuggare Ger synlighet och automatisering av Kubernetes nätverkspolicyer.

Tufin Orca-paketet hanterar Kubernetes nätverkspolicyer (och är källan till skärmdumparna ovan).

ytterligare information

Slutsats

Kubernetes nätverkspolicyer erbjuder en bra uppsättning verktyg för att segmentera kluster, men de är inte intuitiva och har många finesser. På grund av denna komplexitet tror jag att många befintliga klusterpolicyer är buggiga. Möjliga lösningar på detta problem inkluderar automatisering av policydefinitioner eller användning av andra segmenteringsverktyg.

Jag hoppas att den här guiden hjälper dig att reda ut några frågor och lösa problem du kan stöta på.

PS från översättaren

Läs även på vår blogg:

Källa: will.com

Lägg en kommentar