Halaman ini memberikan praktik yang baik untuk merencanakan kebijakan role-based access control (RBAC). Untuk mempelajari cara mengimplementasikan RBAC di Google Kubernetes Engine (GKE), lihat Mengonfigurasi role-based access control.
RBAC adalah fitur keamanan inti di Kubernetes yang memungkinkan Anda membuat izin terperinci untuk mengelola tindakan yang dapat dilakukan pengguna dan workload pada resource dalam cluster Anda. Sebagai administrator platform, Anda membuat peran RBAC dan mengikat peran tersebut ke subjek, yang merupakan pengguna terautentikasi seperti layanan atau Google Grup.
Sebelum memulai
Pastikan Anda sudah memahami konsep berikut:
Untuk checklist panduan ini, lihat Ringkasan checklist.
Cara kerja RBAC
RBAC mendukung jenis peran dan binding berikut:
- ClusterRole: sekumpulan izin yang dapat diterapkan ke namespace apa pun, atau ke seluruh cluster.
- Peran: sekumpulan izin yang dibatasi pada satu namespace.
- ClusterRoleBinding: mengikat
ClusterRole
ke pengguna atau grup untuk semua namespace di cluster. - RoleBinding: mengikat
Role
atauClusterRole
ke pengguna atau grup dalam namespace tertentu.
Anda menentukan izin sebagai rules
dalam Role
atau ClusterRole
. Setiap kolom rules
dalam peran terdiri dari grup API, resource API dalam grup API tersebut, dan verba (tindakan) yang diizinkan pada resource tersebut. Secara opsional, Anda dapat mencakup verba ke instance resource API bernama menggunakan kolom resourceNames
. Sebagai contoh, lihat Membatasi akses ke instance resource tertentu.
Setelah menentukan peran, Anda menggunakan RoleBinding
atau ClusterRoleBinding
untuk mengikat peran ke subjek. Pilih jenis binding berdasarkan apakah Anda ingin memberikan izin dalam satu namespace atau beberapa namespace.
Desain peran RBAC
Menggunakan prinsip hak istimewa terendah
Saat menetapkan izin dalam peran RBAC, gunakan prinsip hak istimewa terendah dan berikan izin minimum yang diperlukan untuk melakukan tugas. Menggunakan prinsip hak istimewa terendah akan mengurangi potensi eskalasi akses jika cluster Anda disusupi, dan mengurangi kemungkinan akses yang berlebihan menyebabkan insiden keamanan.
Saat mendesain peran Anda, pertimbangkan dengan cermat risiko eskalasi akses umum, seperti verba escalate
atau bind
, akses create
untuk PersistentVolumes, atau akses create
untuk Permintaan Penandatanganan Sertifikat. Untuk mengetahui daftar risiko, lihat Kubernetes RBAC - risiko eskalasi akses.
Menghindari peran dan grup default
Kubernetes membuat sekumpulan ClusterRoles dan ClusterRoleBindings default yang dapat Anda gunakan untuk penemuan API dan untuk mengaktifkan fungsi komponen terkelola. Izin yang diberikan oleh peran default ini mungkin sangat luas, bergantung pada perannya. Kubernetes juga memiliki sekumpulan pengguna dan grup pengguna default, yang diidentifikasi dengan awalan system:
.
Secara default, Kubernetes dan GKE secara otomatis mengikat peran ini ke grup default dan ke berbagai subjek. Untuk mengetahui daftar lengkap peran dan binding default yang dibuat Kubernetes, lihat Peran dan binding peran default.
Tabel berikut menjelaskan beberapa peran, pengguna, dan grup default. Sebaiknya hindari berinteraksi dengan peran, pengguna, dan grup ini kecuali jika Anda telah mengevaluasinya dengan cermat, karena berinteraksi dengan resource ini dapat memiliki konsekuensi yang tidak diinginkan terhadap postur keamanan cluster Anda.
Nama | Jenis | Deskripsi |
---|---|---|
cluster-admin |
ClusterRole | Memberikan izin subjek untuk melakukan apa pun pada resource apa pun di cluster. |
system:anonymous |
Pengguna | Kubernetes menetapkan pengguna ini ke permintaan server API yang tidak menyediakan informasi autentikasi. Mengikat peran ke pengguna ini akan memberikan izin kepada setiap pengguna tanpa autentikasi yang diberikan oleh peran tersebut. |
system:unauthenticated |
Grup | Kubernetes menetapkan grup ini ke permintaan server API yang tidak menyediakan informasi autentikasi. Mengikat peran ke grup ini akan memberikan izin kepada setiap pengguna tanpa autentikasi yang diberikan oleh peran tersebut. |
system:authenticated |
Grup | GKE menetapkan grup ini ke permintaan server API yang dibuat
oleh pengguna mana pun yang login dengan Akun Google, termasuk semua
akun Gmail. Dalam praktiknya, hal ini tidak
berbeda secara signifikan dengan Mengikat peran ke grup ini akan memberi semua pengguna Akun Google, termasuk semua akun Gmail, izin yang diberikan oleh peran tersebut. |
system:masters |
Grup | Kubernetes menetapkan ClusterRole Dengan menambahkan subjek Anda sendiri ke grup ini, subjek tersebut akan memiliki akses untuk melakukan apa pun pada resource mana pun dalam cluster Anda. |
Jika memungkinkan, hindari membuat binding yang melibatkan pengguna, peran, dan grup default. Hal ini dapat menimbulkan konsekuensi yang tidak diinginkan terhadap postur keamanan cluster Anda. Contoh:
- Mengikat ClusterRole
cluster-admin
default ke grupsystem:unauthenticated
akan memberikan akses kepada pengguna tanpa autentikasi ke semua resource dalam cluster (termasuk Secret). Binding dengan hak istimewa tinggi ini secara aktif menjadi target serangan seperti kampanye malware massal. - Mengikat Peran khusus ke grup
system:unauthenticated
akan memberikan izin kepada pengguna tanpa autentikasi yang diberikan oleh peran tersebut.
Jika memungkinkan, gunakan panduan berikut:
- Jangan tambahkan subjek Anda sendiri ke grup
system:masters
. - Jangan ikat grup
system:unauthenticated
ke peran RBAC apa pun. - Jangan ikat grup
system:authenticated
ke peran RBAC apa pun. - Jangan ikat pengguna
system:anonymous
ke peran RBAC apa pun. - Jangan ikat ClusterRole
cluster-admin
ke subjek Anda sendiri atau ke pengguna dan grup default mana pun. Jika aplikasi Anda memerlukan banyak izin, tentukan izin yang diperlukan, lalu buat peran khusus untuk tujuan tersebut. - Evaluasi izin yang diberikan oleh peran default lain sebelum mengikat subjek.
- Evaluasi peran yang terikat dengan grup default sebelum mengubah anggota grup tersebut.
Mendeteksi dan mencegah penggunaan peran dan grup default
Anda harus menilai cluster untuk mengidentifikasi apakah Anda telah mengikat pengguna system:anonymous
atau grup system:unauthenticated
atau system:authenticated
menggunakan ClusterRoleBindings dan RoleBindings.
ClusterRoleBindings
Buat daftar nama ClusterRoleBindings dengan subjek
system:anonymous
,system:unauthenticated
, atausystem:authenticated
:kubectl get clusterrolebindings -o json \ | jq -r '["Name"], ["-----"], (.items[] | select((.subjects | length) > 0) | select(any(.subjects[]; .name == "system:anonymous" or .name == "system:unauthenticated" or .name == "system:authenticated")) | [.metadata.namespace, .metadata.name]) | @tsv'
Output hanya akan mencantumkan ClusterRoleBinding berikut:
Name ---- "system:basic-user" "system:discovery" "system:public-info-viewer"
Jika output berisi binding non-default tambahan, lakukan hal berikut untuk setiap binding tambahan. Jika output Anda tidak berisi binding non-default, lewati langkah-langkah berikut.
Cantumkan izin peran yang terkait dengan binding:
kubectl get clusterrolebinding CLUSTER_ROLE_BINDING_NAME -o json \ | jq ' .roleRef.name +" " + .roleRef.kind' \ | sed -e 's/"//g' \ | xargs -l bash -c 'kubectl get $1 $0 -o yaml'
Ganti
CLUSTER_ROLE_BINDING_NAME
dengan nama ClusterRoleBinding non-default.Outputnya mirip dengan hal berikut ini:
apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: ... rules: - apiGroups: - "" resources: - secrets verbs: - get - watch - list
Jika Anda memutuskan bahwa izin dalam output aman untuk diberikan kepada pengguna atau grup default, Anda tidak perlu melakukan tindakan lebih lanjut. Jika Anda memutuskan bahwa izin yang diberikan oleh binding tidak aman, lanjutkan ke langkah berikutnya.
Hapus binding yang tidak aman dari cluster Anda:
kubectl delete clusterrolebinding CLUSTER_ROLE_BINDING_NAME
Ganti
CLUSTER_ROLE_BINDING_NAME
dengan nama ClusterRoleBinding yang akan dihapus.
RoleBindings
Cantumkan namespace dan nama RoleBinding dengan subjek
system:anonymous
,system:unauthenticated
, atausystem:authenticated
:kubectl get rolebindings -A -o json \ | jq -r '["Namespace", "Name"], ["---------", "-----"], (.items[] | select((.subjects | length) > 0) | select(any(.subjects[]; .name == "system:anonymous" or .name == "system:unauthenticated" or .name == "system:authenticated")) | [.metadata.namespace, .metadata.name]) | @tsv'
Jika cluster Anda dikonfigurasi dengan benar, output-nya harus kosong. Jika output berisi binding non-default, lakukan langkah-langkah berikut untuk setiap binding tambahan. Jika output Anda kosong, lewati langkah-langkah berikut.
Jika hanya mengetahui nama RoleBinding, Anda dapat menggunakan perintah berikut untuk menemukan rolebinding yang cocok di semua namespace:
kubectl get rolebindings -A -o json \ | jq -r '["Namespace", "Name"], ["---------", "-----"], (.items[] | select((.subjects | length) > 0) | select(.metadata.name == "ROLE_BINDING_NAME") | [.metadata.namespace, .metadata.name]) | @tsv'
Ganti
ROLE_BINDING_NAME
dengan nama RoleBinding non-default.Buat daftar izin Peran yang terkait dengan binding:
kubectl get rolebinding ROLE_BINDING_NAME --namespace ROLE_BINDING_NAMESPACE -o json \ | jq ' .roleRef.name +" " + .roleRef.kind' \ | sed -e 's/"//g' \ | xargs -l bash -c 'kubectl get $1 $0 -o yaml --namespace ROLE_BINDING_NAMESPACE'
Ganti kode berikut:
ROLE_BINDING_NAME
: nama RoleBinding non-default.ROLE_BINDING_NAMESPACE
: namespace RoleBinding non-default.
Outputnya mirip dengan hal berikut ini:
apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: ... rules: - apiGroups: - "" resources: - secrets verbs: - get - watch - list
Jika Anda memutuskan bahwa izin dalam output aman untuk diberikan kepada pengguna atau grup default, Anda tidak perlu melakukan tindakan lebih lanjut. Jika Anda memutuskan bahwa izin yang diberikan oleh binding tidak aman, lanjutkan ke langkah berikutnya.
Hapus binding yang tidak aman dari cluster Anda:
kubectl delete rolebinding ROLE_BINDING_NAME --namespace ROLE_BINDING_NAMESPACE
Ganti kode berikut:
ROLE_BINDING_NAME
: nama RoleBinding yang akan dihapus.ROLE_BINDING_NAMESPACE
: namespace RoleBinding yang akan dihapus.
Membatasi izin ke tingkat namespace
Gunakan binding dan peran sebagai berikut, bergantung pada kebutuhan workload atau pengguna Anda:
- Untuk memberikan akses ke resource dalam satu namespace, gunakan
Role
denganRoleBinding
. - Untuk memberikan akses ke resource di lebih dari satu namespace, gunakan
ClusterRole
denganRoleBinding
untuk setiap namespace. - Untuk memberikan akses ke resource di setiap namespace, gunakan
ClusterRole
denganClusterRoleBinding
.
Berikan izin pada namespace sesedikit mungkin.
Jangan menggunakan karakter pengganti
Karakter *
adalah karakter pengganti yang berlaku untuk semua hal. Hindari penggunaan karakter pengganti dalam aturan Anda. Tentukan secara eksplisit grup, resource, dan verba API dalam aturan RBAC. Misalnya, menentukan *
di kolom verbs
akan menghasilkan izin get
, list
, watch
, patch
, update
, deletecollection
, dan delete
pada resource. Tabel berikut menunjukkan contoh cara menghindari karakter pengganti dalam aturan Anda:
Direkomendasikan | Tidak direkomendasikan |
---|---|
- rules: apiGroups: ["apps","extensions"] resources: ["deployments"] verbs: ["get","list","watch"] Memberikan verba |
- rules: apiGroups: ["*"] resources: ["deployments"] verbs: ["get","list","watch"] Memberikan verba ke |
- rules: apiGroups: ["apps", "extensions"] resources: ["deployments"] verbs: ["get", "list", "watch"] Hanya memberikan verba |
- rules: apiGroups: ["apps", "extensions"] resources: ["deployments"] verbs: ["*"] Memberikan semua verba, termasuk |
Menggunakan aturan terpisah untuk memberikan akses hak istimewa terendah ke resource tertentu
Saat merencanakan aturan, coba langkah-langkah tingkat tinggi berikut untuk desain aturan dengan hak istimewa terendah yang lebih efisien di setiap peran:
- Buat draf aturan RBAC terpisah untuk setiap verba pada setiap resource yang perlu diakses oleh subjek.
- Setelah membuat draf aturan, analisis aturan untuk memeriksa apakah beberapa aturan memiliki daftar
verbs
yang sama atau tidak. Gabungkan aturan tersebut menjadi satu aturan. - Tetap pisahkan semua aturan lainnya.
Pendekatan ini menghasilkan desain aturan yang lebih teratur, dengan aturan yang memberikan verba yang sama ke beberapa resource digabungkan, dan aturan yang memberikan verba yang berbeda ke resource akan terpisah.
Misalnya, jika workload Anda perlu mendapatkan izin untuk resource deployments
, tetapi memerlukan list
dan watch
pada resource daemonsets
, Anda harus menggunakan aturan terpisah saat membuat peran tersebut. Ketika Anda mengikat peran RBAC ke workload Anda, peran tersebut tidak akan dapat menggunakan watch
di deployments
.
Sebagai contoh lain, jika workload Anda memerlukan get
dan watch
pada resource pods
dan resource daemonsets
, Anda dapat menggabungkannya menjadi satu aturan, karena workload membutuhkan verba yang sama di kedua resource.
Dalam tabel berikut, kedua desain aturan dapat berfungsi, tetapi aturan pemisahan secara lebih terperinci membatasi akses resource berdasarkan kebutuhan Anda:
Direkomendasikan | Tidak direkomendasikan |
---|---|
- rules: apiGroups: ["apps"] resources: ["deployments"] verbs: ["get"] - rules: apiGroups: ["apps"] resources: ["daemonsets"] verbs: ["list", "watch"] Memberikan akses |
- rules: apiGroups: ["apps"] resources: ["deployments", "daemonsets"] verbs: ["get","list","watch"] Memberikan verba ke Deployment dan DaemonSet. Subjek yang mungkin tidak memerlukan akses |
- rules: apiGroups: ["apps"] resources: ["daemonsets", "deployments"] verbs: ["list", "watch"] Menggabungkan dua aturan karena subjek memerlukan verba yang sama untuk resource |
- rules: apiGroups: ["apps"] resources: ["daemonsets"] verbs: ["list", "watch"] - rules: apiGroups: ["apps"] resources: ["deployments"] verbs: ["list", "watch"] Aturan terpisah ini akan memiliki hasil yang sama dengan aturan gabungan, tetapi akan menimbulkan kekacauan yang tidak perlu dalam manifes peran Anda |
Membatasi akses ke instance resource tertentu
Dengan RBAC, Anda dapat menggunakan kolom resourceNames
dalam aturan untuk membatasi akses ke instance resource bernama tertentu. Misalnya, jika Anda menulis peran RBAC yang memerlukan update
ConfigMap seccomp-high
dan bukan yang lainnya, Anda dapat menggunakan resourceNames
untuk menentukan hanya ConfigMap tersebut. Gunakan resourceNames
jika memungkinkan.
Direkomendasikan | Tidak direkomendasikan |
---|---|
- rules: apiGroups: [""] resources: ["configmaps"] resourceNames: ["seccomp-high"] verbs: ["update"] Membatasi subjek hanya untuk memperbarui ConfigMap |
- rules: apiGroups: [""] resources: ["configmaps"] verbs: ["update"] Subjek dapat memperbarui ConfigMap |
- rules: apiGroups: [""] resources: ["configmaps"] verbs: ["list"] - rules: apiGroups: [""] resources: ["configmaps"] resourceNames: ["seccomp-high"] verbs: ["update"] Memberi |
- rules: apiGroups: [""] resources: ["configmaps"] verbs: ["update", "list"] Memberi |
Jangan mengizinkan akun layanan mengubah resource RBAC
Jangan ikat resource Role
atau ClusterRole
yang memiliki izin bind
, escalate
, create
, update
, atau patch
pada grup API rbac.authorization.k8s.io
ke akun layanan di namespace apa pun. escalate
dan bind
secara khusus dapat memungkinkan penyerang mengabaikan mekanisme pencegahan eskalasi yang dibuat dalam RBAC.
Akun layanan Kubernetes
Membuat akun layanan Kubernetes untuk setiap workload
Buat akun layanan Kubernetes terpisah untuk setiap workload. Ikat Role
atau ClusterRole
dengan hak istimewa terendah ke akun layanan tersebut.
Jangan menggunakan akun layanan default
Kubernetes membuat akun layanan bernama default
di setiap namespace. Akun layanan default
secara otomatis ditetapkan ke Pod yang tidak secara eksplisit menentukan akun layanan dalam manifes. Hindari mengikat Role
atau ClusterRole
ke akun layanan default
. Kubernetes mungkin menetapkan akun layanan default
ke Pod yang tidak memerlukan akses yang diberikan dalam peran tersebut.
Jangan memasang token akun layanan secara otomatis
Kolom automountServiceAccountToken
dalam spesifikasi Pod memberi tahu Kubernetes untuk memasukkan token kredensial untuk akun layanan Kubernetes ke dalam Pod. Pod dapat menggunakan token ini untuk membuat permintaan terautentikasi ke server Kubernetes API. Nilai default untuk kolom ini adalah true
.
Di semua versi GKE, tetapkan automountServiceAccountToken=false
dalam spesifikasi Pod jika Pod Anda tidak perlu berkomunikasi dengan server API.
Memilih token efemeral daripada token berbasis Secret
Secara default, proses kubelet pada node mengambil token akun layanan berumur pendek yang dirotasi secara otomatis untuk setiap Pod. kubelet memasang token ini di Pod sebagai volume yang diproyeksikan, kecuali jika Anda menetapkan kolom automountServiceAccountToken
ke false
di spesifikasi Pod. Setiap panggilan ke Kubernetes API dari Pod akan menggunakan token ini untuk melakukan autentikasi ke server API.
Jika Anda mengambil token akun layanan secara manual, hindari penggunaan Secret Kubernetes untuk menyimpan token tersebut. Token akun layanan berbasis secret adalah kredensial lama yang tidak habis masa berlakunya dan tidak dirotasi secara otomatis. Jika Anda memerlukan
kredensial untuk akun layanan, gunakan
TokenRequest
API
untuk mendapatkan token berumur pendek yang dirotasi otomatis.
Meninjau izin RBAC secara terus-menerus
Tinjau peran dan akses RBAC Anda secara rutin untuk mengidentifikasi potensi jalur eskalasi dan aturan yang berlebihan. Misalnya, pertimbangkan situasi saat Anda tidak menghapus RoleBinding
yang mengikat Role
dengan hak istimewa khusus untuk pengguna yang dihapus. Jika penyerang membuat akun pengguna dalam namespace tersebut dengan nama yang sama seperti pengguna yang dihapus, dia akan terikat dengan Role
tersebut dan akan mewarisi akses yang sama. Peninjauan berkala meminimalkan risiko ini.
Ringkasan checklist
Langkah selanjutnya
- Baca saran hardening GKE.
- Baca praktik yang baik terkait RBAC Kubernetes.
- Pelajari praktik terbaik kami yang lain.
- Lihat contoh manifes untuk peran cluster umum