Menerapkan kebijakan keamanan tingkat Pod kustom menggunakan Gatekeeper.


Halaman ini menunjukkan cara menggunakan pengontrol penerimaan Gatekeeper untuk menerapkan kontrol keamanan tingkat Pod ke cluster Google Kubernetes Engine (GKE) Anda.

Ringkasan

Gatekeeper adalah pengontrol penerimaan yang memvalidasi permintaan untuk membuat dan memperbarui Pod di cluster Kubernetes, menggunakan Open Policy Agent (OPA).

Dengan Gatekeeper, administrator dapat menentukan kebijakan dengan batasan, yaitu sekumpulan kondisi yang mengizinkan atau menolak perilaku deployment di Kubernetes. Selanjutnya, Anda dapat menerapkan kebijakan ini pada cluster menggunakan ConstraintTemplate. Dokumen ini memberikan contoh pembatasan kapabilitas keamanan workload untuk menerapkan, menguji, dan mengaudit kebijakan keamanan menggunakan Gatekeeper.

Gatekeeper juga dapat:

  • Meluncurkan kebijakan: Menerapkan kebijakan secara bertahap dan berbatas untuk membatasi risiko terganggunya workload.
  • Menguji coba perubahan kebijakan: Memberikan mekanisme untuk menguji dampak dan rentang kebijakan sebelum penerapan.
  • Mengaudit kebijakan yang ada: Memastikan penerapan kontrol keamanan ke workload baru dan yang sudah ada (kontrol audit).

Konsep

Gatekeeper memperkenalkan dua konsep untuk memberi administrator cara andal dan fleksibel dalam mengontrol cluster: batasan dan template batasan, yang keduanya merupakan konsep yang diwarisi dari Framework Batasan Open Policy Agent.

Batasan adalah representasi kebijakan keamanan Anda—batasan menentukan persyaratan dan rentang penerapan. Template batasan adalah pernyataan yang dapat digunakan kembali (ditulis dalam Rego) yang menerapkan logika untuk mengevaluasi kolom tertentu dalam objek Kubernetes, berdasarkan persyaratan yang ditentukan dalam batasan.

Misalnya, Anda mungkin memiliki batasan yang mendeklarasikan profil keamanan yang diizinkan dan dapat diterapkan ke Pod di namespace tertentu, dan template batasan yang setara yang memberikan logika untuk mengekstrak nilai ini dan menangani penerapan.

Template batasan berikut, dari repositori Gatekeeper, memeriksa keberadaan securityContext.privileged dalam spesifikasi Pod:

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8spspprivilegedcontainer
spec:
  crd:
    spec:
      names:
        kind: K8sPSPPrivilegedContainer
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8spspprivileged

        violation[{"msg": msg, "details": {}}] {
            c := input_containers[_]
            c.securityContext.privileged
            msg := sprintf("Privileged container is not allowed: %v, securityContext: %v", [c.name, c.securityContext])
        }
        input_containers[c] {
            c := input.review.object.spec.containers[_]
        }
        input_containers[c] {
            c := input.review.object.spec.initContainers[_]
        }

Untuk memperluas template batasan di atas, batasan berikut menentukan cakupan (kinds) untuk penerapan spesifik template batasan ini dalam mode dryrun:

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPPrivilegedContainer
metadata:
  name: psp-privileged-container
spec:
  enforcementAction: dryrun
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]

Dengan Gatekeeper, Anda dapat membuat batasan dan template batasan sendiri untuk memenuhi kebutuhan spesifik Anda. Anda juga dapat menggunakan serangkaian batasan dan template batasan standar di repositori Gatekeeper yang telah ditentukan untuk memungkinkan penerapan keamanan dan adopsi yang cepat. Setiap batasan juga disertai dengan contoh konfigurasi Pod.

Google Cloud menyediakan versi Gatekeeper open source yang terkelola dan didukung secara resmi yang bernama Pengontrol Kebijakan. Google tidak mendukung project Gatekeeper open source secara resmi.

Sebelum memulai

Sebelum memulai, pastikan Anda telah menjalankan tugas berikut:

  • Aktifkan Google Kubernetes Engine API.
  • Aktifkan Google Kubernetes Engine API
  • Jika ingin menggunakan Google Cloud CLI untuk tugas ini, instal lalu lakukan inisialisasi gcloud CLI. Jika sebelumnya Anda telah menginstal gcloud CLI, dapatkan versi terbaru dengan menjalankan gcloud components update.

Mengaktifkan Gatekeeper di cluster dengan Pengontrol Kebijakan

Pengontrol Kebijakan adalah mesin kebijakan yang dibuat di project open source Gatekeeper. Google merekomendasikan penggunaan Policy Controller karena menyertakan fitur tambahan untuk membantu menerapkan kebijakan dalam skala besar, termasuk kebijakan sebagai kode, dukungan multi-cluster, integrasi dengan Cloud Logging, dan kemampuan untuk melihat status kebijakan di konsol Google Cloud. Pengontrol Kebijakan tersedia dengan lisensi edisi Enterprise Google Kubernetes Engine (GKE), tetapi Anda dapat menginstal Gatekeeper di cluster.

Untuk mengaktifkan Pengontrol Kebijakan di cluster, ikuti panduan penginstalan Pengontrol Kebijakan.

Mengaktifkan batasan dan template batasan

Gatekeeper dan template batasannya dapat diinstal dan diaktifkan tanpa dampak negatif terhadap workload baru atau yang sudah ada. Karena alasan ini, sebaiknya semua template batasan keamanan Pod yang berlaku diterapkan ke cluster.

Selain itu, batasan Gatekeeper dapat diimplementasikan untuk menerapkan kontrol bagi objek tertentu, seperti namespace dan Pod.

Perhatikan contoh di bawah yang membatasi cakupan ke Pod yang berada di namespace production dengan menentukannya di pernyataan pencocokan batasan:

...
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Pod"]
    namespaces:
      - "production"

Untuk informasi selengkapnya tentang opsi yang tersedia untuk objek Constraint dan ConstraintTemplate, lihat Cara menggunakan Gatekeeper.

Kebijakan pengujian

Memperkenalkan kebijakan baru ke cluster yang ada dapat menimbulkan perilaku buruk, misalnya dengan membatasi workload yang ada. Salah satu manfaat menggunakan Gatekeeper untuk keamanan Pod adalah kemampuan untuk menguji efektivitas dan dampak yang akan ditimbulkan kebijakan tanpa membuat perubahan sebenarnya, melalui penggunaan mode uji coba. Hal ini memungkinkan konfigurasi kebijakan diuji terhadap cluster yang berjalan tanpa menerapkan kebijakan tersebut. Pelanggaran kebijakan dicatat dan diidentifikasi tanpa gangguan.

Langkah-langkah berikut menunjukkan bagaimana developer, operator, atau administrator dapat menerapkan batasan dan template batasan untuk menentukan efektivitas atau potensi dampaknya:

  1. Terapkan konfigurasi Gatekeeper guna mereplikasi data untuk fungsionalitas audit dan uji coba:

    kubectl create -f- <<EOF
    apiVersion: config.gatekeeper.sh/v1alpha1
    kind: Config
    metadata:
      name: config
      namespace: "gatekeeper-system"
    spec:
      sync:
        syncOnly:
          - group: ""
            version: "v1"
            kind: "Namespace"
          - group: ""
            version: "v1"
            kind: "Pod"
    EOF
    
  2. Tanpa batasan yang diterapkan, mari kita jalankan workload dengan hak istimewa yang ditingkatkan:

    kubectl create -f- <<EOF
    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        securityContext:
          privileged: true
    EOF
    
  3. Muat template batasan k8spspprivilegedcontainer yang disebutkan di atas:

    kubectl create -f- <<EOF
    apiVersion: templates.gatekeeper.sh/v1beta1
    kind: ConstraintTemplate
    metadata:
      name: k8spspprivilegedcontainer
    spec:
      crd:
        spec:
          names:
            kind: K8sPSPPrivilegedContainer
      targets:
        - target: admission.k8s.gatekeeper.sh
          rego: |
            package k8spspprivileged
    
            violation[{"msg": msg, "details": {}}] {
                c := input_containers[_]
                c.securityContext.privileged
                msg := sprintf("Privileged container is not allowed: %v, securityContext: %v", [c.name, c.securityContext])
            }
            input_containers[c] {
                c := input.review.object.spec.containers[_]
            }
            input_containers[c] {
                c := input.review.object.spec.initContainers[_]
            }
    EOF
    
  4. Sekarang, mari kita buat batasan baru untuk memperluas template batasan ini. Kali ini, kita akan menetapkan enforcementAction ke dryrun:

    kubectl create -f- <<EOF
    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: K8sPSPPrivilegedContainer
    metadata:
      name: psp-privileged-container
    spec:
      enforcementAction: dryrun
      match:
        kinds:
          - apiGroups: [""]
            kinds: ["Pod"]
    EOF
    
  5. Dengan Gatekeeper yang menyinkronkan data objek yang sedang berjalan, serta secara pasif memeriksa keberadaan pelanggaran, kita dapat mengonfirmasi apakah ada pelanggaran yang ditemukan dengan memeriksa status di batasan tersebut:

    kubectl get k8spspprivilegedcontainer.constraints.gatekeeper.sh/psp-privileged-container -o yaml
    
    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: K8sPSPPrivilegedContainer
    metadata:
    ...
     name: psp-privileged-container
    ...
    spec:
     enforcementAction: dryrun
     match:
       kinds:
       - apiGroups:
         - ""
         kinds:
         - Pod
    status:
     auditTimestamp: "2019-12-15T22:19:54Z"
     byPod:
     - enforced: true
       id: gatekeeper-controller-manager-0
     violations:
     - enforcementAction: dryrun
       kind: Pod
       message: 'Privileged container is not allowed: nginx, securityContext: {"privileged":
         true}'
       name: nginx
       namespace: default
    
  6. Mari jalankan Pod dengan hak istimewa lainnya untuk mengonfirmasi bahwa kebijakan tersebut tidak mengganggu deployment:

    kubectl create -f- <<EOF
    apiVersion: v1
    kind: Pod
    metadata:
      name: privpod
      labels:
        app: privpod
    spec:
      containers:
      - name: nginx
        image: nginx
        securityContext:
          privileged: true
    EOF
    

    Pod baru ini akan berhasil di-deploy.

  7. Untuk membersihkan resource yang dibuat di bagian ini, jalankan perintah berikut:

    kubectl delete k8spspprivilegedcontainer.constraints.gatekeeper.sh/psp-privileged-container
    kubectl delete constrainttemplate k8spspprivilegedcontainer
    kubectl delete pod/nginx
    kubectl delete pod/privpod
    

Memberlakukan kebijakan

Setelah dapat mengonfirmasi validitas dan dampak kebijakan tanpa memengaruhi workload baru atau yang sudah ada, sekarang mari kita implementasikan kebijakan dengan penerapan penuh.

Berdasarkan contoh yang digunakan untuk memvalidasi kebijakan di atas, langkah-langkah berikut menunjukkan bagaimana developer, operator, atau administrator dapat menerapkan batasan dan template batasan untuk memberlakukan kebijakan:

  1. Muat template batasan k8spspprivilegedcontainer yang disebutkan sebelumnya:

    kubectl create -f- <<EOF
    apiVersion: templates.gatekeeper.sh/v1beta1
    kind: ConstraintTemplate
    metadata:
      name: k8spspprivilegedcontainer
    spec:
      crd:
        spec:
          names:
            kind: K8sPSPPrivilegedContainer
      targets:
        - target: admission.k8s.gatekeeper.sh
          rego: |
            package k8spspprivileged
    
            violation[{"msg": msg, "details": {}}] {
                c := input_containers[_]
                c.securityContext.privileged
                msg := sprintf("Privileged container is not allowed: %v, securityContext: %v", [c.name, c.securityContext])
            }
            input_containers[c] {
                c := input.review.object.spec.containers[_]
            }
            input_containers[c] {
                c := input.review.object.spec.initContainers[_]
            }
    EOF
    
  2. Sekarang, mari kita buat batasan baru untuk memperluas template batasan ini. Kali ini, kita tidak akan menetapkan kunci enforcementAction. Secara default, kunci enforcementAction ditetapkan ke deny:

    kubectl create -f- <<EOF
    apiVersion: constraints.gatekeeper.sh/v1beta1
    kind: K8sPSPPrivilegedContainer
    metadata:
      name: psp-privileged-container
    spec:
      match:
        kinds:
          - apiGroups: [""]
            kinds: ["Pod"]
    EOF
    
  3. Cobalah men-deploy container yang mendeklarasikan izin dengan hak istimewa:

    kubectl create -f- <<EOF
    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        securityContext:
          privileged: true
    EOF
    

    Pesan error berikut akan muncul:

    Error from server ([denied by psp-privileged-container] Privileged container is not allowed:
    nginx, securityContext: {"privileged": true}): error when creating "STDIN": admission webhook "validation.gatekeeper.sh" denied the request: [denied by psp-privileged-container]
    Privileged container is not allowed: nginx, securityContext: {"privileged": true}
    
  4. Untuk membersihkan, jalankan perintah berikut:

    kubectl delete k8spspprivilegedcontainer.constraints.gatekeeper.sh/psp-privileged-container
    kubectl delete constrainttemplate k8spspprivilegedcontainer
    

Alternatif dari Gatekeeper

Gatekeeper memungkinkan Anda mendeklarasikan dan menerapkan kebijakan keamanan tingkat Pod kustom. Anda juga dapat menggunakan pengontrol penerimaan PodSecurity bawaan Kubernetes untuk menerapkan kebijakan keamanan tingkat Pod yang telah ditetapkan. Kebijakan yang telah ditetapkan ini diselaraskan dengan tingkat yang ditentukan oleh Standar Keamanan Pod.

Langkah berikutnya

Dengan kebijakan deklaratif, Gatekeeper menyediakan cara yang sangat efektif untuk memberlakukan dan memvalidasi keamanan pada cluster GKE. Namun, Gatekeeper juga dapat digunakan selain untuk keperluan keamanan, seperti dalam aspek administrasi dan operasi lainnya.