Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Tandaan. transl.: Ang may-akda ng artikulo, si Reuven Harrison, ay may higit sa 20 taong karanasan sa pagbuo ng software, at ngayon ay ang CTO at co-founder ng Tufin, isang kumpanya na lumilikha ng mga solusyon sa pamamahala ng patakaran sa seguridad. Habang tinitingnan niya ang mga patakaran sa network ng Kubernetes bilang isang medyo makapangyarihang tool para sa pagse-segment ng network sa isang cluster, naniniwala rin siya na hindi ganoon kadaling ipatupad ang mga ito sa pagsasanay. Ang materyal na ito (medyo napakalaki) ay nilayon upang mapabuti ang kamalayan ng mga espesyalista sa isyung ito at tulungan silang gumawa ng mga kinakailangang configuration.

Ngayon, maraming kumpanya ang lalong pumipili ng mga Kubernetes upang patakbuhin ang kanilang mga aplikasyon. Napakataas ng interes sa software na ito kaya tinawag ng ilan ang Kubernetes na "ang bagong operating system para sa data center." Unti-unti, ang Kubernetes (o k8s) ay nagsisimula nang mapagtanto bilang isang kritikal na bahagi ng negosyo, na nangangailangan ng organisasyon ng mga mature na proseso ng negosyo, kabilang ang network security.

Para sa mga propesyonal sa seguridad na naguguluhan sa pakikipagtulungan sa Kubernetes, ang tunay na paghahayag ay maaaring ang default na patakaran ng platform: payagan ang lahat.

Tutulungan ka ng gabay na ito na maunawaan ang panloob na istruktura ng mga patakaran sa network; maunawaan kung paano sila naiiba sa mga panuntunan para sa mga regular na firewall. Sasakupin din nito ang ilang mga pitfalls at magbibigay ng mga rekomendasyon para makatulong sa pag-secure ng mga application sa Kubernetes.

Mga patakaran sa network ng Kubernetes

Binibigyang-daan ka ng mekanismo ng patakaran sa network ng Kubernetes na pamahalaan ang pakikipag-ugnayan ng mga application na naka-deploy sa platform sa layer ng network (ang pangatlo sa modelo ng OSI). Kulang ang mga patakaran sa network ng ilan sa mga advanced na feature ng mga modernong firewall, tulad ng pagpapatupad ng OSI Layer 7 at pagtukoy ng pagbabanta, ngunit nagbibigay ang mga ito ng pangunahing antas ng seguridad ng network na isang magandang panimulang punto.

Kinokontrol ng mga patakaran sa network ang mga komunikasyon sa pagitan ng mga pod

Ang mga workload sa Kubernetes ay ipinamamahagi sa mga pod, na binubuo ng isa o higit pang mga container na naka-deploy nang magkasama. Ang Kubernetes ay nagtatalaga sa bawat pod ng isang IP address na naa-access mula sa iba pang mga pod. Ang mga patakaran sa network ng Kubernetes ay nagtatakda ng mga karapatan sa pag-access para sa mga pangkat ng mga pod sa parehong paraan na ginagamit ang mga pangkat ng seguridad sa cloud upang kontrolin ang pag-access sa mga virtual machine na instance.

Pagtukoy sa Mga Patakaran sa Network

Tulad ng ibang mga mapagkukunan ng Kubernetes, ang mga patakaran sa network ay tinukoy sa YAML. Sa halimbawa sa ibaba, ang application balance access sa 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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

(Tandaan. transl.: ang screenshot na ito, tulad ng lahat ng kasunod na katulad, ay ginawa hindi gamit ang mga katutubong tool ng Kubernetes, ngunit gamit ang Tufin Orca tool, na binuo ng kumpanya ng may-akda ng orihinal na artikulo at na binanggit sa dulo ng materyal.)

Upang tukuyin ang iyong sariling patakaran sa network, kakailanganin mo ng pangunahing kaalaman sa YAML. Ang wikang ito ay batay sa indentation (tinukoy ng mga puwang sa halip na mga tab). Ang isang naka-indent na elemento ay kabilang sa pinakamalapit na naka-indent na elemento sa itaas nito. Ang isang bagong elemento ng listahan ay nagsisimula sa isang gitling, lahat ng iba pang mga elemento ay may form key-value.

Kapag inilarawan ang patakaran sa YAML, gamitin kubectlpara gawin ito sa cluster:

kubectl create -f policy.yaml

Detalye ng Patakaran sa Network

Kasama sa detalye ng patakaran sa network ng Kubernetes ang apat na elemento:

  1. podSelector: tumutukoy sa mga pod na apektado ng patakarang ito (mga target) - kinakailangan;
  2. policyTypes: ay nagpapahiwatig kung anong mga uri ng mga patakaran ang kasama dito: pagpasok at/o paglabas - opsyonal, ngunit inirerekumenda kong tahasan itong tukuyin sa lahat ng kaso;
  3. ingress: tumutukoy sa pinapayagan papasok trapiko sa mga target na pod - opsyonal;
  4. egress: tumutukoy sa pinapayagan palabas opsyonal ang trapiko mula sa mga target na pod.

Halimbawang kinuha mula sa website ng Kubernetes (pinalitan ko role sa app), ay nagpapakita kung paano ginagamit ang lahat ng apat na elemento:

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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad
Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Mangyaring tandaan na ang lahat ng apat na elemento ay hindi kailangang isama. Ito ay sapilitan lamang podSelector, maaaring gamitin ang iba pang mga parameter ayon sa ninanais.

Kung iiwan mo policyTypes, ang patakaran ay bibigyang-kahulugan bilang sumusunod:

  • Bilang default, ipinapalagay na tinutukoy nito ang panig ng pagpasok. Kung hindi ito tahasang isinasaad ng patakaran, ipapalagay ng system na ipinagbabawal ang lahat ng trapiko.
  • Ang pag-uugali sa gilid ng labasan ay matutukoy sa pamamagitan ng pagkakaroon o kawalan ng kaukulang parameter ng paglabas.

Upang maiwasan ang mga pagkakamali, inirerekomenda ko laging gawin itong tahasan policyTypes.

Ayon sa lohika sa itaas, kung ang mga parameter ingress at / o egress tinanggal, tatanggihan ng patakaran ang lahat ng trapiko (tingnan ang "Sripping Rule" sa ibaba).

Default na patakaran ay Payagan

Kung walang tinukoy na mga patakaran, pinapayagan ng Kubernetes ang lahat ng trapiko bilang default. Ang lahat ng mga pod ay maaaring malayang makipagpalitan ng impormasyon sa kanilang mga sarili. Ito ay maaaring mukhang counterintuitive mula sa isang pananaw sa seguridad, ngunit tandaan na ang Kubernetes ay orihinal na idinisenyo ng mga developer upang paganahin ang interoperability ng application. Ang mga patakaran sa network ay idinagdag sa ibang pagkakataon.

Mga namespace

Ang mga namespace ay ang mekanismo ng pakikipagtulungan ng Kubernetes. Ang mga ito ay idinisenyo upang ihiwalay ang mga lohikal na kapaligiran sa isa't isa, habang ang komunikasyon sa pagitan ng mga puwang ay pinapayagan bilang default.

Tulad ng karamihan sa mga bahagi ng Kubernetes, ang mga patakaran sa network ay nabubuhay sa isang partikular na namespace. Sa block metadata maaari mong tukuyin kung saang espasyo kabilang ang patakaran:

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

Kung ang namespace ay hindi tahasang tinukoy sa metadata, gagamitin ng system ang namespace na tinukoy sa kubectl (bilang default namespace=default):

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

Nirerekomenda ko tahasang tukuyin ang namespace, maliban kung nagsusulat ka ng patakaran na nagta-target ng maraming namespace nang sabay-sabay.

Ang pangunahing elemento podSelector sa patakaran ay pipili ng mga pod mula sa namespace kung saan kabilang ang patakaran (ito ay tinanggihan ng access sa mga pod mula sa isa pang namespace).

Katulad nito, podSelectors sa ingress at egress blocks maaari lamang pumili ng mga pod mula sa kanilang sariling namespace, maliban kung siyempre pagsamahin mo ang mga ito namespaceSelector (ito ay tatalakayin sa seksyong "I-filter ayon sa mga namespace at pod").

Mga Panuntunan sa Pagpapangalan ng Patakaran

Ang mga pangalan ng patakaran ay natatangi sa loob ng parehong namespace. Hindi maaaring magkaroon ng dalawang patakaran na may parehong pangalan sa parehong espasyo, ngunit maaaring mayroong mga patakarang may parehong pangalan sa magkaibang espasyo. Kapaki-pakinabang ito kapag gusto mong ilapat muli ang parehong patakaran sa maraming espasyo.

Gusto ko lalo na ang isa sa mga paraan ng pagbibigay ng pangalan. Binubuo ito ng pagsasama-sama ng pangalan ng namespace sa mga target na pod. Halimbawa:

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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Mga label

Maaari kang mag-attach ng mga custom na label sa mga bagay ng Kubernetes, gaya ng mga pod at namespace. Mga Label (mga label - mga tag) ay ang katumbas ng mga tag sa cloud. Gumagamit ang mga patakaran sa network ng Kubernetes ng mga label para pumili mga podkung saan sila nag-aaplay:

podSelector:
  matchLabels:
    role: db

… o mga namespacekung saan sila nag-aaplay. Pinipili ng halimbawang ito ang lahat ng pod sa mga namespace na may kaukulang mga label:

namespaceSelector:
  matchLabels:
    project: myproject

Isang pag-iingat: kapag ginagamit namespaceSelector siguraduhin na ang mga namespace na pipiliin mo ay naglalaman ng tamang label. Magkaroon ng kamalayan na ang mga built-in na namespace gaya ng default ΠΈ kube-system, bilang default ay hindi naglalaman ng mga label.

Maaari kang magdagdag ng label sa isang puwang na tulad nito:

kubectl label namespace default namespace=default

Kasabay nito, namespace sa seksyon metadata dapat sumangguni sa aktwal na pangalan ng espasyo, hindi ang label:

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

Pinagmulan at patutunguhan

Ang mga patakaran sa firewall ay binubuo ng mga panuntunan na may mga pinagmulan at destinasyon. Ang mga patakaran sa network ng Kubernetes ay tinukoy para sa isang target - isang hanay ng mga pod kung saan nalalapat ang mga ito - at pagkatapos ay nagtatakda ng mga panuntunan para sa trapiko sa pagpasok at/o paglabas. Sa aming halimbawa, ang target ng patakaran ay ang lahat ng pod sa namespace default may label na may susi app at kahulugan 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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad
Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Subsection ingress sa patakarang ito, nagbubukas ng papasok na trapiko sa mga target na pod. Sa madaling salita, ang ingress ang pinagmulan at ang target ay ang kaukulang destinasyon. Gayundin, ang paglabas ay ang destinasyon at ang target ay ang pinagmulan nito.

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Katumbas ito ng dalawang panuntunan sa firewall: Ingress β†’ Target; Layunin β†’ Paglabas.

Egress at DNS (mahalaga!)

Sa pamamagitan ng paglilimita sa papalabas na trapiko, bigyang-pansin ang DNS - Ginagamit ng Kubernetes ang serbisyong ito upang imapa ang mga serbisyo sa mga IP address. Halimbawa, hindi gagana ang sumusunod na patakaran dahil hindi mo pinayagan ang aplikasyon balance i-access ang 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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Maaayos mo ito sa pamamagitan ng pagbubukas ng access sa serbisyo ng 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
  - to:               # <<<
    ports:            # <<<
    - protocol: UDP   # <<<
      port: 53        # <<<
  policyTypes:
  - Egress

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Huling elemento to ay walang laman, at samakatuwid ito ay hindi direktang pumipili lahat ng pod sa lahat ng namespaces, nagpapahintulot balance magpadala ng mga query sa DNS sa naaangkop na serbisyo ng Kubernetes (karaniwang tumatakbo sa espasyo kube-system).

Ang diskarte na ito ay gumagana, gayunpaman ito sobrang permissive at insecure, dahil pinapayagan nito ang mga query sa DNS na maidirekta sa labas ng cluster.

Mapapabuti mo ito sa tatlong magkakasunod na hakbang.

1. Payagan lamang ang mga query sa DNS sa loob cluster sa pamamagitan ng pagdaragdag 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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

2. Payagan ang mga query sa DNS sa loob ng namespace lamang kube-system.

Upang gawin ito kailangan mong magdagdag ng label sa namespace kube-system: kubectl label namespace kube-system namespace=kube-system - at isulat ito sa patakaran gamit 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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

3. Ang mga paranoid na tao ay maaaring pumunta nang higit pa at limitahan ang mga query sa DNS sa isang partikular na serbisyo ng DNS sa kube-system. Sasabihin sa iyo ng seksyong "I-filter ayon sa mga namespace AT pod" kung paano ito makakamit.

Ang isa pang pagpipilian ay upang malutas ang DNS sa antas ng namespace. Sa kasong ito, hindi ito kailangang buksan para sa bawat serbisyo:

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

Walang laman podSelector pinipili ang lahat ng pod sa namespace.

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Unang tugma at pagkakasunud-sunod ng panuntunan

Sa mga nakasanayang firewall, ang aksyon (Pahintulutan o Tanggihan) sa isang packet ay tinutukoy ng unang tuntunin na natutugunan nito. Sa Kubernetes, hindi mahalaga ang pagkakasunud-sunod ng mga patakaran.

Bilang default, kapag walang nakatakdang mga patakaran, pinapayagan ang mga komunikasyon sa pagitan ng mga pod at maaari silang malayang makipagpalitan ng impormasyon. Kapag nagsimula ka nang bumalangkas ng mga patakaran, ang bawat pod na apektado ng kahit isa man lang sa mga ito ay magiging isolated ayon sa disjunction (lohikal na O) ng lahat ng patakarang pumili nito. Ang mga pod na hindi apektado ng anumang patakaran ay mananatiling bukas.

Maaari mong baguhin ang gawi na ito gamit ang isang panuntunan sa paghuhubad.

Panuntunan sa pagtanggal ("Tanggihan")

Karaniwang tinatanggihan ng mga patakaran ng firewall ang anumang trapiko na hindi tahasang pinapayagan.

Walang pagtanggi na aksyon sa Kubernetes, gayunpaman, ang isang katulad na epekto ay maaaring makamit sa isang regular na (permissive) na patakaran sa pamamagitan ng pagpili ng isang walang laman na grupo ng mga source pod (ingress):

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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Pinipili ng patakarang ito ang lahat ng pod sa namespace at iniiwan ang pagpasok na hindi natukoy, na tinatanggihan ang lahat ng papasok na trapiko.

Sa katulad na paraan, maaari mong paghigpitan ang lahat ng papalabas na trapiko mula sa isang namespace:

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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Pakitandaan iyan ang anumang karagdagang mga patakaran na nagpapahintulot sa trapiko sa mga pod sa namespace ay mauuna sa panuntunang ito (katulad ng pagdaragdag ng allow rule bago ang isang deny rule sa isang firewall configuration).

Payagan ang lahat (Any-Any-Any-Allow)

Upang gumawa ng patakarang Allow All, kailangan mong dagdagan ang patakarang Tanggihan sa itaas ng walang laman na elemento ingress:

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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Pinapayagan nito ang pag-access mula sa lahat ng pod sa lahat ng namespaces (at lahat ng IP) sa anumang pod sa namespace default. Ang pag-uugali na ito ay pinagana bilang default, kaya kadalasan ay hindi na ito kailangang tukuyin pa. Gayunpaman, kung minsan ay maaaring kailanganin mong pansamantalang huwag paganahin ang ilang partikular na pahintulot upang masuri ang problema.

Ang panuntunan ay maaaring paliitin upang payagan ang pag-access lamang sa isang tiyak na hanay ng mga pod (app:balance) sa namespace default:

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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Ang sumusunod na patakaran ay nagbibigay-daan sa lahat ng trapiko sa pagpasok at paglabas, kabilang ang pag-access sa anumang IP sa labas ng cluster:

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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad
Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Pagsasama-sama ng Maramihang Mga Patakaran

Pinagsasama-sama ang mga patakaran gamit ang lohikal na O sa tatlong antas; Ang mga pahintulot ng bawat pod ay itinakda alinsunod sa disjunction ng lahat ng patakarang nakakaapekto dito:

1. Sa mga bukid from ΠΈ to Tatlong uri ng mga elemento ang maaaring tukuyin (lahat ay pinagsama gamit ang OR):

  • namespaceSelector β€” pinipili ang buong namespace;
  • podSelector β€” pumipili ng mga pod;
  • ipBlock β€” pumipili ng subnet.

Bukod dito, ang bilang ng mga elemento (kahit na magkapareho) sa mga subsection from/to hindi limitado. Lahat ng mga ito ay pagsasamahin ng lohikal na OR.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.postgres
  namespace: default
spec:
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: indexer
    - podSelector:
        matchLabels:
          app: admin
  podSelector:
    matchLabels:
      app: postgres
  policyTypes:
  - Ingress

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

2. Sa loob ng seksyon ng patakaran ingress maaaring magkaroon ng maraming elemento from (pinagsama ng lohikal na O). Katulad nito, seksyon egress maaaring magsama ng maraming elemento to (pinagsama rin ng disjunction):

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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

3. Ang iba't ibang mga patakaran ay pinagsama rin sa lohikal na O

Ngunit kapag pinagsama ang mga ito, mayroong isang limitasyon kung saan itinuro Chris Cooney: Maaari lamang pagsamahin ng Kubernetes ang mga patakaran sa iba policyTypes (Ingress o Egress). Ang mga patakarang tumutukoy sa pagpasok (o paglabas) ay papatungan ang isa't isa.

Relasyon sa pagitan ng mga namespace

Bilang default, pinapayagan ang pagbabahagi ng impormasyon sa pagitan ng mga namespace. Maaari itong baguhin sa pamamagitan ng paggamit ng patakaran sa pagtanggi na maghihigpit sa trapikong papalabas at/o papasok sa namespace (tingnan ang "Sripping Rule" sa itaas).

Kapag na-block mo na ang access sa isang namespace (tingnan ang "Sripping Rule" sa itaas), maaari kang gumawa ng mga pagbubukod sa patakaran sa pagtanggi sa pamamagitan ng pagpayag sa mga koneksyon mula sa isang partikular na namespace gamit ang 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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Bilang resulta, lahat ng pod sa namespace default magkakaroon ng access sa mga pod postgres sa namespace database. Ngunit paano kung gusto mong buksan ang access sa postgres mga partikular na pod lamang sa namespace default?

I-filter ayon sa mga namespace at pod

Binibigyang-daan ka ng Kubernetes na bersyon 1.11 at mas mataas na pagsamahin ang mga operator namespaceSelector ΠΈ podSelector gamit ang lohikal na AT. Mukhang ganito:

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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Bakit ito binibigyang kahulugan bilang AT sa halip na karaniwang OR?

Mangyaring tandaan na ang podSelector hindi nagsisimula sa gitling. Sa YAML ibig sabihin nito podSelector at nakatayo sa harap niya namespaceSelector sumangguni sa parehong elemento ng listahan. Samakatuwid, ang mga ito ay pinagsama sa lohikal na AT.

Pagdaragdag ng gitling bago podSelector ay magreresulta sa paglitaw ng isang bagong elemento ng listahan, na isasama sa nauna namespaceSelector gamit ang lohikal na O.

Para pumili ng mga pod na may partikular na label sa lahat ng namespaces, ilagay ang blangko 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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Nakipagtulungan ang maraming label sa I

Ang mga panuntunan para sa isang firewall na may maraming bagay (mga host, network, grupo) ay pinagsama gamit ang lohikal na O. Ang sumusunod na panuntunan ay gagana kung ang packet source ay tumutugma Host_1 O kaya Host_2:

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

Sa kabaligtaran, sa Kubernetes ang iba't ibang mga label sa podSelector o namespaceSelector ay pinagsama sa lohikal na AT. Halimbawa, ang sumusunod na panuntunan ay pipili ng mga pod na may parehong label, role=db И version=v2:

podSelector:
  matchLabels:
    role: db
    version: v2

Ang parehong logic ay nalalapat sa lahat ng uri ng mga operator: mga tagapili ng target ng patakaran, mga tagapili ng pod, at mga tagapili ng namespace.

Mga subnet at IP address (IPBlocks)

Gumagamit ang mga firewall ng mga VLAN, IP address, at mga subnet upang i-segment ang isang network.

Sa Kubernetes, awtomatikong itinatalaga ang mga IP address sa mga pod at maaaring magbago nang madalas, kaya ginagamit ang mga label para pumili ng mga pod at namespace sa mga patakaran ng network.

Mga subnet (ipBlocks) ay ginagamit kapag pinamamahalaan ang mga papasok (ingress) o papalabas (egress) na panlabas (North-South) na mga koneksyon. Halimbawa, nagbubukas ang patakarang ito sa lahat ng pod mula sa namespace default access sa serbisyo ng Google DNS:

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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Ang walang laman na pod selector sa halimbawang ito ay nangangahulugang "piliin ang lahat ng pod sa namespace."

Pinapayagan lamang ng patakarang ito ang pag-access sa 8.8.8.8; ang pag-access sa anumang iba pang IP ay ipinagbabawal. Kaya, sa esensya, na-block mo ang pag-access sa panloob na serbisyo ng DNS ng Kubernetes. Kung gusto mo pa rin itong buksan, ipahiwatig ito nang tahasan.

Karaniwan ipBlocks ΠΈ podSelectors ay kapwa eksklusibo, dahil ang mga panloob na IP address ng mga pod ay hindi ginagamit sa ipBlocks. Sa pamamagitan ng pagpapahiwatig panloob na mga IP pod, papayagan mo talaga ang mga koneksyon sa/mula sa mga pod na may mga address na ito. Sa pagsasagawa, hindi mo malalaman kung aling IP address ang gagamitin, kaya naman hindi sila dapat gamitin para pumili ng mga pod.

Bilang isang kontra-halimbawa, kasama sa sumusunod na patakaran ang lahat ng mga IP at samakatuwid ay nagbibigay-daan sa pag-access sa lahat ng iba pang pod:

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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Maaari mo lamang buksan ang access sa mga panlabas na IP, hindi kasama ang mga panloob na IP address ng mga pod. Halimbawa, kung ang subnet ng iyong pod ay 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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Mga port at protocol

Karaniwang nakikinig ang mga pod sa isang port. Nangangahulugan ito na hindi mo maaaring tukuyin ang mga numero ng port sa mga patakaran at iwanan ang lahat bilang default. Gayunpaman, inirerekumenda na gawing mahigpit ang mga patakaran hangga't maaari, kaya sa ilang mga kaso maaari mo pa ring tukuyin ang mga port:

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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Tandaan na ang selector ports nalalapat sa lahat ng elemento sa block to o from, na naglalaman ng. Para tukuyin ang iba't ibang port para sa iba't ibang hanay ng mga elemento, hatiin ingress o egress sa ilang mga subsection na may to o from at sa bawat pagrehistro ng iyong mga port:

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

Isang Panimula sa Mga Patakaran sa Network ng Kubernetes para sa Mga Propesyonal sa Seguridad

Default na operasyon ng port:

  • Kung ganap mong aalisin ang kahulugan ng port (ports), nangangahulugan ito ng lahat ng protocol at lahat ng port;
  • Kung aalisin mo ang kahulugan ng protocol (protocol), nangangahulugan ito ng TCP;
  • Kung aalisin mo ang kahulugan ng port (port), nangangahulugan ito ng lahat ng port.

Pinakamahusay na kasanayan: Huwag umasa sa mga default na halaga, tahasang tukuyin kung ano ang kailangan mo.

Pakitandaan na dapat kang gumamit ng mga pod port, hindi mga service port (higit pa tungkol dito sa susunod na talata).

Tinukoy ba ang mga patakaran para sa mga pod o serbisyo?

Karaniwan, ang mga pod sa Kubernetes ay nag-a-access sa isa't isa sa pamamagitan ng isang serbisyo - isang virtual load balancer na nagre-redirect ng trapiko sa mga pod na nagpapatupad ng serbisyo. Maaari mong isipin na kinokontrol ng mga patakaran ng network ang pag-access sa mga serbisyo, ngunit hindi ito ang kaso. Gumagana ang mga patakaran sa network ng Kubernetes sa mga pod port, hindi sa mga service port.

Halimbawa, kung ang isang serbisyo ay nakikinig sa port 80, ngunit nagre-redirect ng trapiko sa port 8080 ng mga pod nito, dapat mong tukuyin ang eksaktong 8080 sa patakaran ng network.

Ang ganitong mekanismo ay dapat ituring na suboptimal: kung ang panloob na istraktura ng serbisyo (ang mga port kung saan nakikinig ang mga pod) ay nagbabago, ang mga patakaran sa network ay kailangang i-update.

Bagong diskarte sa arkitektura gamit ang Service Mesh (halimbawa, tingnan ang tungkol sa Istio sa ibaba - tinatayang transl.) nagbibigay-daan sa iyo upang makayanan ang problemang ito.

Kailangan bang irehistro ang Ingress at Egress?

Ang maikling sagot ay oo, para makipag-ugnayan ang pod A sa pod B, dapat itong pahintulutan na lumikha ng papalabas na koneksyon (para dito kailangan mong mag-configure ng patakaran sa paglabas), at dapat na tanggapin ng pod B ang isang papasok na koneksyon ( para dito, nang naaayon, kailangan mo ng patakaran sa pagpasok). patakaran).

Gayunpaman, sa pagsasagawa, maaari kang umasa sa default na patakaran upang payagan ang mga koneksyon sa isa o parehong direksyon.

Kung ilang pod-pinagmulan pipiliin ng isa o higit pa palabas-mga pulitiko, ang mga paghihigpit na ipapataw dito ay matutukoy ng kanilang disjunction. Sa kasong ito, kakailanganin mong tahasang payagan ang koneksyon sa pod -sa addressee. Kung ang isang pod ay hindi pinili ng anumang patakaran, ang papalabas na (paglabas) na trapiko nito ay pinapayagan bilang default.

Katulad nito, ang kapalaran ng pod ayaddressee, pinili ng isa o higit pa pagpasok-mga pulitiko, matutukoy sa kanilang disjunction. Sa kasong ito, dapat mong tahasan itong payagan na makatanggap ng trapiko mula sa source pod. Kung ang isang pod ay hindi pinili ng anumang patakaran, ang lahat ng trapiko sa pagpasok para dito ay pinapayagan bilang default.

Tingnan ang Stateful o Stateless sa ibaba.

Mga log

Ang mga patakaran sa network ng Kubernetes ay hindi makapag-log ng trapiko. Ginagawa nitong mahirap na matukoy kung gumagana ang isang patakaran ayon sa nilalayon at lubos na nagpapalubha ng pagsusuri sa seguridad.

Kontrol ng trapiko sa mga panlabas na serbisyo

Hindi ka pinapayagan ng mga patakaran sa network ng Kubernetes na tumukoy ng isang ganap na kwalipikadong pangalan ng domain (DNS) sa mga seksyon ng paglabas. Ang katotohanang ito ay humahantong sa malaking abala kapag sinusubukang limitahan ang trapiko sa mga panlabas na destinasyon na walang nakapirming IP address (gaya ng aws.com).

Pagsusuri ng Patakaran

Babalaan ka ng mga firewall o kahit na tumanggi na tanggapin ang maling patakaran. Gumagawa din ang Kubernetes ng ilang pag-verify. Kapag nagtatakda ng patakaran sa network sa pamamagitan ng kubectl, maaaring ideklara ng Kubernetes na ito ay hindi tama at tumangging tanggapin ito. Sa ibang mga kaso, kukunin ng Kubernetes ang patakaran at pupunan ito ng mga nawawalang detalye. Makikita ang mga ito gamit ang command:

kubernetes get networkpolicy <policy-name> -o yaml

Tandaan na ang sistema ng pagpapatunay ng Kubernetes ay hindi nagkakamali at maaaring makaligtaan ang ilang uri ng mga error.

Pagpapatupad

Ang Kubernetes ay hindi mismo nagpapatupad ng mga patakaran sa network, ngunit isa lamang itong gateway ng API na naglalaan ng pasanin ng kontrol sa isang pinagbabatayan na sistema na tinatawag na Container Networking Interface (CNI). Ang pagtatakda ng mga patakaran sa isang cluster ng Kubernetes nang hindi nagtatalaga ng naaangkop na CNI ay kapareho ng paggawa ng mga patakaran sa isang server ng pamamahala ng firewall nang hindi ini-install ang mga ito sa mga firewall. Nasa sa iyo na tiyaking mayroon kang disenteng CNI o, sa kaso ng mga platform ng Kubernetes, naka-host sa cloud (makikita mo ang listahan ng mga provider dito β€” tinatayang. trans.), paganahin ang mga patakaran sa network na magtatakda ng CNI para sa iyo.

Tandaan na hindi ka babalaan ng Kubernetes kung magtatakda ka ng patakaran sa network nang walang naaangkop na helper na CNI.

Stateful o Stateless?

Ang lahat ng Kubernetes CNI na nakatagpo ko ay stateful (halimbawa, ang Calico ay gumagamit ng Linux conntrack). Nagbibigay-daan ito sa pod na makatanggap ng mga tugon sa koneksyon ng TCP na sinimulan nito nang hindi na kailangang muling itatag ito. Gayunpaman, hindi ko alam ang isang pamantayan ng Kubernetes na maggagarantiya ng statefulness.

Advanced na Pamamahala sa Patakaran sa Seguridad

Narito ang ilang paraan para mapahusay ang pagpapatupad ng patakaran sa seguridad sa Kubernetes:

  1. Gumagamit ang pattern ng arkitektura ng Service Mesh ng mga sidecar container upang magbigay ng detalyadong telemetry at kontrol sa trapiko sa antas ng serbisyo. Bilang halimbawa ay maaari nating kunin Istio.
  2. Pinalawak ng ilan sa mga vendor ng CNI ang kanilang mga tool upang lumampas sa mga patakaran sa network ng Kubernetes.
  3. Tufin Orca Nagbibigay ng visibility at automation ng mga patakaran sa network ng Kubernetes.

Ang pakete ng Tufin Orca ay namamahala sa mga patakaran sa network ng Kubernetes (at ang pinagmulan ng mga screenshot sa itaas).

karagdagang impormasyon

Konklusyon

Ang mga patakaran sa network ng Kubernetes ay nag-aalok ng magandang hanay ng mga tool para sa pagse-segment ng mga cluster, ngunit ang mga ito ay hindi intuitive at may maraming mga subtleties. Dahil sa pagiging kumplikadong ito, naniniwala ako na maraming umiiral na mga patakaran ng cluster ay maraming surot. Kabilang sa mga posibleng solusyon sa problemang ito ang pag-automate ng mga kahulugan ng patakaran o paggamit ng iba pang tool sa pagse-segment.

Umaasa akong makakatulong ang gabay na ito sa pag-alis ng ilang tanong at pagresolba sa mga isyu na maaari mong makaharap.

PS mula sa tagasalin

Basahin din sa aming blog:

Pinagmulan: www.habr.com

Magdagdag ng komento