【Kubernetes】Security Contextについて
はじめに
KubernetesでPodとコンテナに設定できるSecurity Contextについて簡単に紹介して、実際に動かしてみます。
Security Contextとは
Security Contextは、Podもしくはコンテナに権限やアクセス制御を設定できます。
いくつか例を挙げると、Security Contextでは、下記のような設定ができます。
- 非rootユーザーでのコンテナ実行
- ルートファイルシステムの読み取り専用
- 権限昇格の有無
- Capabilityの設定
設定によって、Podでまとめて設定できるもの、コンテナごとに設定できるものがあります。
非rootユーザーとして実行
下記の設定で非rootユーザーとして、プロセスを実行したり、ファイルの所有者を指定したりします。
runAsUser
: コンテナのプロセスのUIDを指定runAsGroup
: コンテナのプロセスのGIDを指定fsGroup
: マウントされたボリュームのファイルシステムのGIDを指定
1spec:
2 securityContext:
3 runAsUser: 1000
4 runAsGroup: 3000
5 fsGroup: 2000
6 containers:
7 - image: busybox
8 name: pod-with-sc
rootユーザーでの実行をブロック
runAsNonRoot
で、rootユーザーとしてプロセスが実行されるのを拒否します。
1spec:
2 securityContext:
3 runAsNonRoot: true
4 containers:
5 - image: busybox
6 name: pod-with-sc
ルートファイルシステムを読み取り専用に
readOnlyRootFilesystem
で、ルートファイルシステムを読み取り専用にします。
1 containers:
2 - image: busybox
3 name: pod-with-sc
4 securityContext:
5 readOnlyRootFilesystem: true
権限昇格
allowPrivilegeEscalation
で、権限昇格を無効化します。
1 containers:
2 - image: busybox
3 name: pod-with-sc
4 securityContext:
5 allowPrivilegeEscalation: false
Capability
capabilities
で、Capabilityの設定ができます。
Capabilityとは、Linuxでのプログラムが実行できる権限を細かく分けたものです。
この設定で、不要なCapabilityの削除と、必要なCapabilityの追加ができます。
1 containers:
2 - image: busybox
3 name: pod-with-sc
4 securityContext:
5 capabilities:
6 drop: ["all"]
7 add: ["NET_BIND_SERVICE"]
試してみる
紹介した設定について、Security ContextなしのPodとありのPodを比較しながら試してみます。
Security ContextなしでPod実行
まずは、Security ContextなしのPodを実行します。
1apiVersion: v1
2kind: Pod
3metadata:
4 name: pod-non-sc
5spec:
6 containers:
7 - image: busybox
8 name: pod-non-sc
9 command: [ "sh", "-c", "sleep 3600" ]
10 volumeMounts:
11 - name: sc-vol
12 mountPath: /tmp/demo
13 volumes:
14 - name: sc-vol
15 emptyDir: {}
Podを作成します。
1kubectl apply -f pod-non-sc.yml
Security ContextありでPod実行
次に、Security ContextありのPodを実行します。
Capabilityに関しては、とりあえずNET_BIND_SERVICE
だけ付与しています。
1apiVersion: v1
2kind: Pod
3metadata:
4 name: pod-with-sc
5spec:
6 securityContext:
7 runAsUser: 1000
8 runAsGroup: 3000
9 fsGroup: 2000
10 runAsNonRoot: true
11 containers:
12 - image: busybox
13 name: pod-with-sc
14 command: [ "sh", "-c", "sleep 3600" ]
15 securityContext:
16 readOnlyRootFilesystem: true
17 allowPrivilegeEscalation: false
18 capabilities:
19 drop: ["all"]
20 add: ["NET_BIND_SERVICE"]
21 volumeMounts:
22 - name: sc-vol
23 mountPath: /tmp/demo
24 volumes:
25 - name: sc-vol
26 emptyDir: {}
Podを作成します。
1kubectl apply -f pod-with-sc.yml
動作確認
動作を比較していきます。
まずは、それぞれのPodのシェルに接続しておきます。
1kubectl exec -it pod-non-sc -- sh
2kubectl exec -it pod-with-sc -- sh
プロセスのユーザー
プロセスを確認します。
Security Contextを設定するとプロセスの実行ユーザーとグループが設定されたユーザーになっていることが確認できます。
1# --- Security Contextなし ---
2/ # ps -o pid,user,group,args
3PID USER GROUP COMMAND
4 1 root root sleep 3600
5 7 root root sh
6 17 root root ps -o pid,user,group,args
7
8
9# --- Security Contextあり ---
10/ $ ps -o pid,user,group,args
11PID USER GROUP COMMAND
12 1 1000 3000 sleep 3600
13 8 1000 3000 sh
14 19 1000 3000 ps -o pid,user,group,args
ボリュームの所有者
マウントしたボリュームのパスとそこで作成されたファイルの所有者を確認します。
ユーザーがrunAsUser
、グループがfsGroup
のIDになっていることが確認できます。
1# --- Security Contextなし ---
2/ $ cd tmp
3
4/tmp # ls -l
5total 4
6drwxrwxrwx 2 root root 4096 Jun 19 05:29 demo
7
8/tmp # cd demo
9
10/tmp/demo # echo hello > testfile
11
12/tmp/demo # ls -l
13total 4
14-rw-r--r-- 1 root root 6 Jun 19 05:36 testfile
15
16
17# --- Security Contextあり ---
18/ $ cd tmp
19
20/tmp $ ls -l
21total 4
22drwxrwsrwx 2 root 2000 4096 Jun 19 05:29 demo
23
24/tmp $ cd demo
25
26/tmp/demo $ echo hello > testfile
27
28/tmp/demo $ ls -l
29total 4
30-rw-r--r-- 1 1000 2000 6 Jun 19 05:37 testfile
ルートファイルシステムの書き込み
ルートファイルシステムの書き込みについても確認します。
設定していると、Read-onlyというエラーになり、書き込みができなくなっています。
1# --- Security Contextなし ---
2/ # echo hello > testfile
3
4/ # ls
5bin dev etc home proc root sys testfile tmp usr var
6
7
8# --- Security Contextあり ---
9/ $ echo hello > testfile
10sh: can't create testfile: Read-only file system
権限昇格
権限昇格が可能か確認します。
su
コマンドで試してみると、昇格できないようになっていることが確認できます。
1# --- Security Contextなし ---
2/ # su -c ls
3bin dev etc home proc root sys testfile tmp usr var
4
5
6# --- Security Contextあり ---
7/ $ su -c ls
8su: must be suid to work properly
Capability
最後にCapabilityについて確認します。
試しにPIDが1のプロセスを確認すると、NET_BIND_SERVICE
のビットだけ立っていることが確認できます。
1# --- Security Contextなし ---
2/ $ cat /proc/1/status
3...
4CapPrm: 00000000a80425fb
5CapEff: 00000000a80425fb
6CapBnd: 00000000a80425fb
7...
8
9# --- Security Contextあり ---
10/ $ cat /proc/1/status
11...
12CapPrm: 0000000000000000
13CapEff: 0000000000000000
14CapBnd: 0000000000000400
15...
Capabilityのビットについては、capability.hから確認してください。
参考
- Configure a Security Context for a Pod or Container | Kubernetes
- linux/capability.h at master · torvalds/linux