【Kubernetes】Security Contextについて

2022.06.19
2024.03.24
Kubernetes
Security Context

本ページはAmazonアフィリエイトのリンクを含みます。

はじめに

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から確認してください。

参考

Support

\ この記事が役に立ったと思ったら、サポートお願いします! /

buy me a coffee
Share

Profile

author

Masa

都内のIT企業で働くエンジニア
自分が学んだことをブログでわかりやすく発信していきながらスキルアップを目指していきます!

buy me a coffee