Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Huomautus. käännös: Artikkelin kirjoittajalla Reuven Harrisonilla on yli 20 vuoden kokemus ohjelmistokehityksestä, ja hän on nykyään tietoturvapolitiikan hallintaratkaisuja luovan Tufinin CTO ja toinen perustaja. Vaikka hän pitää Kubernetesin verkkopolitiikkaa varsin tehokkaana työkaluna verkon segmentointiin klusterissa, hän uskoo myös, että niitä ei ole niin helppo toteuttaa käytännössä. Tämän materiaalin (melko laaja) tarkoituksena on parantaa asiantuntijoiden tietoisuutta tästä ongelmasta ja auttaa heitä luomaan tarvittavat kokoonpanot.

Nykyään monet yritykset valitsevat yhä useammin Kubernetesin sovellusten suorittamiseen. Kiinnostus tätä ohjelmistoa kohtaan on niin suurta, että jotkut kutsuvat Kubernetesia "palvelinkeskuksen uudeksi käyttöjärjestelmäksi". Vähitellen Kubernetes (tai k8s) alkaa nähdä liiketoiminnan kriittisenä osana, mikä edellyttää kypsien liiketoimintaprosessien järjestämistä, mukaan lukien verkkoturvallisuus.

Tietoturva-ammattilaisille, jotka ovat ymmällään työskentelystä Kubernetesin kanssa, todellinen paljastus voi olla alustan oletuskäytäntö: salli kaikki.

Tämä opas auttaa sinua ymmärtämään verkkokäytäntöjen sisäisen rakenteen; ymmärtää, miten ne eroavat tavallisten palomuurien säännöistä. Se kattaa myös joitain sudenkuoppia ja antaa suosituksia sovellusten suojaamiseksi Kubernetesissa.

Kubernetes-verkkokäytännöt

Kubernetes-verkkokäytäntömekanismin avulla voit hallita alustalle asennettujen sovellusten vuorovaikutusta verkkokerroksessa (kolmas OSI-mallissa). Verkkokäytännöistä puuttuu joitain nykyaikaisten palomuurien edistyneitä ominaisuuksia, kuten OSI Layer 7 -valvonta ja uhkien havaitseminen, mutta ne tarjoavat verkon suojauksen perustason, joka on hyvä lähtökohta.

Verkkokäytännöt ohjaavat podien välistä viestintää

Kubernetesin työkuormat on jaettu ryhmiin, jotka koostuvat yhdestä tai useammasta yhdessä käyttöönotetusta säiliöstä. Kubernetes määrittää jokaiselle podille IP-osoitteen, joka on käytettävissä muista podeista. Kubernetes-verkkokäytännöt määrittävät pod-ryhmien käyttöoikeudet samalla tavalla kuin pilven suojausryhmiä käytetään hallitsemaan pääsyä virtuaalikoneen ilmentymiin.

Verkkokäytäntöjen määrittäminen

Kuten muutkin Kubernetes-resurssit, verkkokäytännöt määritetään YAML:ssä. Alla olevassa esimerkissä sovellus balance pääsy 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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

(Huomautus. käännös: tämä kuvakaappaus, kuten kaikki myöhemmät samanlaiset, ei luotu käyttämällä alkuperäisiä Kubernetes-työkaluja, vaan käyttämällä Tufin Orca -työkalua, jonka on kehittänyt alkuperäisen artikkelin kirjoittajan yritys ja joka mainitaan materiaalin lopussa.)

Jotta voit määrittää oman verkkokäytäntösi, tarvitset YAML:n perustiedot. Tämä kieli perustuu sisennykseen (määritetään välilyönnillä sarkaimien sijaan). Sisennetty elementti kuuluu lähimpään sen yläpuolella olevaan sisennettyyn elementtiin. Uusi luetteloelementti alkaa yhdysviivalla, kaikilla muilla elementeillä on muoto avainarvo.

Kun olet kuvannut käytännön YAML:ssä, käytä kubectlluodaksesi sen klusteriin:

kubectl create -f policy.yaml

Verkkokäytännön määrittely

Kubernetes-verkkokäytäntömääritys sisältää neljä elementtiä:

  1. podSelector: määrittää podit, joihin tämä käytäntö vaikuttaa (tavoitteet) - pakollinen;
  2. policyTypes: ilmaisee, minkä tyyppisiä käytäntöjä tämä sisältää: sisääntulo ja/tai ulostulo - valinnainen, mutta suosittelen, että määrität sen erikseen kaikissa tapauksissa;
  3. ingress: määrittelee sallitun saapuva liikenne kohdepaloihin – valinnainen;
  4. egress: määrittelee sallitun lähtevä kohdepodista tuleva liikenne on valinnaista.

Esimerkki otettu Kubernetes-verkkosivustolta (korvasin role päälle app), näyttää kuinka kaikkia neljää elementtiä käytetään:

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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille
Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Huomaa, että kaikkia neljää elementtiä ei tarvitse sisällyttää. Se on vain pakollinen podSelector, muita parametreja voidaan käyttää haluttaessa.

Jos jätät väliin policyTypes, käytäntöä tulkitaan seuraavasti:

  • Oletuksena oletetaan, että se määrittää sisääntulopuolen. Jos käytäntö ei nimenomaisesti kerro tätä, järjestelmä olettaa, että kaikki liikenne on kielletty.
  • Lähtöpuolen käyttäytyminen määräytyy vastaavan ulostuloparametrin läsnäolon tai puuttumisen perusteella.

Virheiden välttämiseksi suosittelen tee se aina selväksi policyTypes.

Yllä olevan logiikan mukaan, jos parametrit ingress ja / tai egress jätetään pois, käytäntö estää kaiken liikenteen (katso "Kuvaussääntö" alla).

Oletuskäytäntö on Salli

Jos käytäntöjä ei ole määritetty, Kubernetes sallii kaiken liikenteen oletuksena. Kaikki podit voivat vapaasti vaihtaa tietoja keskenään. Tämä saattaa tuntua tietoturvan kannalta ristiriitaiselta, mutta muista, että kehittäjät suunnittelivat Kubernetesin alun perin mahdollistamaan sovellusten yhteentoimivuuden. Verkkokäytännöt lisättiin myöhemmin.

Nimiavaruudet

Nimitilat ovat Kubernetes-yhteistyömekanismi. Ne on suunniteltu eristämään loogiset ympäristöt toisistaan, kun taas tilojen välinen viestintä on oletuksena sallittu.

Kuten useimmat Kubernetes-komponentit, verkkokäytännöt sijaitsevat tietyssä nimiavaruudessa. Korttelissa metadata voit määrittää mihin tilaan käytäntö kuuluu:

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

Jos nimiavaruutta ei ole erikseen määritelty metatiedoissa, järjestelmä käyttää kubectl:ssä määritettyä nimiavaruutta (oletuksena namespace=default):

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

Suosittelen määritä nimiavaruus eksplisiittisesti, ellet kirjoita käytäntöä, joka kohdistuu useaan nimiavaruuteen kerralla.

Ensisijainen elementti podSelector Käytännössä valitsee podit nimiavaruudesta, johon käytäntö kuuluu (siltä evätään pääsy toisen nimiavaruuden podeihin).

Samoin podSelectors sisään- ja ulostulolohkoissa voivat valita podeja vain omasta nimiavaruudestaan, ellet tietysti yhdistä niitä namespaceSelector (tätä käsitellään osiossa "Suodata nimiavaruuksien ja ryhmien mukaan").

Käytännön nimeämissäännöt

Käytäntöjen nimet ovat yksilöllisiä samassa nimiavaruudessa. Samassa tilassa ei voi olla kahta samannimistä käytäntöä, mutta eri tiloissa voi olla samannimistä käytäntöä. Tämä on hyödyllistä, kun haluat käyttää samaa käytäntöä useissa tiloissa.

Pidän erityisesti yhdestä nimeämismenetelmistä. Se koostuu nimitilan nimen yhdistämisestä kohderyhmiin. Esimerkiksi:

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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Tarrat

Voit liittää mukautettuja tunnisteita Kubernetes-objekteihin, kuten podeihin ja nimiavaruuksiin. Tarrat (tarrat - tagit) vastaavat pilvessä olevia tunnisteita. Kubernetes-verkkokäytännöt käyttävät valintaan tunnisteita palojajoihin ne koskevat:

podSelector:
  matchLabels:
    role: db

… tai nimitilatjoita ne koskevat. Tässä esimerkissä valitaan kaikki nimiavaruuksien podit vastaavilla tunnisteilla:

namespaceSelector:
  matchLabels:
    project: myproject

Yksi varoitus: käytettäessä namespaceSelector varmista, että valitsemasi nimitilat sisältävät oikean tunnisteen. Huomaa, että sisäänrakennetut nimitilat, kuten default и kube-system, eivät oletuksena sisällä tunnisteita.

Voit lisätä tunnisteen tilaan seuraavasti:

kubectl label namespace default namespace=default

Samanaikaisesti nimiavaruus osiossa metadata tulee viitata tilan todelliseen nimeen, ei tunnisteeseen:

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

Lähde ja kohde

Palomuurikäytännöt koostuvat säännöistä, joissa on lähteet ja kohteet. Kubernetes-verkkokäytännöt määritellään kohteelle - joukko poddeja, joita ne koskevat - ja sitten asetetaan säännöt sisään- ja/tai poistumisliikenteelle. Esimerkissämme käytännön kohteena ovat kaikki nimitilan tyypit default etiketillä ja avaimella app ja merkitys 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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille
Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

alajakso ingress tässä käytännössä avaa saapuvan liikenteen kohderyhmiin. Toisin sanoen sisääntulo on lähde ja kohde on vastaava kohde. Samoin lähtö on määränpää ja kohde on sen lähde.

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Tämä vastaa kahta palomuurisääntöä: Ingress → Target; Maali → Ulospääsy.

Lähtö ja DNS (tärkeää!)

Rajoittamalla lähtevää liikennettä, kiinnitä erityistä huomiota DNS:ään - Kubernetes käyttää tätä palvelua kartoittaakseen palvelut IP-osoitteisiin. Esimerkiksi seuraava käytäntö ei toimi, koska et ole sallinut sovellusta balance pääsy 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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Voit korjata sen avaamalla pääsyn DNS-palveluun:

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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Viimeinen elementti to on tyhjä, ja siksi se valitsee epäsuorasti kaikki podit kaikissa nimitiloissa, sallien balance lähettää DNS-kyselyitä asianmukaiseen Kubernetes-palveluun (yleensä käynnissä tilassa kube-system).

Tämä lähestymistapa toimii kuitenkin liian salliva ja epävarma, koska sen avulla DNS-kyselyt voidaan ohjata klusterin ulkopuolelle.

Voit parantaa sitä kolmessa peräkkäisessä vaiheessa.

1. Salli vain DNS-kyselyt sisällä klusteri lisäämällä 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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

2. Salli DNS-kyselyt vain nimiavaruudessa kube-system.

Tätä varten sinun on lisättävä nimiavaruuteen tunniste kube-system: kubectl label namespace kube-system namespace=kube-system - ja kirjoita se käytäntöön käyttämällä 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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

3. Vainoharhaiset ihmiset voivat mennä vielä pidemmälle ja rajoittaa DNS-kyselyt tiettyyn DNS-palveluun kube-system. Kohdassa "Suodata nimiavaruuksien JA ryhmien mukaan" kerrotaan, kuinka tämä saavutetaan.

Toinen vaihtoehto on ratkaista DNS nimiavaruuden tasolla. Tässä tapauksessa sitä ei tarvitse avata jokaiselle palvelulle:

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

Tyhjä podSelector valitsee kaikki nimiavaruuden podit.

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Ensimmäinen ottelu ja sääntöjärjestys

Perinteisissä palomuurissa paketin toiminto (Salli tai Estä) määräytyy ensimmäisen säännön mukaan, jonka se täyttää. Kubernetesissa käytäntöjen järjestyksellä ei ole väliä.

Oletusarvoisesti, kun käytäntöjä ei ole asetettu, podien välinen viestintä on sallittu ja ne voivat vaihtaa vapaasti tietoja. Kun aloitat käytäntöjen muotoilun, jokainen ryhmä, johon ainakin yksi niistä vaikuttaa, eristetään kaikkien sen valinneiden käytäntöjen disjunktion (looginen TAI) mukaan. Podit, joihin mikään käytäntö ei vaikuta, pysyvät auki.

Voit muuttaa tätä toimintaa poistamissäännöllä.

Poistamissääntö ("Estä")

Palomuurikäytännöt yleensä estävät kaiken liikenteen, jota ei ole erikseen sallittu.

Kubernetesin toimintaa ei voi kieltääSamanlainen vaikutus voidaan kuitenkin saavuttaa tavallisella (sallittavalla) käytännöllä valitsemalla tyhjä ryhmä lähderyhmiä (sisääntulo):

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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Tämä käytäntö valitsee kaikki nimiavaruuden ryhmät ja jättää sisääntulon määrittelemättömäksi, mikä estää kaiken saapuvan liikenteen.

Samalla tavalla voit rajoittaa kaiken lähtevän liikenteen nimiavaruudesta:

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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Huomaa, että kaikki lisäkäytännöt, jotka sallivat liikenteen nimiavaruudessa oleviin ryhmiin, ovat tämän säännön edelle (samanlainen kuin sallimissäännön lisääminen ennen kieltämissääntöä palomuurikokoonpanossa).

Salli kaikki (Any-Any-Any-Allow)

Jos haluat luoda Salli kaikki -käytännön, sinun on täydennettävä yllä olevaa Estä-käytäntöä tyhjällä elementillä ingress:

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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Se mahdollistaa pääsyn osoitteesta kaikki podit kaikissa nimiavaruuksissa (ja kaikki IP) mihin tahansa nimiavaruuden ryhmään default. Tämä toiminta on oletuksena käytössä, joten sitä ei yleensä tarvitse määritellä tarkemmin. Joskus saatat kuitenkin joutua poistamaan tilapäisesti käytöstä tietyt luvat ongelman diagnosoimiseksi.

Sääntöä voidaan kaventaa sallimaan pääsy vain tietty joukko paloja (app:balance) nimiavaruudessa default:

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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Seuraava käytäntö sallii kaiken sisään- ja ulosmenoliikenteen, mukaan lukien pääsyn mihin tahansa klusterin ulkopuoliseen IP-osoitteeseen:

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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille
Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Useiden käytäntöjen yhdistäminen

Käytännöt yhdistetään käyttämällä loogista TAI kolmella tasolla; Kunkin podin käyttöoikeudet määritetään kaikkien siihen vaikuttavien käytäntöjen eron mukaisesti:

1. Pelloilla from и to Kolmen tyyppisiä elementtejä voidaan määrittää (jotka kaikki yhdistetään TAI:lla):

  • namespaceSelector — valitsee koko nimitilan;
  • podSelector — valitsee palot;
  • ipBlock — valitsee aliverkon.

Lisäksi elementtien lukumäärä (jopa identtiset) alajaksoissa from/to ei rajoitettu. Ne kaikki yhdistetään loogisella TAI:lla.

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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

2. Käytäntöosion sisällä ingress voi sisältää monia elementtejä from (yhdistettynä loogiseen TAI:iin). Samoin jakso egress voi sisältää monia elementtejä to (myös yhdistetty disjunktiolla):

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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

3. Erilaiset käytännöt yhdistetään myös loogiseen TAI:iin

Mutta kun niitä yhdistetään, on yksi rajoitus huomautti Chris Cooney: Kubernetes voi yhdistää vain erilaisia ​​käytäntöjä policyTypes (Ingress tai Egress). Sisääntuloa (tai ulostuloa) määrittävät käytännöt korvaavat toisensa.

Nimiavaruuksien välinen suhde

Oletusarvoisesti tietojen jakaminen nimiavaruuksien välillä on sallittu. Tätä voidaan muuttaa käyttämällä estokäytäntöä, joka rajoittaa nimiavaruuteen lähtevää ja/tai saapuvaa liikennettä (katso yllä olevaa "Kuvaussääntö").

Kun olet estänyt pääsyn nimiavaruuteen (katso yllä olevaa "Kuvaussääntöä"), voit tehdä poikkeuksia estokäytäntöön sallimalla yhteydet tietystä nimiavaruudesta käyttämällä 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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Tämän seurauksena kaikki nimiavaruuden tyynyt default saa pääsyn paloihin postgres nimiavaruudessa database. Mutta entä jos haluat avata pääsyn postgres vain tietyt tyynyt nimiavaruudessa default?

Suodata nimiavaruuksien ja ryhmien mukaan

Kubernetes-versio 1.11 ja uudemmat mahdollistavat operaattoreiden yhdistämisen namespaceSelector и podSelector käyttämällä loogista JA. Se näyttää tältä:

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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Miksi tämä tulkitaan JA:ksi tavallisen OR:n sijaan?

Huomaa, että podSelector ei ala tavuviivalla. YAML:ssa tämä tarkoittaa sitä podSelector ja seisoo hänen edessään namespaceSelector viittaavat samaan luetteloelementtiin. Siksi ne yhdistetään loogiseen AND:iin.

Tavuviivan lisääminen ennen podSelector tuloksena syntyy uusi luetteloelementti, joka yhdistetään edelliseen namespaceSelector käyttämällä loogista TAI:ta.

Tietyllä etiketillä varustettujen palojen valitseminen kaikissa nimitiloissa, kirjoita tyhjäksi 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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Useat levy-yhtiöt tekevät yhteistyötä I:n kanssa

Säännöt palomuurille, jossa on useita objekteja (isännät, verkot, ryhmät), yhdistetään käyttämällä loogista TAI. Seuraava sääntö toimii, jos pakettilähde täsmää Host_1 TAI Host_2:

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

Päinvastoin, Kubernetesissa eri tarrat podSelector tai namespaceSelector yhdistetään loogiseen AND:iin. Esimerkiksi seuraava sääntö valitsee tyynyjä, joissa on molemmat tunnisteet, role=db И version=v2:

podSelector:
  matchLabels:
    role: db
    version: v2

Sama logiikka koskee kaikentyyppisiä operaattoreita: käytäntökohteen valitsimia, pod-valitsimia ja nimitilan valitsimia.

Aliverkot ja IP-osoitteet (IPBlocks)

Palomuurit käyttävät VLAN-verkkoja, IP-osoitteita ja aliverkkoja verkon segmentointiin.

Kubernetesissa IP-osoitteet määritetään podille automaattisesti, ja ne voivat muuttua usein, joten tunnisteita käytetään podien ja nimiavaruuksien valitsemiseen verkkokäytännöissä.

Aliverkot (ipBlocks) käytetään tulevien (tulo) tai lähtevien (ulostulo) ulkoisten (pohjoinen-etelä) yhteyksien hallinnassa. Tämä käytäntö esimerkiksi avautuu kaikille nimiavaruuden ryhmille default pääsy Google DNS -palveluun:

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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Tämän esimerkin tyhjä pod-valitsin tarkoittaa "valitse kaikki nimiavaruuden podit".

Tämä käytäntö sallii pääsyn vain versioon 8.8.8.8; pääsy muihin IP-osoitteisiin on kielletty. Joten pohjimmiltaan olet estänyt pääsyn sisäiseen Kubernetes DNS -palveluun. Jos haluat silti avata sen, ilmoita siitä selvästi.

Yleensä ipBlocks и podSelectors ovat toisensa poissulkevia, koska koteloiden sisäisiä IP-osoitteita ei käytetä ipBlocks. Ilmoittamalla sisäiset IP-kotelot, sallit itse asiassa yhteydet näillä osoitteilla oleviin koteloihin tai niistä. Käytännössä et tiedä mitä IP-osoitetta käyttää, minkä vuoksi niitä ei tule käyttää podien valitsemiseen.

Vastaesimerkkinä seuraava käytäntö sisältää kaikki IP-osoitteet ja sallii siksi pääsyn kaikkiin muihin podeihin:

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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Voit avata pääsyn vain ulkoisiin IP-osoitteisiin, lukuun ottamatta podien sisäisiä IP-osoitteita. Jos podisi aliverkko on esimerkiksi 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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Portit ja protokollat

Tyypillisesti podit kuuntelevat yhtä porttia. Tämä tarkoittaa, että et voi yksinkertaisesti määrittää porttinumeroita käytännöissä ja jättää kaiken oletukseksi. On kuitenkin suositeltavaa tehdä käytännöistä mahdollisimman rajoittavia, joten joissakin tapauksissa voit silti määrittää portit:

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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Huomaa, että valitsin ports koskee kaikkia lohkon elementtejä to tai from, joka sisältää. Määritä eri portit eri elementtisarjoille jakamalla ingress tai egress useisiin alaosiin to tai from ja jokaisessa rekisteröimässä porttisi:

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

Johdatus Kubernetes-verkkokäytäntöihin tietoturva-ammattilaisille

Oletusportin toiminta:

  • Jos jätät portin määritelmän kokonaan pois (ports), tämä tarkoittaa kaikkia protokollia ja kaikkia portteja;
  • Jos jätät protokollamäärittelyn pois (protocol), tämä tarkoittaa TCP:tä;
  • Jos jätät pois portin määritelmän (port), tämä tarkoittaa kaikkia portteja.

Paras käytäntö: Älä luota oletusarvoihin, vaan määritä, mitä tarvitset selvästi.

Huomaa, että sinun on käytettävä pod-portteja, ei huoltoportteja (lisää tästä seuraavassa kappaleessa).

Onko käytännöt määritelty podille tai palveluille?

Tyypillisesti Kubernetesin podit käyttävät toisiaan palvelun kautta - virtuaalisen kuormituksen tasapainottajan kautta, joka ohjaa liikenteen palvelun toteuttaviin podeihin. Saatat ajatella, että verkkokäytännöt hallitsevat pääsyä palveluihin, mutta näin ei ole. Kubernetes-verkkokäytännöt toimivat pod-porteissa, eivät palveluporteissa.

Jos palvelu esimerkiksi kuuntelee porttia 80, mutta ohjaa liikenteen ryhmiensä porttiin 8080, sinun on määritettävä verkkokäytännössä tarkalleen 8080.

Tällaista mekanismia tulisi pitää epäoptimaalisena: jos palvelun sisäinen rakenne (joiden podit kuuntelevat) muuttuu, verkkopolitiikkaa on päivitettävä.

Uusi arkkitehtoninen lähestymistapa Service Meshin avulla (Katso esimerkiksi Istio alta - noin käännös.) avulla voit selviytyä tästä ongelmasta.

Pitääkö sekä Ingressin että Egressin rekisteröinti?

Lyhyt vastaus on kyllä, jotta pod A voisi kommunikoida pod B:n kanssa, sen on voitava luoda lähtevä yhteys (tätä varten sinun on määritettävä poistumiskäytäntö) ja pod B:n on voitava hyväksyä saapuva yhteys ( tätä varten tarvitset sisääntulopolitiikan).

Käytännössä voit kuitenkin luottaa oletuskäytäntöön salliaksesi yhteydet yhteen tai molempiin suuntiin.

Jos jokin pod-lähde valitaan yksi tai useampi ulosmeno-poliitikot, sille asetettavat rajoitukset määräytyvät heidän eriytymisensä perusteella. Tässä tapauksessa sinun on sallittava yhteys podiin -vastaanottajalle. Jos podia ei ole valittu millään käytännöllä, sen lähtevä (poistuva) liikenne sallitaan oletuksena.

Samoin padon kohtalo onvastaanottaja, jonka yksi tai useampi on valinnut sisääntulo-poliitikot, määräytyy heidän erimielisyytensä perusteella. Tässä tapauksessa sinun on nimenomaisesti sallittava sen vastaanottaa liikennettä lähderyhmästä. Jos podia ei ole valittu millään käytännöllä, kaikki sen sisääntuloliikenne sallitaan oletuksena.

Katso valtiollinen tai valtioton alla.

Lokit

Kubernetes-verkkokäytännöt eivät voi kirjata liikennettä. Tämä tekee vaikeaksi määrittää, toimiiko käytäntö tarkoitetulla tavalla, ja vaikeuttaa suuresti tietoturva-analyysiä.

Liikenteen ohjaus ulkoisiin palveluihin

Kubernetes-verkkokäytännöt eivät salli täysin kelpuutetun toimialueen nimen (DNS) määrittämistä poistumisosioissa. Tämä seikka aiheuttaa merkittäviä haittoja, kun yritetään rajoittaa liikennettä ulkoisiin kohteisiin, joilla ei ole kiinteää IP-osoitetta (kuten aws.com).

Käytännön tarkistus

Palomuurit varoittavat sinua tai jopa kieltäytyvät hyväksymästä väärää käytäntöä. Kubernetes tekee myös jonkin verran vahvistusta. Kun Kubernetes määrittää verkkokäytännön kubectlin kautta, se voi ilmoittaa sen olevan virheellinen ja kieltäytyä hyväksymästä sitä. Muissa tapauksissa Kubernetes ottaa vakuutuksen ja täyttää sen puuttuvilla tiedoilla. Ne voidaan nähdä komennolla:

kubernetes get networkpolicy <policy-name> -o yaml

Muista, että Kubernetes-validointijärjestelmä ei ole erehtymätön ja saattaa jättää huomiotta tietyntyyppiset virheet.

Teloitus

Kubernetes ei itse toteuta verkkokäytäntöjä, vaan se on vain API-yhdyskäytävä, joka siirtää hallintataakan taustalla olevalle järjestelmälle, jota kutsutaan Container Networking Interface (CNI) -käyttöliittymäksi. Käytäntöjen asettaminen Kubernetes-klusteriin ilman asianmukaista CNI:tä on sama kuin käytäntöjen luominen palomuurin hallintapalvelimelle asentamatta niitä sitten palomuuriin. Sinun on varmistettava, että sinulla on kunnollinen CNI tai Kubernetes-alustojen tapauksessa pilvipalvelu (näet luettelon tarjoajista täällä - n. käänn.), ota käyttöön verkkokäytännöt, jotka määrittävät CNI:n puolestasi.

Huomaa, että Kubernetes ei varoita sinua, jos asetat verkkokäytännön ilman asianmukaista apu-CNI:tä.

Valtiollinen vai valtioton?

Kaikki löytämäni Kubernetes CNI:t ovat tilallisia (esimerkiksi Calico käyttää Linux-yhteyttä). Tämä antaa podille mahdollisuuden vastaanottaa vastauksia aloittamansa TCP-yhteyden kautta ilman, että sitä tarvitsee muodostaa uudelleen. En kuitenkaan ole tietoinen Kubernetes-standardista, joka takaisi tilallisuuden.

Kehittynyt suojauskäytäntöjen hallinta

Tässä on joitain tapoja parantaa Kubernetesin turvallisuuspolitiikan täytäntöönpanoa:

  1. Service Mesh -arkkitehtuurikuvio käyttää sivuvaunukontteja tarjoamaan yksityiskohtaista telemetriaa ja liikenteen ohjausta palvelutasolla. Esimerkkinä voimme ottaa Sama.
  2. Jotkut CNI-toimittajista ovat laajentaneet työkalujaan ylittääkseen Kubernetes-verkkokäytännöt.
  3. Tufin Orca Tarjoaa Kubernetes-verkkokäytäntöjen näkyvyyden ja automatisoinnin.

Tufin Orca -paketti hallitsee Kubernetes-verkkokäytäntöjä (ja on yllä olevien kuvakaappausten lähde).

lisätiedot

Johtopäätös

Kubernetes-verkkokäytännöt tarjoavat hyvän joukon työkaluja klusterien segmentointiin, mutta ne eivät ole intuitiivisia ja niissä on monia hienouksia. Tämän monimutkaisuuden vuoksi uskon, että monet nykyiset klusterikäytännöt ovat virheellisiä. Mahdollisia ratkaisuja tähän ongelmaan ovat käytäntömäärittelyjen automatisointi tai muiden segmentointityökalujen käyttö.

Toivon, että tämä opas auttaa selvittämään joitain kysymyksiä ja ratkaisemaan ongelmia, joita saatat kohdata.

PS kääntäjältä

Lue myös blogistamme:

Lähde: will.com

Lisää kommentti