【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を指定
spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000
  containers:
  - image: busybox
    name: pod-with-sc

rootユーザーでの実行をブロック

runAsNonRootで、rootユーザーとしてプロセスが実行されるのを拒否します。

spec:
  securityContext:
    runAsNonRoot: true
  containers:
  - image: busybox
    name: pod-with-sc

ルートファイルシステムを読み取り専用に

readOnlyRootFilesystemで、ルートファイルシステムを読み取り専用にします。

  containers:
  - image: busybox
    name: pod-with-sc
    securityContext:
      readOnlyRootFilesystem: true

権限昇格

allowPrivilegeEscalationで、権限昇格を無効化します。

  containers:
  - image: busybox
    name: pod-with-sc
    securityContext:
      allowPrivilegeEscalation: false

Capability

capabilitiesで、Capabilityの設定ができます。

Capabilityとは、Linuxでのプログラムが実行できる権限を細かく分けたものです。

この設定で、不要なCapabilityの削除と、必要なCapabilityの追加ができます。

  containers:
  - image: busybox
    name: pod-with-sc
    securityContext:
      capabilities:
        drop: ["all"]
        add: ["NET_BIND_SERVICE"]

試してみる

紹介した設定について、Security ContextなしのPodとありのPodを比較しながら試してみます。

Security ContextなしでPod実行

まずは、Security ContextなしのPodを実行します。

apiVersion: v1
kind: Pod
metadata:
  name: pod-non-sc
spec:
  containers:
  - image: busybox
    name: pod-non-sc
    command: [ "sh", "-c", "sleep 3600" ]
    volumeMounts:
      - name:  sc-vol
        mountPath:  /tmp/demo
  volumes:
  - name: sc-vol
    emptyDir: {}

Podを作成します。

kubectl apply -f pod-non-sc.yml

Security ContextありでPod実行

次に、Security ContextありのPodを実行します。

Capabilityに関しては、とりあえずNET_BIND_SERVICEだけ付与しています。

apiVersion: v1
kind: Pod
metadata:
  name: pod-with-sc
spec:
  securityContext:
    runAsUser: 1000
    runAsGroup: 3000
    fsGroup: 2000
    runAsNonRoot: true
  containers:
  - image: busybox
    name: pod-with-sc
    command: [ "sh", "-c", "sleep 3600" ]
    securityContext:
      readOnlyRootFilesystem: true
      allowPrivilegeEscalation: false
      capabilities:
        drop: ["all"]
        add: ["NET_BIND_SERVICE"]
    volumeMounts:
      - name:  sc-vol
        mountPath:  /tmp/demo
  volumes:
  - name: sc-vol
    emptyDir: {}

Podを作成します。

kubectl apply -f pod-with-sc.yml

動作確認

動作を比較していきます。

まずは、それぞれのPodのシェルに接続しておきます。

kubectl exec -it pod-non-sc -- sh
kubectl exec -it pod-with-sc -- sh

プロセスのユーザー

プロセスを確認します。

Security Contextを設定するとプロセスの実行ユーザーとグループが設定されたユーザーになっていることが確認できます。

# --- Security Contextなし ---
/ # ps -o pid,user,group,args
PID   USER     GROUP    COMMAND
    1 root     root     sleep 3600
    7 root     root     sh
   17 root     root     ps -o pid,user,group,args

# --- Security Contextあり ---
/ $ ps -o pid,user,group,args
PID   USER     GROUP    COMMAND
    1 1000     3000     sleep 3600
    8 1000     3000     sh
   19 1000     3000     ps -o pid,user,group,args

ボリュームの所有者

マウントしたボリュームのパスとそこで作成されたファイルの所有者を確認します。

ユーザーがrunAsUser、グループがfsGroupのIDになっていることが確認できます。

# --- Security Contextなし ---
/ $ cd tmp

/tmp # ls -l
total 4
drwxrwxrwx    2 root     root          4096 Jun 19 05:29 demo

/tmp # cd demo

/tmp/demo # echo hello > testfile

/tmp/demo # ls -l
total 4
-rw-r--r--    1 root     root             6 Jun 19 05:36 testfile

# --- Security Contextあり ---
/ $ cd tmp

/tmp $ ls -l
total 4
drwxrwsrwx    2 root     2000          4096 Jun 19 05:29 demo

/tmp $ cd demo

/tmp/demo $ echo hello > testfile

/tmp/demo $ ls -l
total 4
-rw-r--r--    1 1000     2000             6 Jun 19 05:37 testfile

ルートファイルシステムの書き込み

ルートファイルシステムの書き込みについても確認します。

設定していると、Read-onlyというエラーになり、書き込みができなくなっています。

# --- Security Contextなし ---
/ # echo hello > testfile

/ # ls
bin  dev  etc  home proc root  sys  testfile tmp  usr  var

# --- Security Contextあり ---
/ $ echo hello > testfile
sh: can't create testfile: Read-only file system

権限昇格

権限昇格が可能か確認します。

suコマンドで試してみると、昇格できないようになっていることが確認できます。

# --- Security Contextなし ---
/ # su -c ls
bin  dev  etc  home  proc  root  sys  testfile  tmp  usr  var

# --- Security Contextあり ---
/ $ su -c ls
su: must be suid to work properly

Capability

最後にCapabilityについて確認します。

試しにPIDが1のプロセスを確認すると、NET_BIND_SERVICEのビットだけ立っていることが確認できます。

# --- Security Contextなし ---
/ $ cat /proc/1/status
...
CapPrm: 00000000a80425fb
CapEff: 00000000a80425fb
CapBnd: 00000000a80425fb
...

# --- Security Contextあり ---
/ $ cat /proc/1/status
...
CapPrm: 0000000000000000
CapEff: 0000000000000000
CapBnd: 0000000000000400
...

Capabilityのビットについては、capability.hから確認してください。

参考

タイトルとURLをコピーしました