Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

Megjegyzés fordítás.: A cikk szerzője, Reuven Harrison, több mint 20 éves szoftverfejlesztési tapasztalattal rendelkezik, és jelenleg a Tufin technikai igazgatója és társalapítója, amely biztonsági irányelvek kezelésére készült megoldásokat fejleszt. A Kubernetes hálózati irányelveit mint a klaszterekben történő hálószegmentálás hatékony eszközét tartja, ugyanakkor azt is megjegyzi, hogy ezek alkalmazása a gyakorlatban nem olyan egyszerű. Ez az anyag (meglehetősen terjedelmes) arra hivatott, hogy javítsa a szakemberek tájékozottságát erről a kérdésről és segítsen nekik a szükséges konfigurációk létrehozásában.

Ma már sok cég egyre inkább a Kubernetes-t választja alkalmazásaik futtatására. Az érdeklődés a szoftver iránt olyan magas, hogy néhányan a Kubernetes-t a "központi adatfeldolgozó rendszerek új operációs rendszerének" nevezik. Fokozatosan a Kubernetes (vagy k8s) kritikus fontosságú üzleti elemmé válik, amely megköveteli a kiforrott üzleti folyamatok kialakítását, beleértve a hálózati biztonság biztosítását is.

A biztonsági szakemberek számára, akiknek gondot okoz a Kubernetes használata, meglepetés lehet a platform alapértelmezett politikája: mindent engedélyezni.

Ez a kézikönyv segít megérteni a hálózati irányelvek belső működését; világossá tenni, miben különböznek a hagyományos tűzfalakkal kapcsolatos szabályoktól. Szó lesz néhány buktatóról, valamint ajánlásokat is ad, amelyek segítenek a Kubernetes alkalmazások védelmében.

Kubernetes hálózati irányelvek

A Kubernetes hálózati irányelvek mechanizmusa lehetővé teszi a platformon futó alkalmazások hálózati szintű (az OSI modell harmadik szintje) kommunikációjának kezelését. A hálózati irányelvekből hiányoznak a modern tűzfalak néhány fejlett funkciója, mint például a 7. szintű OSI kontroll és a fenyegetésészlelés, azonban alapvető szintű hálózati biztonságot biztosítanak, ami kedvező kiindulópontot jelent.

A hálózati irányelvek ellenőrzik a podok közötti kommunikációt

A Kubernetesben lévő munkaterhelések pod-ok közé vannak elosztva, amelyek egy vagy több, közösen telepített konténerből állnak. A Kubernetes minden pod-nak egy IP-címet rendel, amely más pod-okból elérhető. A Kubernetes hálózati politikái hozzáférési jogokat rendelnek a pod-csoportokhoz, hasonlóan ahhoz, ahogy a felhőben a biztonsági csoportokat használják a virtuális gépekhez való hozzáférés kezelésére.

Hálózati politikák meghatározása

A többi Kubernetes-erőforráshoz hasonlóan a hálózati politikák is YAML nyelven vannak meghatározva. Az alábbi példában az alkalmazás balance hozzáférést kap az 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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

(Megjegyzés fordítás.: ez a képernyőkép, mint minden hasonló, nem a Kubernetes beépített eszközeivel készült, hanem a Tufin Orca eszköz segítségével, amelynek fejlesztésében az eredeti cikk szerzője részt vett, és amely a tartalom végén van említve.)

Saját hálózati politika meghatározásához alapvető YAML-ismeretek szükségesek. Ez a nyelv behúzásokon alapul (amelyeket szóközök, nem tabulátorok határoznak meg). A behúzott elem a fölötte lévő legközelebbi behúzott elemhez tartozik. Egy új listaelem mínusszal kezdődik, az összes többi elem pedig a következőképpen néz ki kulcs-érték.

A politikát YAML formátumban leírva használja kubectl, hogy létrehozza a klaszterben:

kubectl create -f policy.yaml

Hálózati politika specifikációja

A Kubernetes hálózati politika specifikációja négy elemet tartalmaz:

  1. podSelector: meghatározza azokat a pod-okat, amelyeket ez a politika érint (célok) – kötelező;
  2. policyTypes: megadja, hogy milyen típusú politikák tartoznak ide: ingress és/vagy egress – nem kötelező, azonban javaslom, hogy minden esetben határozzuk meg;
  3. ingress: meghatározza a megengedett bejövő forgalmat a célzott pod-okhoz – nem kötelező;
  4. egress: meghatározza a megengedett kimenő forgalom a célzott pod-okból – nem kötelező.

A Kubernetes weboldaláról kölcsönzött példa (én kicseréltem role Gyorsan emlékezzünk vissza, hogyan működik a moduláris aritmetika. Az óra már egy ismert koncepció. Az órák használata app), megmutatja, hogyan használják a négy elemet:

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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára
Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

Kérjük, vegye figyelembe, hogy az összes négy elem megadása nem kötelező. Csak az podSelector, a többi paraméter szabadon használható.

Ha kihagyja policyTypes, akkor a politika a következőképpen lesz értelmezve:

  • Alapértelmezés szerint feltételezzük, hogy a bejövő oldalt határozza meg. Ha a politikában nincsenek erre vonatkozó kifejezett utalások, a rendszer úgy fogja tekinteni, hogy minden forgalmat tiltanak.
  • A kimenő oldal viselkedését az egress paraméter megléte vagy hiánya határozza meg.

A hibák elkerülése érdekében javaslom, hogy mindig egyértelműen adja meg, policyTypes.

A fenti logika szerint, ha a paraméterek ingress Services egress kihagyásra kerülnek, a politika megtiltja az összes forgalmat (lásd az alábbi "Tisztító szabályt").

Az alapértelmezett politika - engedélyezni

Ha a politikák nincsenek meghatározva, a Kubernetes alapértelmezés szerint engedélyezi az összes forgalmat. Minden pod szabadon információt cserélhet. Biztonsági szempontból logikátlannak tűnhet, de ne feledje, hogy a Kubernetes-et eredetileg a fejlesztők az alkalmazások közötti interakció elősegítésére hozták létre. A hálózati politikák később kerültek bevezetésre.

Névterek

A névterek (Namespaces) a Kubernetes összefogásának mechanizmusa. Azért jöttek létre, hogy elkülönítsék a logikai környezeteket egymástól, ugyanakkor az alapértelmezett beállítás szerint adatcsere megengedett az egyes névterek között.

A Kubernetes legtöbb komponenséhez hasonlóan a hálózati politikák is egy adott névtérben találhatók. A blokkban metadata megadhatja, hogy a politika melyik névtérhez tartozik:

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

Ha a metadatokban a névtér kifejezetten nincs megadva, a rendszer a kubectl által megadott névteret fogja használni (alapértelmezés szerint namespace=default):

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

Javaslom, hogy egyértelműen adja meg a névteret., hacsak nem írsz egy politikát, amely egyszerre több névtérre vonatkozik.

Alap elem podSelector a politikában a pod-ok kiválasztása az ahhoz tartozó névtérből történik (nincs hozzáférése más névtérben lévő pod-okhoz).

Hasonlóképpen, a podSelector-ok a bejövő és kimenő blokkokban csak a saját névtérből választhatnak pod-okat, kivéve, ha azokat összevonod a namespaceSelector (erről a „Szűrés névterek és pod-ok szerint” részben lesz szó).

A politikák elnevezési szabályai

A politikák nevei egy névtéren belül egyediek. Két politikának ugyanazzal a névvel nem lehet a ugyanabban a névtérben, de lehetnek ugyanazon néven politikák különböző névterekben. Ez hasznos, amikor ugyanazt a politikát szeretnéd több névtérben alkalmazni.

Különösen tetszik az elnevezés egyik módja. Ez abból áll, hogy a névtér nevét összekapcsoljuk a célzott pod-okkal. Például:

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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

Címkék

A Kubernetes objektumokhoz, mint például a pod-ok és névterek, felhasználói címkék rendelhetők. A címkék (címkéket — címkék) a felhőben található tagek megfelelői. A Kubernetes hálózati politikák a címkéket használják a kiválasztásra, pod-ok, amelyekre alkalmazzák őket:

podSelector:
  matchLabels:
    role: db

… vagy névterek, amelyekre alkalmazzák. Ebben a példában az összes pod-ot választja, a névterekben megfelelő címkékkel:

namespaceSelector:
  matchLabels:
    project: myproject

Egy figyelmeztetés: a namespaceSelector használata során győződj meg arról, hogy a kiválasztott névterek tartalmazzák a szükséges címkét.Ne feledd, hogy az alapértelmezett névterek, mint például alapértelmezett és kube-system, alapértelmezés szerint nem tartalmaznak címkéket.

Címkét az alábbi módon adhatunk hozzá egy névtérhez:

kubectl label namespace default namespace=default

Ebben az esetben a namespace a metadata részben a tényleges név hivatkozására kell, hogy utaljon, nem pedig a címkére:

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

Forrás és címzett

A tűzfal politikái forrásokból és címzettekből álló szabályokat tartalmaznak. A Kubernetes hálózati politikák célzottak - a podok összességére, amelyekre alkalmazzák őket, majd meghatározzák a bejövő (ingress) és/vagy kimenő (egress) forgalom szabályait. Példánkban a politika célja az összes pod a névtérben alapértelmezett a következő kulccsal rendelkező címkével app és az értékkel szolgáltatáshoz. A szolgáltatásrácsok általában mTLS segítségével oldják meg az ilyen problémákat: a tanúsítványok ebben az esetben szükséges azonosítóként szolgálnak.:

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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára
Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

Rész ingress ebben a politikában a célzott podok számára megnyitja a bejövő forgalmat. Más szóval, az ingress a forrást képviseli, míg a cél a megfelelő címzett. Hasonlóképpen az egress a címzett, a cél pedig a forrás.

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

Ez két tűzfal szabálynak felel meg: Ingress → Cél; Cél → Egress.

Egress és DNS (fontos!)

A kimenő forgalom korlátozása során külön figyelmet kell fordítani a DNS-re — a Kubernetes ezt a szolgáltatást használja a szolgáltatások IP-címekhez való hozzárendelésére. Például a következő politika nem fog működni, mivel nem engedélyezted az alkalmazásnak balance a DNS-hez való hozzáférést:

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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

Ezt úgy javíthatod, ha hozzáférést adsz a DNS szolgáltatáshoz:

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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

Az utolsó elem to üres, és ezért közvetve kiválasztja az összes podot minden névtérben, lehetővé téve a balance DNS-lekérdezések küldését a megfelelő Kubernetes szolgáltatásnak (általában a névtérben működik) kube-system).

Ez a megközelítés működőképes, de túlzottan engedélyezett és nem biztonságos, mivel lehetővé teszi a DNS-lekérdezések irányítását a klaszteren kívül.

Három lépésben javítható.

1. Engedélyezd a DNS-lekérdezéseket csak bent a klaszternek, a hozzáadásával 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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

2. Csak DNS lekérdezéseket engedélyezhetünk a névtérben kube-system.

Ehhez címkét kell hozzáadni a névtérhez kube-system: kubectl label namespace kube-system namespace=kube-system — és bele kell írni a politikába 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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

3. A paranoid emberek még tovább is elmehetnek, és korlátozhatják a DNS lekérdezéseket egy meghatározott DNS szolgáltatásra kube-system. A „Szűrés névterek és podok szerint” részben olvashat arról, hogyan érhető el ez.

Egy másik lehetőség, hogy a DNS-t névtéren belül engedélyezzük. Ez esetben nem kell azt minden szolgáltatás számára megnyitni:

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

Üres podSelector minden podot kiválaszt a névtérben.

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

Első egyezés és szabályok sorrendje

Hagyományos tűzfalaknál a cselekvés („Engedélyezés” vagy „Tiltás”) a csomagra vonatkozóan az első szabály alapján kerül meghatározásra, amelynek megfelel. A Kubernetesben a politikák sorrendje nem számít.

Alapértelmezés szerint, amikor nincsenek politikák megadva, a podok közötti kommunikáció engedélyezett, és szabadon cserélhetnek információt. Amint elkezd politikákat megfogalmazni, minden pod, amelyet bármelyik érint, izolálódik az összes olyan politika diszjunkt (logikai VAGY) hatásai szerint, amelyik választotta. Azok a podok, amelyeket egyetlen politika sem érint, nyitva maradnak.

Egy ilyen viselkedést törlési szabállyal lehet módosítani.

Törlési szabály („Tiltani”)

A tűzfalszabályok általában bármilyen kifejezetten nem engedélyezett forgalmat tiltani.

A Kubernetesben nincs „tiltani” (deny) cselekvés, azonban hasonló hatást elérhetünk egy szokásos (engedélyező) politikával, amely egy üres pod forráscsoportot választ (ingress):

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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

Ez a politika minden pod-ot kiválaszt a névtérben, és az ingress-t határozatlanná hagyja, megtiltva minden bejövő forgalmat.

Hasonló módon korlátozhatjuk az összes kimenő forgalmat a névtérből:

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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

Ne feledje, hogy bármely további politika, amely engedélyezi a forgalmat a névtér pod-jaihoz, prioritással bír ezzel a szabállyal szemben (hasonlóan ahhoz, hogy egy engedélyező szabályt adunk hozzá egy tiltóhoz a tűzfalszabályzatban).

Mindet engedélyezni (Any-Any-Any-Allow)

Ahhoz, hogy létrehozzuk a „Mindent engedélyezni” politikát, kiegészítenünk kell a fent említett tilalmi politikát egy üres elemmel ingress:

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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

Ez lehetővé teszi, hogy minden pod-ról minden névtérben (és minden IP-ről) hozzáférjünk bármely pod-hoz a névtérben alapértelmezett. Az ilyen viselkedés alapértelmezés szerint engedélyezett, így általában nem szükséges külön megadni. Néha azonban szükség lehet egyes konkrét engedélyek ideiglenes letiltására a probléma diagnosztizálása érdekében.

A szabályt szűkíthetjük, és csak a meghatározott pod-okhoz engedélyezhetjük a hozzáférést (app:balance) a névtérben alapértelmezett:

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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

A következő politika lehetővé teszi az összes bejövő (ingress) és kimenő (egress) forgalmat, beleértve a hozzáférést bármely IP-hez a klaszter határain kívül:

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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára
Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

Több politika egyesítése

A politikák logikai VAGY operátorral egyesülnek három szinten; minden pod engedélyezett hozzáférése a rá vonatkozó összes politika diszjunkciójának megfelelően van meghatározva:

1. A mezőkben a és to háromféle elemet lehet megadni (mindegyik VAGY operátorral kombinálható):

  • namespaceSelector — az egész névtér kiválasztása;
  • podSelector — pod-ok kiválasztása;
  • ipBlock — alhálózat kiválasztása.

Ezeknél a alsorozatokban lévő elemek (még ha azonosak is) száma nincs korlátozva. Mindegyik logikai VAGY operátorral egyesítésre kerül. a/to не ограничено. Все они будут объединены логическим ИЛИ.

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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

2. A politika belsejében ingress több elemet is tartalmazhat a (logikai VAGY formai összegzésük). Hasonló módon a szakasz egress több elemet is tartalmazhat to (ezek is diszjunkcióval összevonhatók):

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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

3. A különböző politikák logikai VAGY-nal összevonhatók

De van egy korlátozás, amelyre megjegyezte Chris Cooney: A Kubernetes csak különböző policyTypes (Ingress vagy Egress). Az ingress (vagy egress) politikák felülírják egymást.

Kapcsolat névtér között

Alapértelmezés szerint a névtér közötti információcsere engedélyezett. Ezt megváltoztathatja egy tiltó politikával, amely korlátozza a kimenő és/vagy bejövő forgalmat egy névtérben (lásd a fent említett 'Tisztító Szabályt').

Ha blokkolja a hozzáférést egy névtérben (lásd a fent említett 'Tisztító Szabályt'), akkor kivételeket tehet a tiltó politikában, engedélyezve a kapcsolatot egy adott névtérrel 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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

Ennek eredményeként minden pod a névtérben alapértelmezett hozzáférést kap a podokhoz postgres a névtérben database. De mi van, ha csak bizonyos podokhoz szeretne hozzáférést biztosítani a névtérben postgres Szűrés névterek és podok alapján alapértelmezett?

A Kubernetes 1.11-es és újabb verziói lehetővé teszik az operátorok kombinálását

logikai ÉS segítségével. Ez a következőképpen néz ki: namespaceSelector és podSelector apiVersion: networking.k8s.io/v1 kind: NetworkPolicy metadata: name: database.postgres namespace: database spec: podSelector: matchLabels: app: postgres ingress: - from: - namespaceSelector: matchLabels: namespace: default podSelector: # <<< matchLabels: app: admin policyTypes: - Ingress

Miért értelmezzük ezt ÉS-ként, a megszokott VAGY helyett?

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

nem kezdődik kötőjellel. A YAML-ban ez azt jelenti, hogy

p(x) – podSelector és ami előtte áll podSelector ugyanahhoz a listaelemhez tartoznak. Ezért logikai ÉS-ként egyesülnek. namespaceSelector Kötőjel hozzáadása előtt

Добавление дефиса перед podSelector egy új listaelem létrehozásához vezet, amely kombinálódik a korábbival namespaceSelector logikai VAGY használatával.

Címkés podok kiválasztásához minden névtérben, írjon be üreset 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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

Többszörös címkék kombinálódnak ÉS

A tűzfal szabályai több objektummal (hostokkal, hálózatokkal, csoportokkal) logikai VAGY segítségével kombinálódnak. A következő szabály akkor lép életbe, ha a csomag forrása megegyezik Host_1 VAGY Host_2:

| Forrás | Cél | Szolgáltatás | Akció |
| ----------------------------------------|
| Host_1 | Subnet_A    | HTTPS   | Engedélyez |
| Host_2 |             |         |        |
| ----------------------------------------|

Ellenkezőleg, a Kubernetesben a különböző címkék podSelector vagy namespaceSelector logikai ÉS segítségével kombinálódnak. Például a következő szabály olyan podokat választ, amelyek mindkét címkével rendelkeznek, role=db és version=v2:

podSelector:
  matchLabels:
    role: db
    version: v2

Ugyanez a logika vonatkozik minden operátor típusra: a politikai célok selektoraira, a pod selektorokra és a névtér selektorokra.

Alhálózatok és IP-címek (IPBlocks)

A hálózat szegmentálásához a tűzfalak VLAN-t, IP-címeket és alhálózatokat használnak.

A Kubernetesben az IP-címeket automatikusan a podokhoz rendelik, és gyakran változhatnak, ezért a podok és névterek kiválasztásához a hálózati politikákban címkéket használnak.

Alhálózatok (ipBlocks) a bejövő (ingress) vagy kimenő (egress) külső (North-South) kapcsolatok kezelésére használatosak. Például ez a politika lehetővé teszi minden pod számára a névtérből alapértelmezett hozzáférést a Google DNS-szolgáltatásához:

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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

A podok üres szelektora ebben a példában azt jelenti, hogy "válassza az összes podot a névtérben."

Ez a politika csak a 8.8.8.8-hoz biztosít hozzáférést; minden más IP elérhetőségét blokkolja. Így lényegében letiltotta a Kubernetes belső DNS-szolgáltatásához való hozzáférést. Ha mégis szeretné megnyitni, azt egyértelműen jelezni kell.

Általában ipBlocks és podSelectors kizárólagosak, mivel a podok belső IP-címei nem használatosak a ipBlocks. A podok belső IP-címeinek megadásával внутренние IP pod’ов, gyakorlatilag engedélyezi a pod-okhoz való csatlakozást ezekkel a címekkel. A gyakorlatban nem fogja tudni, melyik IP-címet használja, ezért ezeket nem szabad használni a pod-ok kiválasztásához.

Egy ellenpélda, amely a következő politikát tartalmazza, minden IP-t magában foglal, ezért hozzáférést biztosít az összes többi pod-hoz:

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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

Csak a külső IP-khez lehet hozzáférést biztosítani, kizárva a pod-ok belső IP-címeit. Például, ha a pod hálózati szegmense 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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

Portok és protokollok

Általában a pod-ok egy portot hallgatnak. Ez azt jelenti, hogy a politikákban egyszerűen nem szükséges megadni a port számokat, és mindent alapértelmezetten lehet hagyni. Mindazonáltal a politikákat a lehető legkorlátozóbban kell megalkotni, ezért bizonyos esetekben érdemes lehet megadni a portokat:

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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

Megjegyzendő, hogy a szelekciós portok alkalmazásra kerül az összes elemre a blokkban to vagy a, amelyben található. Különböző portokat különböző elemcsoportokhoz megadni úgy lehet, hogy ingress vagy egress több alrészre bontjuk to vagy a és mindegyikben a saját portjait rögzítjük:

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

Bevezetés a Kubernetes hálózati politikákba a biztonsági szakemberek számára

Alapértelmezetten a portok működése:

  • Ha teljesen kihagyja a portok meghatározását (portok), ez minden protokollt és minden portot jelent;
  • Ha a protokoll meghatározását kihagyja (protocol), ez TCP-t jelent;
  • Ha a port meghatározását kihagyja (port), ez minden portot jelent.

Legjobb gyakorlat: ne bízzon az alapértelmezett értékekben, határozza meg a szükségeseket egyértelműen.

Felhívjuk figyelmét, hogy a podok portjait, és nem a szolgáltatásokét kell használni (erről a következő bekezdésben olvashat).

A politikák podokhoz vagy szolgáltatásokhoz vannak definiálva?

A Kubernetesben általában a podok egymás között a szolgáltatáson keresztül kommunikálnak — egy virtuális terheléselosztó, amely a forgalmat a szolgáltatást megvalósító podokhoz irányítja. Lehet azt gondolni, hogy a hálózati politikák a szolgáltatásokhoz való hozzáférést szabályozzák, de ez nem így van. A Kubernetes hálózati politikák a podok portjain működnek, és nem a szolgáltatásokén.

Például, ha egy szolgáltatás a 80-as portot hallgatja, de a podok 8080-as portjára irányítja a forgalmat, akkor a hálózati politikában kifejezetten a 8080-as portot kell megadni.

Ez a mechanizmus nem optimális: a szolgáltatás belső felépítése (amelyet a podok portjai hallgatnak) változása esetén a hálózati politikákat is frissíteni kell.

Új architekturális megközelítés a Service Mesh használatával (például lásd Istio-t alább — a fordító megjegyzése) segít megoldani ezt a problémát.

Szükséges megadni mind az Ingress-t, mind az Egress-t?

A rövid válasz — igen, ahhoz, hogy az A pod kommunikálhasson a B poddal, engedélyeznie kell a kimenő kapcsolat létrehozását (ehhez Egress politikát kell beállítani), és a B podnak lehetőséget kell adnia a bejövő kapcsolat fogadására (ehhez, megfelelően, Ingress politikára van szükség).

A gyakorlatban azonban támaszkodhatunk egy alapértelmezett politikára, amely az egy vagy mindkét irányban történő kapcsolatok engedélyezésére vonatkozik.

Ha egy pod-forrás ki lesz választva egy vagy több egress-politikával, azokra vonatkozó korlátozások a diszjunktiójuk alapján fognak megvalósulni. Ebben az esetben kifejezetten engedélyezni kell a kapcsolatot a pod--címzettel.Ha a podot nem választotta ki egy politikai szabály, akkor a kimenő (Egress) forgalma alapértelmezés szerint engedélyezett.

Hasonlóképpen a pod--címzett sorsa, amelyet egy vagy több-politika választ ki, a diszjunktiójuk alapján fog megvalósulni. Ebben az esetben kifejezetten engedélyezni kell számára, hogy kimenő forgalmat fogadjon a pod-forrástól. Ha a podot nem választotta ki egy politikai szabály, akkor az összes bejövő (Ingress) forgalma alapértelmezés szerint engedélyezett. ingressLásd a «Stateful vagy Stateless» pontot alább.

A Kubernetes hálózati politikák nem képesek a forgalom naplózására. Ez megnehezíti annak meghatározását, hogy a politika megfelelően működik-e, és jelentősen megnehezíti a biztonsági elemzést.

Naplok

A forgalom ellenőrzése a külső szolgáltatások felé.

Контроль за трафиком к внешним сервисам

A Kubernetes hálózati politikák nem engedélyezik teljes domain név (DNS) megadását az egress szekciókban. Ez a tény jelentős kényelmetlenséget okoz, amikor a forgalmat külső címzettekhez szeretnénk korlátozni, akiknek nincs fix IP-címük (például aws.com).

Politika ellenőrzése

A tűzfalak figyelmeztetnek vagy akár elutasítják a hibás politikát. A Kubernetes is végez némi ellenőrzést. Amikor a hálózati politikát a kubectl-en keresztül adjuk meg, a Kubernetes jelezheti, hogy az helytelen, és elutasíthatja azt. Más esetekben a Kubernetes elfogadja a politikát, és kiegészíti a hiányzó részletekkel. Ezeket a következő parancs segítségével nézheti meg:

kubernetes get networkpolicy  -o yaml

Ne feledje, hogy a Kubernetes ellenőrző rendszere nem tévedhetetlen, és bizonyos típusú hibákat átugorhat.

Végrehajtás

A Kubernetes nem valósítja meg a hálózati politikákat saját magától, csupán API-híd, amely a költséges ellenőrzési feladatot egy alsóbb szintű rendszerre, a Container Networking Interface (CNI)-re hárítja. A politikák megadása a Kubernetes klaszterben CNI hozzárendelése nélkül egyenértékű a tűzfalkezelő szerver politikáinak létrehozásával anélkül, hogy azokat később telepítené a tűzfalkészülékekre. Önnek magának kell biztosítania a megfelelő CNI-t, vagy, ha a Kubernetes platform felhőben van telepítve, (a szolgáltatók listáját itt találja) itt — szerk. megj., alkalmazhatja a hálózati politikákat, amelyek beállítják a CNI-t ön helyett.

Vegye észre, hogy a Kubernetes nem figyelmeztet, ha hálózati politikát ad meg a megfelelő támogatói CNI nélkül.

Stateful vagy Stateless?

Minden CNI, amellyel találkoztam a Kubernetes rendszerében állapotot tart fenn (például a Calico Linux conntrack-et használ). Ez lehetővé teszi a pod számára, hogy válaszokat kapjon az általa kezdeményezett TCP-kapcsolaton anélkül, hogy azt újra kellene indítania. Ezen kívül nem tudok olyan Kubernetes szabványról, amely garantálná az állapot kezelését (statefulness).

Fejlett biztonságpolitikai kezelés

Néhány módja van a biztonságpolitika végrehajtásának hatékonyságának növelésére a Kubernetes rendszerében:

  1. A Service Mesh architekturális minta sidecar-konténereket használ a részletes telemetria és forgalomellenőrzés biztosítása érdekében, szintetizálva a szolgáltatások szintjén. Például... Istio.
  2. Néhány CNI szolgáltató bővítette eszközeit, hogy túllépjenek a Kubernetes hálózati politikáin.
  3. Tufin Orca átláthatóságot és automatizálást biztosít a Kubernetes hálózati politikáihoz.

A Tufin Orca csomag kezeli a Kubernetes hálózati politikáit (és forrást biztosít a fenti képernyőképekhez).

Dokumentáció

Zárás

A Kubernetes hálózati politikák elég jó szerszámkészletet kínálnak a klaszterek szegmentálásához, azonban nem intuitívak, és számos finomságuk van. Úgy vélem, hogy e bonyolultság miatt sok meglévő klaszter politikái hibásak. E probléma lehetséges megoldásai a politikai határozatok automatizálása vagy más szegmentáló eszközök alkalmazása.

Remélem, hogy ez az útmutató segít tisztázni néhány kérdést és megoldani azokat a problémákat, amelyekkel szembesülhet.

Fejlesztési eszközök, amelyek Kubernetesben futnak

Olvasson további információkat a blogunkban:

Forrás: habr.com

Megbízható hosting vásárlása weboldalak számára, DDoS védelemmel, VPS VDS szerverek. 🔥 Megbízható webtárhely vásárlása DDoS védelemmel, VPS VDS szerverek | ProHoster