Mengonfigurasi Konteks Keamanan untuk Pod atau Container
Konteks keamanan (security context) menentukan wewenang (privilege) dan aturan kontrol akses untuk sebuah Pod atau Container. Aturan konteks keamanan meliputi hal-hal berikut ini namun tidak terbatas pada hal-hal tersebut:
-
Kontrol akses bersifat diskresi: Izin untuk mengakses objek, seperti sebuah berkas, yang didasarkan pada ID pengguna atau user ID (UID) dan ID grup atau group ID (GID).
-
Security Enhanced Linux (SELinux): Di mana objek diberi label keamanan.
-
Menjalankan dengan wewenang (privileged) atau tanpa wewenang (unprivileged).
-
Kapabilitas Linux (Linux Capabilities): Memberi sebuah proses beberapa wewenang, namun tidak semua wewenang dari pengguna root.
-
AppArmor: Menggunakan profil program untuk membatasi kemampuan dari masing-masing program.
-
Seccomp: Menyaring panggilan sistem (system calls) dari suatu proses.
-
AllowPrivilegeEscalation: Mengontrol apakah suatu proses dapat memperoleh lebih banyak wewenang daripada proses induknya. Pilihan ini mengontrol secara langsung apakah opsi
no_new_privs
diaktifkan pada proses dalam Container. AllowPrivilegeEscalation selalu aktif (true) ketika Container: 1) berjalan dengan wewenang ATAU 2) memilikiCAP_SYS_ADMIN
. -
readOnlyRootFilesystem: Menambatkan (mount) sistem berkas (file system) root dari sebuah Container hanya sebatas untuk dibaca saja (read-only).
Poin-poin di atas bukanlah sekumpulan lengkap dari aturan konteks keamanan - silakan lihat SecurityContext untuk daftar lengkapnya.
Untuk informasi lebih lanjut tentang mekanisme keamanan pada Linux, silahkan lihat ikhtisar fitur keamanan pada Kernel Linux
Sebelum kamu memulai
Kamu harus memiliki klaster Kubernetes, dan perangkat baris perintah kubectl juga harus dikonfigurasikan untuk berkomunikasi dengan klastermu. Jika kamu belum memiliki klaster, kamu dapat membuatnya dengan menggunakan minikube, atau kamu juga dapat menggunakan salah satu dari tempat mencoba Kubernetes berikut ini:
Untuk melihat versi, tekankubectl version
.
Mengatur konteks keamanan untuk Pod
Untuk menentukan aturan keamanan pada Pod, masukkan bagian securityContext
dalam spesifikasi Pod. Bagian securityContext
adalah sebuah objek
PodSecurityContext.
Aturan keamanan yang kamu tetapkan untuk Pod akan berlaku untuk semua Container dalam Pod tersebut.
Berikut sebuah berkas konfigurasi untuk Pod yang memiliki volume securityContext
dan emptyDir
:
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo
spec:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
volumes:
- name: sec-ctx-vol
emptyDir: {}
containers:
- name: sec-ctx-demo
image: busybox
command: [ "sh", "-c", "sleep 1h" ]
volumeMounts:
- name: sec-ctx-vol
mountPath: /data/demo
securityContext:
allowPrivilegeEscalation: false
Dalam berkas konfigurasi ini, bagian runAsUser
menentukan bahwa dalam setiap Container pada
Pod, semua proses dijalankan oleh ID pengguna 1000. Bagian runAsGroup
menentukan grup utama dengan ID 3000 untuk
semua proses dalam setiap Container pada Pod. Jika bagian ini diabaikan, maka ID grup utama dari Container
akan berubah menjadi root(0). Berkas apa pun yang dibuat juga akan dimiliki oleh pengguna dengan ID 1000 dan grup dengan ID 3000 ketika runAsGroup
ditentukan.
Karena fsGroup
ditentukan, semua proses milik Container juga merupakan bagian dari grup tambahan dengan ID 2000.
Pemilik volume /data/demo
dan berkas apa pun yang dibuat dalam volume tersebut adalah grup dengan ID 2000.
Buatlah Pod tersebut:
kubectl apply -f https://k8s.io/examples/pods/security/security-context.yaml
Periksa apakah Container dari Pod sedang berjalan:
kubectl get pod security-context-demo
Masuk ke shell dari Container yang sedang berjalan tersebut:
kubectl exec -it security-context-demo -- sh
Pada shell kamu, lihat daftar proses yang berjalan:
ps
Keluarannya menunjukkan bahwa proses dijalankan oleh pengguna dengan ID 1000, yang merupakan nilai dari bagian runAsUser
:
PID USER TIME COMMAND
1 1000 0:00 sleep 1h
6 1000 0:00 sh
...
Pada shell kamu, pindah ke direktori /data
, dan lihat isinya:
cd /data
ls -l
Keluarannya menunjukkan bahwa direktori /data/demo
memiliki grup dengan ID 2000, yang merupakan
nilai dari bagian fsGroup
.
drwxrwsrwx 2 root 2000 4096 Jun 6 20:08 demo
Pada shell kamu, pindah ke direktori /data/demo
, dan buatlah sebuah berkas didalamnya:
cd demo
echo hello > testfile
Lihatlah daftar berkas dalam direktori /data/demo
:
ls -l
Keluarannya menunjukkan bahwa testfile
memiliki grup dengan ID 2000, dimana merupakan nilai dari bagian fsGroup
.
-rw-r--r-- 1 1000 2000 6 Jun 6 20:08 testfile
Jalankan perintah berikut ini:
$ id
uid=1000 gid=3000 groups=2000
Kamu akan melihat bahwa nilai gid adalah 3000, sama dengan bagian runAsGroup
. Jika runAsGroup
diabaikan maka nilai gid akan
tetap bernilai 0(root) dan proses akan dapat berinteraksi dengan berkas-berkas yang dimiliki oleh grup root(0) dan yang memiliki
izin grup untuk grup root(0).
Keluarlah dari shell kamu:
exit
Melakukan konfigurasi izin volume dan kebijakan perubahan kepemilikan untuk Pod
Kubernetes v1.18 [alpha]
Secara bawaan, Kubernetes mengubah kepemilikan dan izin secara rekursif untuk konten masing-masing
volume untuk mencocokkan fsGroup
yang ditentukan dalam securityContext
dari Pod pada saat volume itu
ditambatkan (mounted). Untuk volume yang besar, memeriksa dan mengubah kepemilikan dan izin dapat memerlukan waktu yang sangat lama,
sehingga memperlambat proses menjalankan Pod. Kamu dapat menggunakan bagian fsGroupChangePolicy
dalam sebuah securityContext
untuk mengontrol cara Kubernetes memeriksa dan mengelola kepemilikan dan izin
untuk sebuah volume.
fsGroupChangePolicy - fsGroupChangePolicy
mendefinisikan perilaku untuk mengubah kepemilikan dan izin volume
sebelum diekspos di dalam sebuah Pod. Bagian ini hanya berlaku untuk tipe volume yang mendukung
fsGroup
untuk mengontrol kepemilikan dan izin. Bagian ini memiliki dua nilai yang dapat dimasukkan:
- OnRootMismatch: Hanya mengubah izin dan kepemilikan jika izin dan kepemilikan dari direktori root tidak sesuai dengan izin volume yang diharapkan. Hal ini dapat membantu mempersingkat waktu yang diperlukan untuk mengubah kepemilikan dan izin sebuah volume.
- Always: Selalu mengubah izin dan kepemilikan volume ketika volume sudah ditambatkan.
Sebagai contoh:
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
fsGroupChangePolicy: "OnRootMismatch"
Ini adalah fitur alpha. Untuk menggunakannya, silahkan aktifkan gerbang fitur ConfigurableFSGroupPolicy
untuk kube-api-server, kube-controller-manager, dan kubelet.
Mengatur konteks keamanan untuk Container
Untuk menentukan aturan keamanan untuk suatu Container, sertakan bagian securityContext
dalam manifes Container. Bagian securityContext
adalah sebuah objek
SecurityContext.
Aturan keamanan yang kamu tentukan untuk Container hanya berlaku untuk
Container secara individu, dan aturan tersebut menimpa aturan yang dibuat pada tingkat Pod apabila
ada aturan yang tumpang tindih. Aturan pada Container mempengaruhi volume pada Pod.
Berikut berkas konfigurasi untuk Pod yang hanya memiliki satu Container. Keduanya, baik Pod
dan Container memiliki bagian securityContext
sebagai berikut:
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo-2
spec:
securityContext:
runAsUser: 1000
containers:
- name: sec-ctx-demo-2
image: gcr.io/google-samples/node-hello:1.0
securityContext:
runAsUser: 2000
allowPrivilegeEscalation: false
Buatlah Pod tersebut:
kubectl apply -f https://k8s.io/examples/pods/security/security-context-2.yaml
Periksa jika Container dalam Pod sedang berjalan:
kubectl get pod security-context-demo-2
Masuk ke dalam shell Container yang sedang berjalan tersebut:
kubectl exec -it security-context-demo-2 -- sh
Pada shell kamu, lihat daftar proses yang sedang berjalan:
ps aux
Keluarannya menunjukkan bahwa proses dijalankan oleh user dengan ID 2000, yang merupakan
nilai dari runAsUser
seperti yang telah ditentukan untuk Container tersebut. Nilai tersebut menimpa nilai ID 1000 yang
ditentukan untuk Pod-nya.
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
2000 1 0.0 0.0 4336 764 ? Ss 20:36 0:00 /bin/sh -c node server.js
2000 8 0.1 0.5 772124 22604 ? Sl 20:36 0:00 node server.js
...
Keluar dari shell anda:
exit
Mengatur Kapabilitas untuk Container
Dengan menggunakan Kapabilitas Linux (Linux Capabilities),
kamu dapat memberikan wewenang tertentu kepada suatu proses tanpa memberikan semua wewenang
dari pengguna root. Untuk menambah atau menghapus Kapabilitas Linux pada suatu Container, masukkan
bagian capabilities
pada securityContext
di manifes Container-nya.
Pertama-tama, mari melihat apa yang terjadi ketika kamu tidak menyertakan bagian capabilities
.
Berikut ini adalah berkas konfigurasi yang tidak menambah atau mengurangi kemampuan apa pun dari Container:
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo-3
spec:
containers:
- name: sec-ctx-3
image: gcr.io/google-samples/node-hello:1.0
Buatlah Pod tersebut:
kubectl apply -f https://k8s.io/examples/pods/security/security-context-3.yaml
Periksa apakah Container dari Pod tersebut sedang berjalan:
kubectl get pod security-context-demo-3
Masuk ke dalam shell dari Container yang berjalan:
kubectl exec -it security-context-demo-3 -- sh
Dalam shell tersebut, lihatlah daftar proses yang berjalan:
ps aux
Keluarannya menunjukkan ID dari proses atau process IDs (PIDs) untuk Container tersebut:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 4336 796 ? Ss 18:17 0:00 /bin/sh -c node server.js
root 5 0.1 0.5 772124 22700 ? Sl 18:17 0:00 node server.js
Dalam shell kamu, lihat status dari proses dengan ID 1:
cd /proc/1
cat status
Keluarannya menunjukkan bitmap dari kapabilitas untuk proses tersebut:
...
CapPrm: 00000000a80425fb
CapEff: 00000000a80425fb
...
Buatlah catatan untuk bitmap dari kapabilitas tersebut, dan keluarlah dari shell kamu:
exit
Berikutnya, jalankan Container yang sama seperti dengan Container sebelumnya, namun Container ini memiliki kapabilitas tambahan yang sudah ditentukan.
Berikut ini adalah berkas konfigurasi untuk Pod yang hanya menjalankan satu Container. Konfigurasi
ini menambahkan kapabilitas CAP_NET_ADMIN
dan CAP_SYS_TIME
:
apiVersion: v1
kind: Pod
metadata:
name: security-context-demo-4
spec:
containers:
- name: sec-ctx-4
image: gcr.io/google-samples/node-hello:1.0
securityContext:
capabilities:
add: ["NET_ADMIN", "SYS_TIME"]
Buatlah Pod tersebut:
kubectl apply -f https://k8s.io/examples/pods/security/security-context-4.yaml
Masuk ke dalam shell dari Container yang berjalan:
kubectl exec -it security-context-demo-4 -- sh
Di dalam shell kamu, lihatlah kapabilitas dari proses dengan ID 1:
cd /proc/1
cat status
Keluarannya menunjukkan bitmap kapabilitas untuk proses tersebut:
...
CapPrm: 00000000aa0435fb
CapEff: 00000000aa0435fb
...
Bandingkan kemampuan dari kedua Containers tersebut:
00000000a80425fb
00000000aa0435fb
Dalam bitmap kapabilitas pada Container pertama, bit-12 dan ke-25 tidak diatur. Sedangkan dalam Container kedua,
bit ke-12 dan ke-25 diatur. Bit ke-12 adalah kapabilitas CAP_NET_ADMIN
, dan bit-25 adalah kapabilitas CAP_SYS_TIME
.
Lihatlah capability.h
untuk nilai dari konstanta kapabilitas-kapabilitas yang lainnya.
Catatan: Konstanta kapabilitas Linux memiliki formatCAP_XXX
. Tetapi ketika kamu memasukkan daftar kemampuan dalam manifes Container kamu, kamu harus menghilangkan bagianCAP_
dari konstantanya. Misalnya, untuk menambahkanCAP_SYS_TIME
, masukkanSYS_TIME
ke dalam daftar kapabilitas Container kamu.
Memberikan label SELinux pada sebuah Container
Untuk memberikan label SELinux pada sebuah Container, masukkan bagian seLinuxOptions
pada
bagian securityContext
dari manifes Pod atau Container kamu.
Bagian seLinuxOptions
adalah sebuah objek SELinuxOptions.
Berikut ini adalah contoh yang menerapkan sebuah level dari SELinux:
...
securityContext:
seLinuxOptions:
level: "s0:c123,c456"
Catatan: Untuk menetapkan label SELinux, modul keamanan SELinux harus dimuat terlebih dahulu pada sistem operasi dari hosnya.
Diskusi
Konteks keamanan untuk sebuah Pod berlaku juga untuk Container yang berada dalam Pod tersebut dan juga untuk
volume dari Pod tersebut jika ada. Terkhusus untuk fsGroup
dan seLinuxOptions
akan diterapkan pada volume seperti berikut:
-
fsGroup
: Volume yang mendukung manajemen kepemilikan (ownership) akan dimodifikasi agar dapat dimiliki dan ditulis oleh ID group (GID) yang disebutkan dalamfsGroup
. Lihatlah Dokumen Desain untuk Manajemen Kepemilikan untuk lebih lanjut. -
seLinuxOptions
: Volume yang mendukung pelabelan SELinux akan dilabel ulang agar dapat diakses oleh label yang ditentukan padaseLinuxOptions
. Biasanya kamu hanya perlu mengatur bagianlevel
. Dimana ini akan menetapkan label Keamanan multi-kategori (Multi-Category Security) (MCS) yang diberikan kepada semua Container dalam Pod serta Volume yang ada didalamnya.
Peringatan: Setelah kamu menentukan label MCS untuk Pod, maka semua Pod dengan label yang sama dapat mengakses Volume tersebut. Jika kamu membutuhkan perlindungan antar Pod, kamu harus menetapkan label MCS yang unik untuk setiap Pod.
Bersih-bersih (Clean Up)
Hapus Pod-Pod tersebut:
kubectl delete pod security-context-demo
kubectl delete pod security-context-demo-2
kubectl delete pod security-context-demo-3
kubectl delete pod security-context-demo-4
Selanjutnya
- PodSecurityContext
- SecurityContext
- Menyetel Docker dengan peningkatan keamanan terbaru
- Dokumen desain konteks keamanan
- Dokumen desain manajemen kepemilikan
- Kebijakan keamanan Pod
- Dokumen desain AllowPrivilegeEscalation