Ringkasan kebijakan otorisasi

Tidak seperti aplikasi monolitik yang mungkin berjalan di satu tempat, aplikasi microservice yang didistribusikan secara global melakukan panggilan di seluruh batas jaringan. Artinya, ada lebih banyak titik entri ke aplikasi Anda, dan lebih banyak peluang untuk serangan berbahaya. Selain itu, karena pod Kubernetes memiliki IP sementara, aturan firewall berbasis IP tradisional tidak memadai untuk mengamankan akses antar- workload. Dalam arsitektur microservice, pendekatan baru untuk keamanan diperlukan. Dengan fitur keamanan seperti akun layanan Kubernetes dan kebijakan keamanan Istio, Cloud Service Mesh memberikan lebih banyak kemampuan untuk membantu Anda mengamankan aplikasi.

Halaman ini memberikan ringkasan resource kustom (CR) AuthorizationPolicy kepada operator aplikasi. Kebijakan otorisasi memungkinkan Anda mengaktifkan kontrol akses pada beban kerja di lapisan aplikasi (L7) dan transpor (L3/4). Anda mengonfigurasi kebijakan otorisasi untuk menentukan izin—apa yang diizinkan untuk dilakukan oleh layanan atau pengguna ini?

Kebijakan otorisasi

Permintaan antarlayanan dalam mesh Anda (dan antara pengguna akhir dan layanan) diizinkan secara default. Anda menggunakan CR AuthorizationPolicy untuk menentukan kebijakan terperinci untuk beban kerja Anda. Setelah Anda menerapkan kebijakan otorisasi, Cloud Service Mesh mendistribusikannya ke proxy sidecar. Saat permintaan masuk ke workload, proxy sidecar akan memeriksa kebijakan otorisasi untuk menentukan apakah permintaan harus diizinkan atau ditolak.

Cakupan kebijakan

Anda dapat menerapkan kebijakan ke seluruh mesh layanan, ke namespace, atau ke setiap beban kerja.

  • Untuk menerapkan kebijakan seluruh mesh, tentukan namespace root, istio-system, di kolom metadata:namespace:

    apiVersion: "security.istio.io/v1beta1"
    kind: "AuthorizationPolicy"
    metadata:
      name: "mesh-wide"
      namespace: istio-system
    spec:
    ...
    
  • Untuk menerapkan kebijakan ke namespace, tentukan namespace di kolom metadata:namespace:

    apiVersion: "security.istio.io/v1beta1"
    kind: "AuthorizationPolicy"
    metadata:
      name: "currencyservice"
      namespace: currencyservice
    spec:
    ...
    
  • Untuk membatasi kebijakan ke workload tertentu, sertakan kolom selector.

    apiVersion: "security.istio.io/v1beta1"
    kind: "AuthorizationPolicy"
    metadata:
      name: "frontend"
      namespace: demo
    spec:
      selector:
        matchLabels:
          app: frontend
       ...
    

Struktur dasar

Kebijakan otorisasi mencakup cakupan kebijakan, action, dan daftar rules:

  • Seperti yang dijelaskan di bagian sebelumnya, cakupan kebijakan dapat berupa seluruh mesh, namespace, atau beban kerja tertentu. Jika Anda menyertakannya, kolom selector akan menentukan target kebijakan.

  • Kolom action menentukan apakah akan ALLOW atau DENY permintaan. Jika Anda tidak menentukan tindakan, tindakan akan ditetapkan ke ALLOW secara default. Untuk kejelasan, sebaiknya Anda selalu menentukan tindakan. (Kebijakan otorisasi juga mendukung tindakan AUDIT dan CUSTOM.)

  • rules menentukan kapan tindakan akan dipicu.

    • Kolom from di rules menentukan sumber permintaan.

    • Kolom to di rules menentukan operasi permintaan.

    • Kolom when menentukan kondisi tambahan yang diperlukan untuk menerapkan aturan.

Dalam contoh berikut:

  • Kebijakan ini diterapkan ke permintaan ke layanan frontend di namespace demo.

  • Permintaan diizinkan jika "hello:world" ada di header permintaan; jika tidak, permintaan akan ditolak.

apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "hello-world"
  namespace: demo
spec:
  selector:
    matchLabels:
      app: frontend
  action: ALLOW
  rules:
  - when:
    - key: request.headers[hello]
      values: ["world"]

Kontrol akses pada operasi permintaan

Anda dapat mengontrol akses ke operasi permintaan tertentu seperti metode HTTP atau port TCP dengan menambahkan bagian to di bagian rules. Pada contoh berikut, hanya metode HTTP GET dan POST yang diizinkan ke currencyservice di namespace demo.

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: currencyservice
 namespace: demo
spec:
 selector:
   matchLabels:
     app: currencyservice
 action: ALLOW
 rules:
 - to:
   - operation:
       methods: ["GET", "POST"]

Kontrol akses pada identitas yang diautentikasi

Pada contoh sebelumnya, kebijakan mengizinkan permintaan dari beban kerja yang tidak diautentikasi. Jika telah mengaktifkan STRICT mutual TLS (mTLS), Anda dapat membatasi akses berdasarkan identitas workload atau namespace yang menjadi asal permintaan di bagian source.

  • Gunakan kolom principals atau notPrincipal untuk mengontrol akses di tingkat beban kerja.

  • Gunakan kolom namespaces atau notNamespaces untuk mengontrol akses di tingkat namespace.

Semua kolom di atas mengharuskan Anda mengaktifkan mTLS STRICT. Jika Anda tidak dapat menetapkan mTLS STRICT, lihat Menolak permintaan teks biasa untuk mengetahui solusi alternatif.

Workload yang diidentifikasi

Pada contoh berikut, permintaan ke currencyservice hanya diizinkan dari layanan frontend. Permintaan ke currencyservice dari beban kerja lainnya ditolak.

apiVersion: "security.istio.io/v1beta1"
kind: "AuthorizationPolicy"
metadata:
  name: "currencyservice"
  namespace: demo
spec:
  selector:
    matchLabels:
      app: currencyservice
  action: ALLOW
  rules:
  - from:
    - source:
        principals: ["example-project-1234.svc.id.goog/ns/demo/sa/frontend-sa"]

Untuk menentukan akun layanan, principals untuk otoritas sertifikasi Cloud Service Mesh (Mesh CA) dan Layanan Otoritas Sertifikasi (Layanan CA) harus dalam format berikut:

principals: ["PROJECT_ID.svc.id.goog/ns/NAMESPACE/sa/SERVICE_ACCOUNT_NAME"]

PROJECT_ID.svc.id.goog adalah domain kepercayaan untuk CA Mesh. Jika Anda menggunakan CA Istio (sebelumnya dikenal sebagai Citadel), domain kepercayaan default-nya adalah cluster.local.

Namespace yang diidentifikasi

Contoh berikut menunjukkan kebijakan yang menolak permintaan jika sumbernya bukan namespace foo:

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
 name: httpbin-deny
 namespace: foo
spec:
 selector:
   matchLabels:
     app: httpbin
     version: v1
 action: DENY
 rules:
 - from:
   - source:
       notNamespaces: ["foo"]

Pencocokan nilai

Sebagian besar kolom dalam kebijakan otorisasi mendukung semua skema pencocokan berikut:

  • Pencocokan persis: pencocokan string yang sama persis.
  • Pencocokan karakter pengganti menggunakan karakter pengganti "*":
    • Pencocokan awalan: string dengan akhiran "*". Misalnya, "test.example.*" cocok dengan "test.example.com" atau "test.example.com.cn".
    • Kecocokan akhiran: string dengan "*" awal. Misalnya, "*.example.com" cocok dengan "eng.example.com" atau "test.eng.example.com".
  • Kecocokan kehadiran: Untuk menentukan bahwa kolom harus ada dan tidak kosong, gunakan format fieldname: ["*"]. Hal ini berbeda dengan membiarkan kolom tidak ditentukan, yang berarti cocok dengan apa pun, termasuk kosong.

Ada beberapa pengecualian. Misalnya, kolom berikut hanya mendukung pencocokan persis:

  • Kolom key di bagian when
  • ipBlocks di bagian source
  • Kolom ports di bagian to

Contoh kebijakan berikut mengizinkan akses di jalur dengan awalan /test/* atau akhiran */info:

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: tester
  namespace: default
spec:
  selector:
    matchLabels:
      app: products
  action: ALLOW
  rules:
  - to:
    - operation:
        paths: ["/test/*", "*/info"]

Pencocokan pengecualian

Untuk mencocokkan kondisi negatif seperti notValues di kolom when, notIpBlocks di kolom source, notPorts di kolom to, Cloud Service Mesh mendukung pencocokan pengecualian. Contoh berikut memerlukan permintaan principals yang valid, yang berasal dari autentikasi JWT, jika jalur permintaan bukan /healthz. Dengan demikian, kebijakan mengecualikan permintaan ke jalur /healthz dari autentikasi JWT:

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: disable-jwt-for-healthz
  namespace: default
spec:
  selector:
    matchLabels:
      app: products
  action: ALLOW
  rules:
  - to:
    - operation:
        notPaths: ["/healthz"]
    from:
    - source:
        requestPrincipals: ["*"]

Menolak permintaan teks biasa

Di Cloud Service Mesh, mTLS otomatis diaktifkan secara default. Dengan mTLS otomatis, proxy sidecar klien akan otomatis mendeteksi apakah server memiliki sidecar. Sidecar klien mengirim mTLS ke workload dengan sidecar dan mengirim teks biasa ke workload tanpa sidecar. Untuk keamanan terbaik, sebaiknya Anda mengaktifkan mTLS STRICT.

Jika tidak dapat mengaktifkan mTLS dengan mode STRICT untuk beban kerja atau namespace, Anda dapat:

  • membuat kebijakan otorisasi untuk mengizinkan traffic secara eksplisit dengan namespaces yang tidak kosong atau principals yang tidak kosong, atau
  • menolak traffic dengan namespaces atau principals kosong.

Karena namespaces dan principals hanya dapat diekstrak dengan permintaan mTLS, kebijakan ini secara efektif menolak traffic teks biasa.

Kebijakan berikut menolak permintaan jika akun utama dalam permintaan kosong (yang berlaku untuk permintaan teks biasa). Kebijakan ini mengizinkan permintaan jika akun utama tidak kosong. ["*"] berarti pencocokan yang tidak kosong, dan penggunaan dengan notPrincipals berarti pencocokan pada akun utama kosong.

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: require-mtls
  namespace: NAMESPACE
spec:
  action: DENY
  rules:
  - from:
    - source:
        notPrincipals: ["*"]

Prioritas kebijakan otorisasi

Anda dapat mengonfigurasi kebijakan otorisasi ALLOW dan DENY terpisah, tetapi Anda perlu memahami prioritas kebijakan dan perilaku default untuk memastikan bahwa kebijakan melakukan hal yang Anda inginkan. Diagram berikut menjelaskan prioritas kebijakan.

prioritas kebijakan otorisasi

Contoh kebijakan di bagian berikut mengilustrasikan beberapa perilaku default dan situasi saat Anda mungkin merasa kebijakan tersebut berguna.

Tidak mengizinkan apa pun

Contoh berikut menunjukkan kebijakan ALLOW yang tidak cocok dengan apa pun. Secara default, jika tidak ada kebijakan ALLOW lain, permintaan akan selalu ditolak.

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-nothing
spec:
  action: ALLOW

Praktik keamanan yang baik adalah memulai dengan kebijakan yang tidak mengizinkan apa pun dan menambahkan lebih banyak kebijakan ALLOW secara bertahap untuk membuka lebih banyak akses ke beban kerja.

Menolak semua akses

Contoh berikut menunjukkan kebijakan DENY yang cocok dengan semuanya. Karena kebijakan DENY dievaluasi sebelum kebijakan ALLOW, semua permintaan akan ditolak meskipun ada kebijakan ALLOW yang cocok dengan permintaan.

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: deny-all
spec:
  action: DENY
  rules:
  - {}

Kebijakan tolak semua berguna jika Anda ingin menonaktifkan semua akses ke beban kerja untuk sementara.

Mengizinkan semua akses

Contoh berikut menunjukkan kebijakan ALLOW yang cocok dengan semuanya, dan mengizinkan akses penuh ke beban kerja. Kebijakan izinkan semua membuat kebijakan ALLOW lainnya tidak berguna karena selalu mengizinkan permintaan.

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-all
spec:
  action: ALLOW
  rules:
  - {}

Kebijakan izinkan semua berguna jika Anda ingin mengekspos akses penuh ke beban kerja untuk sementara. Jika ada kebijakan DENY, permintaan masih dapat ditolak karena kebijakan DENY dievaluasi sebelum kebijakan ALLOW.

Praktik terbaik

  1. Buat akun layanan Kubernetes untuk setiap layanan, dan tentukan akun layanan di Deployment. Contoh:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: frontend-sa
      namespace: demo
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: frontend
      namespace:demo
    spec:
      selector:
        matchLabels:
          app: frontend
      template:
        metadata:
          labels:
            app: frontend
        spec:
          serviceAccountName: frontend-sa
        ...
    
  2. Mulai dengan kebijakan yang tidak mengizinkan apa pun dan secara bertahap tambahkan kebijakan ALLOW lainnya untuk membuka lebih banyak akses ke beban kerja.

  3. Jika Anda menggunakan JWT untuk layanan Anda:

    1. Buat kebijakan DENY untuk memblokir permintaan yang tidak diautentikasi, misalnya:

      apiVersion: security.istio.io/v1beta1
      kind: AuthorizationPolicy
      metadata:
        name: requireJWT
        namespace: admin
      spec:
        action: DENY
        rules:
        -  from:
          - source:
              notRequestPrincipals: ["*"]
      
    2. Terapkan kebijakan yang tidak mengizinkan apa pun.

    3. Tentukan kebijakan ALLOW untuk setiap beban kerja. Untuk contoh, lihat Token JWT.

Langkah selanjutnya

Pelajari lebih lanjut fitur keamanan Cloud Service Mesh:

Pelajari kebijakan otorisasi lebih lanjut dari dokumentasi Istio: