Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Catatan. terjemah: Pengarang artikel, Reuven Harrison, mempunyai lebih 20 tahun pengalaman dalam pembangunan perisian, dan hari ini ialah CTO dan pengasas bersama Tufin, sebuah syarikat yang mencipta penyelesaian pengurusan dasar keselamatan. Walaupun beliau melihat dasar rangkaian Kubernetes sebagai alat yang agak berkuasa untuk pembahagian rangkaian dalam kelompok, beliau juga percaya bahawa dasar rangkaian Kubernetes tidak begitu mudah untuk dilaksanakan dalam amalan. Bahan ini (agak besar) bertujuan untuk meningkatkan kesedaran pakar tentang isu ini dan membantu mereka membuat konfigurasi yang diperlukan.

Hari ini, banyak syarikat semakin memilih Kubernetes untuk menjalankan aplikasi mereka. Minat terhadap perisian ini sangat tinggi sehingga ada yang memanggil Kubernetes "sistem pengendalian baharu untuk pusat data." Secara beransur-ansur, Kubernetes (atau k8s) mula dilihat sebagai bahagian penting dalam perniagaan, yang memerlukan organisasi proses perniagaan yang matang, termasuk keselamatan rangkaian.

Bagi profesional keselamatan yang hairan dengan bekerja dengan Kubernetes, pendedahan sebenar mungkin dasar lalai platform: benarkan segala-galanya.

Panduan ini akan membantu anda memahami struktur dalaman dasar rangkaian; memahami bagaimana ia berbeza daripada peraturan untuk tembok api biasa. Ia juga akan merangkumi beberapa masalah dan memberikan cadangan untuk membantu mengamankan aplikasi pada Kubernetes.

Dasar rangkaian Kubernetes

Mekanisme dasar rangkaian Kubernetes membolehkan anda mengurus interaksi aplikasi yang digunakan pada platform pada lapisan rangkaian (yang ketiga dalam model OSI). Dasar rangkaian kekurangan beberapa ciri lanjutan tembok api moden, seperti penguatkuasaan OSI Layer 7 dan pengesanan ancaman, tetapi ia menyediakan tahap asas keselamatan rangkaian yang merupakan titik permulaan yang baik.

Dasar rangkaian mengawal komunikasi antara pod

Beban kerja dalam Kubernetes diagihkan ke seluruh pod, yang terdiri daripada satu atau lebih bekas yang digunakan bersama. Kubernetes memberikan setiap pod alamat IP yang boleh diakses daripada pod lain. Dasar rangkaian Kubernetes menetapkan hak akses untuk kumpulan pod dengan cara yang sama seperti kumpulan keselamatan dalam awan digunakan untuk mengawal akses kepada tika mesin maya.

Menentukan Dasar Rangkaian

Seperti sumber Kubernetes lain, dasar rangkaian ditentukan dalam YAML. Dalam contoh di bawah, aplikasi balance akses kepada 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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

(Catatan. terjemah: tangkapan skrin ini, seperti semua yang serupa berikutnya, dibuat bukan menggunakan alat Kubernetes asli, tetapi menggunakan alat Tufin Orca, yang dibangunkan oleh syarikat pengarang artikel asal dan yang disebut pada akhir bahan.)

Untuk menentukan dasar rangkaian anda sendiri, anda memerlukan pengetahuan asas tentang YAML. Bahasa ini berdasarkan lekukan (ditentukan oleh ruang dan bukannya tab). Unsur inden tergolong dalam unsur inden yang terdekat di atasnya. Elemen senarai baharu bermula dengan tanda sempang, semua elemen lain mempunyai bentuk nilai kunci.

Setelah menerangkan dasar dalam YAML, gunakan kubectluntuk menciptanya dalam kelompok:

kubectl create -f policy.yaml

Spesifikasi Dasar Rangkaian

Spesifikasi dasar rangkaian Kubernetes merangkumi empat elemen:

  1. podSelector: mentakrifkan pod yang terjejas oleh dasar ini (sasaran) - diperlukan;
  2. policyTypes: menunjukkan jenis dasar yang disertakan dalam ini: kemasukan dan/atau jalan keluar - pilihan, tetapi saya syorkan untuk menyatakannya secara eksplisit dalam semua kes;
  3. ingress: mentakrifkan dibenarkan masuk trafik ke pod sasaran adalah pilihan;
  4. egress: mentakrifkan dibenarkan keluar trafik dari pod sasaran adalah pilihan.

Contoh diambil dari laman web Kubernetes (saya menggantikan role pada app), menunjukkan bagaimana keempat-empat elemen digunakan:

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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan
Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Sila ambil perhatian bahawa keempat-empat elemen tidak perlu disertakan. Ia hanya wajib podSelector, parameter lain boleh digunakan seperti yang dikehendaki.

Jika anda tinggalkan policyTypes, dasar tersebut akan ditafsirkan seperti berikut:

  • Secara lalai, diandaikan bahawa ia mentakrifkan bahagian kemasukan. Jika dasar tidak menyatakan perkara ini secara eksplisit, sistem akan menganggap bahawa semua trafik adalah dilarang.
  • Tingkah laku di bahagian jalan keluar akan ditentukan oleh kehadiran atau ketiadaan parameter jalan keluar yang sepadan.

Untuk mengelakkan kesilapan saya syorkan sentiasa jelaskan policyTypes.

Mengikut logik di atas, jika parameter ingress dan / atau egress diabaikan, dasar ini akan menafikan semua trafik (lihat "Peraturan Pelucutan" di bawah).

Dasar lalai ialah Benarkan

Jika tiada dasar ditentukan, Kubernetes membenarkan semua trafik secara lalai. Semua pod boleh bertukar-tukar maklumat secara bebas sesama mereka. Ini mungkin kelihatan berlawanan dengan intuisi dari perspektif keselamatan, tetapi ingat bahawa Kubernetes pada asalnya direka oleh pembangun untuk mendayakan saling kendalian aplikasi. Dasar rangkaian telah ditambahkan kemudian.

Ruang nama

Ruang nama ialah mekanisme kerjasama Kubernetes. Ia direka untuk mengasingkan persekitaran logik antara satu sama lain, manakala komunikasi antara ruang dibenarkan secara lalai.

Seperti kebanyakan komponen Kubernetes, dasar rangkaian hidup dalam ruang nama tertentu. Dalam blok metadata anda boleh menentukan ruang yang dimiliki oleh dasar tersebut:

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

Jika ruang nama tidak dinyatakan secara eksplisit dalam metadata, sistem akan menggunakan ruang nama yang dinyatakan dalam kubectl (secara lalai namespace=default):

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

Saya cadangkan nyatakan ruang nama secara eksplisit, melainkan anda menulis dasar yang menyasarkan berbilang ruang nama sekaligus.

Rendah unsur podSelector dalam dasar akan memilih pod daripada ruang nama yang menjadi milik dasar (ia dinafikan akses kepada pod daripada ruang nama lain).

Begitu juga, podSelectors dalam blok masuk dan keluar hanya boleh memilih pod daripada ruang nama mereka sendiri, melainkan sudah tentu anda menggabungkannya dengannya namespaceSelector (ini akan dibincangkan dalam bahagian "Tapis mengikut ruang nama dan pod").

Peraturan Penamaan Dasar

Nama dasar adalah unik dalam ruang nama yang sama. Tidak boleh ada dua dasar dengan nama yang sama dalam ruang yang sama, tetapi boleh ada dasar dengan nama yang sama dalam ruang yang berbeza. Ini berguna apabila anda ingin memohon semula dasar yang sama merentas berbilang ruang.

Saya sangat suka salah satu kaedah penamaan. Ia terdiri daripada menggabungkan nama ruang nama dengan pod sasaran. Sebagai contoh:

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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Label

Anda boleh melampirkan label tersuai pada objek Kubernetes, seperti pod dan ruang nama. Label (label - tag) adalah setara dengan tag dalam awan. Dasar rangkaian Kubernetes menggunakan label untuk memilih buah polongyang mereka gunakan:

podSelector:
  matchLabels:
    role: db

… atau ruang namayang mereka gunakan. Contoh ini memilih semua pod dalam ruang nama dengan label yang sepadan:

namespaceSelector:
  matchLabels:
    project: myproject

Satu amaran: apabila menggunakan namespaceSelector pastikan ruang nama yang anda pilih mengandungi label yang betul. Sedar bahawa ruang nama terbina dalam seperti default ΠΈ kube-system, secara lalai tidak mengandungi label.

Anda boleh menambah label pada ruang seperti ini:

kubectl label namespace default namespace=default

Pada masa yang sama, ruang nama dalam bahagian metadata hendaklah merujuk kepada nama ruang sebenar, bukan label:

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

Sumber dan destinasi

Dasar firewall terdiri daripada peraturan dengan sumber dan destinasi. Dasar rangkaian Kubernetes ditakrifkan untuk sasaran - satu set pod yang digunakan - dan kemudian menetapkan peraturan untuk trafik masuk dan/atau keluar. Dalam contoh kami, sasaran dasar ialah semua pod dalam ruang nama default dengan label dengan kunci app dan makna 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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan
Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Subseksyen ingress dalam dasar ini, membuka trafik masuk ke pod sasaran. Dalam erti kata lain, kemasukan ialah sumber dan sasaran ialah destinasi yang sepadan. Begitu juga, jalan keluar adalah destinasi dan sasaran adalah sumbernya.

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Ini bersamaan dengan dua peraturan firewall: Ingress β†’ Target; Matlamat β†’ Keluar.

Egress dan DNS (penting!)

Dengan mengehadkan lalu lintas keluar, memberi perhatian khusus kepada DNS - Kubernetes menggunakan perkhidmatan ini untuk memetakan perkhidmatan kepada alamat IP. Sebagai contoh, dasar berikut tidak akan berfungsi kerana anda tidak membenarkan permohonan itu balance akses 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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Anda boleh membetulkannya dengan membuka akses kepada perkhidmatan 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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Elemen terakhir to kosong, dan oleh itu ia secara tidak langsung memilih semua pod dalam semua ruang nama, membenarkan balance hantar pertanyaan DNS kepada perkhidmatan Kubernetes yang sesuai (biasanya dijalankan dalam ruang kube-system).

Pendekatan ini berfungsi, walau bagaimanapun ia terlalu permisif dan tidak selamat, kerana ia membenarkan pertanyaan DNS diarahkan ke luar kluster.

Anda boleh memperbaikinya dalam tiga langkah berturut-turut.

1. Benarkan pertanyaan DNS sahaja dalam kelompok dengan menambah 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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

2. Benarkan pertanyaan DNS dalam ruang nama sahaja kube-system.

Untuk melakukan ini, anda perlu menambah label pada ruang nama kube-system: kubectl label namespace kube-system namespace=kube-system - dan tuliskannya dalam polisi menggunakan 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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

3. Orang paranoid boleh pergi lebih jauh dan mengehadkan pertanyaan DNS kepada perkhidmatan DNS tertentu dalam kube-system. Bahagian "Tapis mengikut ruang nama dan pod" akan memberitahu anda cara untuk mencapai ini.

Pilihan lain ialah menyelesaikan DNS pada peringkat ruang nama. Dalam kes ini, ia tidak perlu dibuka untuk setiap perkhidmatan:

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

kosong podSelector memilih semua pod dalam ruang nama.

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Perlawanan pertama dan susunan peraturan

Dalam tembok api konvensional, tindakan (Benarkan atau Tolak) pada paket ditentukan oleh peraturan pertama yang dipenuhi. Dalam Kubernetes, susunan dasar tidak penting.

Secara lalai, apabila tiada dasar ditetapkan, komunikasi antara pod dibenarkan dan mereka boleh bertukar maklumat secara bebas. Sebaik sahaja anda mula merumuskan dasar, setiap pod yang terjejas oleh sekurang-kurangnya satu daripadanya akan diasingkan mengikut percanggahan (logik ATAU) semua dasar yang memilihnya. Pod yang tidak terjejas oleh sebarang dasar kekal terbuka.

Anda boleh menukar tingkah laku ini menggunakan peraturan pelucutan.

Peraturan pelucutan (β€œNafi”)

Dasar firewall biasanya menafikan sebarang trafik yang tidak dibenarkan secara jelas.

Tiada tindakan dinafikan dalam Kubernetes, walau bagaimanapun, kesan yang serupa boleh dicapai dengan dasar biasa (permisif) dengan memilih kumpulan kosong pod sumber (masuk):

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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Dasar ini memilih semua pod dalam ruang nama dan meninggalkan kemasukan tidak ditentukan, menafikan semua trafik masuk.

Dengan cara yang sama, anda boleh menyekat semua trafik keluar dari ruang nama:

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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Sila ambil perhatian bahawa sebarang dasar tambahan yang membenarkan trafik ke pod dalam ruang nama akan diutamakan daripada peraturan ini (sama seperti menambah peraturan membenarkan sebelum peraturan penafian dalam konfigurasi tembok api).

Benarkan segala-galanya (Any-Any-Any-Allow)

Untuk membuat dasar Benarkan Semua, anda perlu menambah dasar Tolak di atas dengan elemen kosong ingress:

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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Ia membenarkan akses daripada semua pod dalam semua ruang nama (dan semua IP) ke mana-mana pod dalam ruang nama default. Tingkah laku ini didayakan secara lalai, jadi ia biasanya tidak perlu ditakrifkan lagi. Walau bagaimanapun, kadangkala anda mungkin perlu melumpuhkan sementara beberapa kebenaran khusus untuk mendiagnosis masalah.

Peraturan boleh dikecilkan untuk membenarkan akses sahaja kepada satu set buah tertentu (app:balance) dalam ruang nama default:

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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Dasar berikut membenarkan semua trafik masuk dan keluar, termasuk akses kepada mana-mana IP di luar kelompok:

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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan
Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Menggabungkan Pelbagai Dasar

Dasar digabungkan menggunakan logik ATAU pada tiga peringkat; Kebenaran setiap pod ditetapkan mengikut percanggahan semua dasar yang mempengaruhinya:

1. Di ladang from ΠΈ to Tiga jenis elemen boleh ditakrifkan (semuanya digabungkan menggunakan OR):

  • namespaceSelector β€” memilih keseluruhan ruang nama;
  • podSelector β€” memilih pod;
  • ipBlock β€” memilih subnet.

Selain itu, bilangan elemen (walaupun sama) dalam subseksyen from/to tidak terhad. Kesemuanya akan digabungkan dengan OR logik.

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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

2. Di dalam bahagian polisi ingress boleh mempunyai banyak unsur from (digabungkan dengan logik ATAU). Begitu juga bahagian egress mungkin mengandungi banyak elemen to (juga digabungkan dengan 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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

3. Dasar yang berbeza juga digabungkan dengan OR logik

Tetapi apabila menggabungkannya, terdapat satu batasan menegaskan Chris Cooney: Kubernetes hanya boleh menggabungkan dasar dengan berbeza policyTypes (Ingress atau Egress). Dasar yang mentakrifkan masuk (atau keluar) akan menimpa satu sama lain.

Hubungan antara ruang nama

Secara lalai, perkongsian maklumat antara ruang nama dibenarkan. Ini boleh diubah dengan menggunakan dasar penafian yang akan menyekat trafik keluar dan/atau masuk ke ruang nama (lihat "Peraturan Pelucutan" di atas).

Sebaik sahaja anda telah menyekat akses kepada ruang nama (lihat "Peraturan Pelucutan" di atas), anda boleh membuat pengecualian kepada dasar penafian dengan membenarkan sambungan daripada ruang nama tertentu menggunakan 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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Akibatnya, semua pod dalam ruang nama default akan mempunyai akses kepada pod postgres dalam ruang nama database. Tetapi bagaimana jika anda ingin membuka akses kepada postgres hanya pod tertentu dalam ruang nama default?

Tapis mengikut ruang nama dan pod

Kubernetes versi 1.11 dan lebih tinggi membolehkan anda menggabungkan pengendali namespaceSelector ΠΈ podSelector menggunakan logik DAN. Ia kelihatan seperti ini:

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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Mengapa ini ditafsirkan sebagai DAN bukannya OR biasa?

Sila ambil perhatian bahawa podSelector tidak bermula dengan tanda sempang. Dalam YAML ini bermakna itu podSelector dan berdiri di hadapannya namespaceSelector rujuk elemen senarai yang sama. Oleh itu, mereka digabungkan dengan logik DAN.

Menambah tanda sempang sebelum ini podSelector akan mengakibatkan kemunculan elemen senarai baharu, yang akan digabungkan dengan yang sebelumnya namespaceSelector menggunakan logik ATAU.

Untuk memilih pod dengan label tertentu dalam semua ruang nama, masukkan kosong 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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Berbilang label bekerjasama dengan I

Peraturan untuk tembok api dengan berbilang objek (hos, rangkaian, kumpulan) digabungkan menggunakan OR logik. Peraturan berikut akan berfungsi jika sumber paket sepadan Host_1 Atau Host_2:

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

Sebaliknya, dalam Kubernetes pelbagai label dalam podSelector atau namespaceSelector digabungkan dengan logik DAN. Contohnya, peraturan berikut akan memilih pod yang mempunyai kedua-dua label, role=db И version=v2:

podSelector:
  matchLabels:
    role: db
    version: v2

Logik yang sama digunakan untuk semua jenis operator: pemilih sasaran dasar, pemilih pod dan pemilih ruang nama.

Subnet dan alamat IP (IPBlocks)

Firewall menggunakan VLAN, alamat IP dan subnet untuk membahagikan rangkaian.

Dalam Kubernetes, alamat IP diberikan kepada pod secara automatik dan boleh berubah dengan kerap, jadi label digunakan untuk memilih pod dan ruang nama dalam dasar rangkaian.

Subnet (ipBlocks) digunakan apabila menguruskan sambungan masuk (masuk) atau keluar (keluar) luaran (Utara-Selatan). Sebagai contoh, dasar ini terbuka kepada semua pod daripada ruang nama default akses kepada perkhidmatan DNS Google:

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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Pemilih pod kosong dalam contoh ini bermaksud "pilih semua pod dalam ruang nama."

Dasar ini hanya membenarkan akses kepada 8.8.8.8; akses kepada mana-mana IP lain adalah dilarang. Jadi, pada dasarnya, anda telah menyekat akses kepada perkhidmatan DNS Kubernetes dalaman. Jika anda masih mahu membukanya, nyatakan ini dengan jelas.

Biasanya ipBlocks ΠΈ podSelectors adalah saling eksklusif, kerana alamat IP dalaman pod tidak digunakan ipBlocks. Dengan menunjukkan pod IP dalaman, anda sebenarnya akan membenarkan sambungan ke/daripada pod dengan alamat ini. Dalam amalan, anda tidak akan tahu alamat IP yang hendak digunakan, itulah sebabnya ia tidak sepatutnya digunakan untuk memilih pod.

Sebagai contoh balas, dasar berikut merangkumi semua IP dan oleh itu membenarkan akses kepada semua pod lain:

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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Anda boleh membuka akses hanya kepada IP luaran, tidak termasuk alamat IP dalaman pod. Contohnya, jika subnet pod anda ialah 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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Pelabuhan dan protokol

Biasanya, pod mendengar satu port. Ini bermakna anda tidak boleh menentukan nombor port dalam dasar dan membiarkan semuanya sebagai lalai. Walau bagaimanapun, adalah disyorkan untuk membuat dasar sehad yang mungkin, jadi dalam beberapa kes anda masih boleh menentukan 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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Perhatikan bahawa pemilih ports terpakai kepada semua elemen dalam blok to atau from, yang mengandungi. Untuk menentukan port yang berbeza untuk set elemen yang berbeza, belah ingress atau egress kepada beberapa subseksyen dengan to atau from dan dalam setiap daftar port anda:

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

Pengenalan kepada Dasar Rangkaian Kubernetes untuk Profesional Keselamatan

Operasi pelabuhan lalai:

  • Jika anda meninggalkan definisi port sepenuhnya (ports), ini bermakna semua protokol dan semua port;
  • Jika anda meninggalkan definisi protokol (protocol), ini bermakna TCP;
  • Jika anda meninggalkan definisi port (port), ini bermakna semua port.

Amalan terbaik: Jangan bergantung pada nilai lalai, nyatakan perkara yang anda perlukan dengan jelas.

Sila ambil perhatian bahawa anda mesti menggunakan port pod, bukan port perkhidmatan (lebih lanjut mengenai perkara ini dalam perenggan seterusnya).

Adakah dasar ditakrifkan untuk pod atau perkhidmatan?

Biasanya, pod dalam Kubernetes mengakses satu sama lain melalui perkhidmatan - pengimbang beban maya yang mengubah hala trafik ke pod yang melaksanakan perkhidmatan. Anda mungkin berfikir bahawa dasar rangkaian mengawal akses kepada perkhidmatan, tetapi ini tidak berlaku. Dasar rangkaian Kubernetes berfungsi pada port pod, bukan port perkhidmatan.

Contohnya, jika perkhidmatan mendengar port 80, tetapi mengubah hala trafik ke port 8080 podnya, tepat 8080 mesti dinyatakan dalam dasar rangkaian.

Mekanisme sedemikian harus dianggap sebagai suboptimum: jika struktur dalaman perkhidmatan (port yang pod mendengar) berubah, dasar rangkaian perlu dikemas kini.

Pendekatan seni bina baharu menggunakan Service Mesh (contohnya, lihat tentang Istio di bawah - lebih kurang transl.) membolehkan anda mengatasi masalah ini.

Adakah perlu mendaftar kedua-dua Ingress dan Egress?

Jawapan ringkasnya ialah ya, untuk pod A berkomunikasi dengan pod B, ia mesti dibenarkan membuat sambungan keluar (untuk ini anda perlu mengkonfigurasi dasar keluar), dan pod B mesti boleh menerima sambungan masuk ( untuk ini, sewajarnya, anda memerlukan polisi kemasukan). polisi).

Walau bagaimanapun, dalam amalan, anda boleh bergantung pada dasar lalai untuk membenarkan sambungan dalam satu atau kedua-dua arah.

Jika beberapa pod-sumber akan dipilih oleh satu atau lebih jalan keluar-ahli politik, sekatan yang dikenakan ke atasnya akan ditentukan oleh disjunction mereka. Dalam kes ini, anda perlu membenarkan sambungan ke pod secara eksplisit -kepada penerima. Jika pod tidak dipilih oleh mana-mana dasar, trafik keluar (keluar) dibenarkan secara lalai.

Begitu juga nasib podpenerima, dipilih oleh satu atau lebih kemasukan-ahli politik, akan ditentukan oleh disjunction mereka. Dalam kes ini, anda mesti membenarkannya secara eksplisit menerima trafik daripada pod sumber. Jika pod tidak dipilih oleh mana-mana dasar, semua trafik kemasukan untuknya dibenarkan secara lalai.

Lihat Stateful atau Stateless di bawah.

Log

Dasar rangkaian Kubernetes tidak boleh log trafik. Ini menyukarkan untuk menentukan sama ada sesuatu dasar itu berfungsi seperti yang dimaksudkan dan sangat merumitkan analisis keselamatan.

Kawalan trafik ke perkhidmatan luar

Dasar rangkaian Kubernetes tidak membenarkan anda menentukan nama domain (DNS) yang layak sepenuhnya dalam bahagian jalan keluar. Fakta ini membawa kepada kesulitan yang ketara apabila cuba mengehadkan trafik ke destinasi luaran yang tidak mempunyai alamat IP tetap (seperti aws.com).

Semakan Polisi

Firewall akan memberi amaran kepada anda atau enggan menerima dasar yang salah. Kubernetes juga melakukan beberapa pengesahan. Apabila menetapkan dasar rangkaian melalui kubectl, Kubernetes mungkin mengisytiharkan bahawa ia tidak betul dan enggan menerimanya. Dalam kes lain, Kubernetes akan mengambil polisi dan mengisinya dengan butiran yang tiada. Mereka boleh dilihat menggunakan arahan:

kubernetes get networkpolicy <policy-name> -o yaml

Perlu diingat bahawa sistem pengesahan Kubernetes tidak sempurna dan mungkin terlepas beberapa jenis ralat.

Pelaksanaan

Kubernetes tidak melaksanakan dasar rangkaian itu sendiri, tetapi hanyalah gerbang API yang mewakilkan beban kawalan kepada sistem asas yang dipanggil Antara Muka Rangkaian Kontena (CNI). Menetapkan dasar pada gugusan Kubernetes tanpa memperuntukkan CNI yang sesuai adalah sama seperti membuat dasar pada pelayan pengurusan tembok api tanpa memasangnya pada dinding api. Terpulang kepada anda untuk memastikan anda mempunyai CNI yang baik atau, dalam kes platform Kubernetes, dihoskan dalam awan (anda boleh melihat senarai pembekal di sini - lebih kurang trans.), dayakan dasar rangkaian yang akan menetapkan CNI untuk anda.

Harap maklum bahawa Kubernetes tidak akan memberi amaran kepada anda jika anda menetapkan dasar rangkaian tanpa CNI pembantu yang sesuai.

Stateful atau Stateless?

Semua CNI Kubernetes yang saya temui adalah stateful (contohnya, Calico menggunakan conntrack Linux). Ini membolehkan pod menerima respons pada sambungan TCP yang dimulakan tanpa perlu mewujudkannya semula. Walau bagaimanapun, saya tidak mengetahui tentang piawaian Kubernetes yang akan menjamin status kewarganegaraan.

Pengurusan Dasar Keselamatan Lanjutan

Berikut ialah beberapa cara untuk meningkatkan penguatkuasaan dasar keselamatan dalam Kubernetes:

  1. Corak seni bina Service Mesh menggunakan bekas kereta sampingan untuk menyediakan telemetri terperinci dan kawalan trafik pada peringkat perkhidmatan. Sebagai contoh yang boleh kita ambil Istio.
  2. Beberapa vendor CNI telah memperluaskan alatan mereka untuk melangkaui dasar rangkaian Kubernetes.
  3. Tufin Orca Menyediakan keterlihatan dan automasi dasar rangkaian Kubernetes.

Pakej Tufin Orca mengurus dasar rangkaian Kubernetes (dan merupakan sumber tangkapan skrin di atas).

maklumat tambahan

Kesimpulan

Dasar rangkaian Kubernetes menawarkan set alat yang baik untuk membahagikan kelompok, tetapi ia tidak intuitif dan mempunyai banyak kehalusan. Oleh kerana kerumitan ini, saya percaya banyak dasar kluster sedia ada adalah buggy. Penyelesaian yang mungkin untuk masalah ini termasuk mengautomasikan definisi dasar atau menggunakan alat pembahagian lain.

Saya harap panduan ini membantu menyelesaikan beberapa soalan dan menyelesaikan masalah yang mungkin anda hadapi.

PS daripada penterjemah

Baca juga di blog kami:

Sumber: www.habr.com

Tambah komen