defaultAllowPrivilegeEscalationの挙動

PodSecuriyPolicyのdefaultAllowPrivilegeEscalationの意味がよくわからなかったので、確認したメモ。

まず、KubernetesのデフォルトでPSPを有効にしていない状態では、権限昇格は許可されている。

root@cks-master:~# k run pod1 --image=nginx
pod/pod1 created
root@cks-master:~# k exec -it pod1 -- cat /proc/1/status | grep NoNew
NoNewPrivs: 0
root@cks-master:~# k get pod pod1 -o yaml | grep -A 2 securityContext
        f:securityContext: {}
        f:terminationGracePeriodSeconds: {}
    manager: kubectl-run
--
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
root@cks-master:~# k delete pod pod1
pod "pod1" deleted

PSPを有効にして、以下のようなPSPを作成する。

apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: default
spec:
  # allowPrivilegeEscalation: false
  # defaultAllowPrivilegeEscalation: false
  privileged: false  # Don't allow privileged pods!
  # The rest fills in some required fields.
  seLinux:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  runAsUser:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  volumes:
  - '*'

cluster-adminなのでこのPSPが使えるとして、Podを作成して確認する。PSPを変更して、allowPrivilegeEscalationdefaultAllowPrivilegeEscalationの組み合わせでどうなるかを確認する。以下の組み合わせを確認する。

allowPrivilegeEscalation defaultAllowPrivilegeEscalation
指定しない 指定しない
指定しない false
指定しない true
false 指定しない
false false
false true
true 指定しない
true false
true true

指定しない/指定しない

権限昇格は許可される。PSPを有効にする前と同じ結果。

root@cks-master:~# k run pod1 --image=nginx
pod/pod1 created
root@cks-master:~# k exec -it pod1 -- cat /proc/1/status | grep NoNew
NoNewPrivs: 0
root@cks-master:~# k get pod pod1 -o yaml | grep -A 2 securityContext
        f:securityContext: {}
        f:terminationGracePeriodSeconds: {}
    manager: kubectl-run
--
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
root@cks-master:~# k delete pod pod1
pod "pod1" deleted

指定しない/false

権限昇格は許可されない。コンテナのSecurityContextに自動的にallowPrivilegeEscalation: falseが追加されている。

root@cks-master:~# k run pod1 --image=nginx
pod/pod1 created
root@cks-master:~# k exec -it pod1 -- cat /proc/1/status | grep NoNew
NoNewPrivs: 1
root@cks-master:~# k get pod pod1 -o yaml | grep -A 2 securityContext
        f:securityContext: {}
        f:terminationGracePeriodSeconds: {}
    manager: kubectl-run
--
    securityContext:
      allowPrivilegeEscalation: false
    terminationMessagePath: /dev/termination-log
--
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
root@cks-master:~# k delete pod pod1
pod "pod1" deleted

指定しない/true

権限昇格は許可される。コンテナのSecurityContextに自動的にallowPrivilegeEscalation: trueが追加されている。

root@cks-master:~# k run pod1 --image=nginx
pod/pod1 created
root@cks-master:~# k exec -it pod1 -- cat /proc/1/status | grep NoNew
NoNewPrivs: 0
root@cks-master:~# k get pod pod1 -o yaml | grep -A 2 securityContext
        f:securityContext: {}
        f:terminationGracePeriodSeconds: {}
    manager: kubectl-run
--
    securityContext:
      allowPrivilegeEscalation: true
    terminationMessagePath: /dev/termination-log
--
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
root@cks-master:~# k delete pod pod1
pod "pod1" deleted

false/指定しない

権限昇格は許可されない。コンテナのSecurityContextに自動的にallowPrivilegeEscalation: falseが追加されている。

root@cks-master:~# k run pod1 --image=nginx
pod/pod1 created
root@cks-master:~# k exec -it pod1 -- cat /proc/1/status | grep NoNew
NoNewPrivs: 1
root@cks-master:~# k get pod pod1 -o yaml | grep -A 2 securityContext
        f:securityContext: {}
        f:terminationGracePeriodSeconds: {}
    manager: kubectl-run
--
    securityContext:
      allowPrivilegeEscalation: false
    terminationMessagePath: /dev/termination-log
--
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
root@cks-master:~# k delete pod pod1
pod "pod1" deleted

false/false

権限昇格は許可されない。コンテナのSecurityContextに自動的にallowPrivilegeEscalation: falseが追加されている。「false/指定しない」の場合と同じ結果。

root@cks-master:~# k run pod1 --image=nginx
pod/pod1 created
root@cks-master:~# k exec -it pod1 -- cat /proc/1/status | grep NoNew
NoNewPrivs: 1
root@cks-master:~# k get pod pod1 -o yaml | grep -A 2 securityContext
        f:securityContext: {}
        f:terminationGracePeriodSeconds: {}
    manager: kubectl-run
--
    securityContext:
      allowPrivilegeEscalation: false
    terminationMessagePath: /dev/termination-log
--
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
root@cks-master:~# k delete pod --all
pod "pod1" deleted

false/true

この組み合わせではPSPを作成できない。

root@cks-master:~# k apply -f psp.yaml
The PodSecurityPolicy "default" is invalid: spec.defaultAllowPrivilegeEscalation: Invalid value: true: Cannot set DefaultAllowPrivilegeEscalation to true without also setting AllowPrivilegeEscalation to true

true/指定しない

権限昇格は許可される。PSPを有効にする前と同じ結果。

root@cks-master:~# k run pod1 --image=nginx
pod/pod1 created
root@cks-master:~# k exec -it pod1 -- cat /proc/1/status | grep NoNew
NoNewPrivs: 0
root@cks-master:~# k get pod pod1 -o yaml | grep -A 2 securityContext
        f:securityContext: {}
        f:terminationGracePeriodSeconds: {}
    manager: kubectl-run
--
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
root@cks-master:~# k delete pod pod1
pod "pod1" deleted

true/false

権限昇格は許可されない。コンテナのSecurityContextに自動的にallowPrivilegeEscalation: falseが追加されている。

root@cks-master:~# k run pod1 --image=nginx
pod/pod1 created
root@cks-master:~# k exec -it pod1 -- cat /proc/1/status | grep NoNew
NoNewPrivs: 1
root@cks-master:~# k get pod pod1 -o yaml | grep -A 2 securityContext
        f:securityContext: {}
        f:terminationGracePeriodSeconds: {}
    manager: kubectl-run
--
    securityContext:
      allowPrivilegeEscalation: false
    terminationMessagePath: /dev/termination-log
--
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
root@cks-master:~# k delete pod pod1
pod "pod1" deleted

true/true

権限昇格は許可される。コンテナのSecurityContextに自動的にallowPrivilegeEscalation: trueが追加されている。

root@cks-master:~# k run pod1 --image=nginx
pod/pod1 created
root@cks-master:~# k exec -it pod1 -- cat /proc/1/status | grep NoNew
NoNewPrivs: 0
root@cks-master:~# k get pod pod1 -o yaml | grep -A 2 securityContext
        f:securityContext: {}
        f:terminationGracePeriodSeconds: {}
    manager: kubectl-run
--
    securityContext:
      allowPrivilegeEscalation: true
    terminationMessagePath: /dev/termination-log
--
  securityContext: {}
  serviceAccount: default
  serviceAccountName: default
root@cks-master:~# k delete pod pod1
pod "pod1" deleted

まとめ

まとめると以下のようになった。

allowPrivilegeEscalation defaultAllowPrivilegeEscalation NoNewPrivs 備考
指定しない 指定しない 0 PSPを有効にする前と同じ
指定しない false 1 コンテナのSecurityContextに自動的にallowPrivilegeEscalation: falseが追加
指定しない true 0 コンテナのSecurityContextに自動的にallowPrivilegeEscalation: trueが追加
false 指定しない 1 コンテナのSecurityContextに自動的にallowPrivilegeEscalation: falseが追加
false false 1 コンテナのSecurityContextに自動的にallowPrivilegeEscalation: falseが追加
false true - この組み合わせは不可
true 指定しない 0 PSPを有効にする前と同じ
true false 1 コンテナのSecurityContextに自動的にallowPrivilegeEscalation: falseが追加
true true 0 コンテナのSecurityContextに自動的にallowPrivilegeEscalation: trueが追加

PSPdefaultAllowPrivilegeEscalationはコンテナのSecurityContextに自動的にデフォルト値としてallowPrivilegeEscalationを指定した値で追加する機能と思えばよさそう。ただし、PSPallowPrivilegeEscalation: falseを指定している場合だけが特殊で、defaultAllowPrivilegeEscalationを指定してないなくても、defaultAllowPrivilegeEscalation: falseを設定したのと同じ挙動になる。