今日覚えて帰ること
Privilege Escalation
日本語では権限昇格
Kubernetesにおいては、コンテナにrootユーザーでは入れてしまうことに対して使うことが多い。
SecurityContextというフィールドの下に設定を行うことで、権限昇格を防ぐことができる。
Privilege Escalation Containers
Set Privilege Escalation for Deployment
There is a Deployment named
logger
which constantly outputs theNoNewPrivs
flag.Let the Pods of that Deployment run with Privilege Escalation disabled.
The logs should show the field change.
deployment によって生成されている pod の権限昇格を無効化せよ、と言っています。
SecurityContextの設定をするだけです。
spec 配下に記述するものと spec.container 配下に記述するものがあるので要注意です。
controlplane $ k edit deployments.apps logger
deployment.apps/logger edited
修正が必要な箇所の近辺を切り出しています。
また、修正した箇所を赤字にしています。
spec:
containers:
- command:
- sh
- -c
- while true; do cat /proc/1/status | grep NoNewPrivs; sleep 1; done
image: bash:5.0.18-alpine3.14
imagePullPolicy: IfNotPresent
name: httpd
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
securityContext:
allowPrivilegeEscalation: false
dnsPolicy: ClusterFirst
restartPolicy: Always
これで完了です。
Privileged Containers
Create a privileged Pod
Create a Pod named
prime
imagenginx:alpine
.The container should run as
privileged
.Install iptables (
apk add iptables
) inside the Pod.Test the capabilities using
iptables -L
.
特権で動く pod を作成し、 iptables をインストールし、 iptables -L で権限の確認をせよ、と言っています。
まずは pod を作成します。
–command オプションで pod 起動時に実行するコマンドを指定することが出来ます。
コマンドを実行してもすぐに破棄されてしまわないように、sleepコマンドを実行するように設定します。
特権の設定はコマンドからはできないので、一旦マニフェストファイルを書き起こして編集し、
k apply コマンドで pod を作成します。
controlplane $ k run prime --image=nginx:alpine -oyaml --dry-run=client --command -- sh -c 'sleep 1d' > pod.yaml
続いて権限昇格を有効にする設定を追記していきます。
追記した箇所は赤字にしています。
controlplane $ vi pod.yaml
apiVersion: v1
kind: Pod
metadata:
creationTimestamp: null
labels:
run: prime
name: prime
spec:
containers:
- command:
- sh
- -c
- sleep 1d
image: nginx:alpine
name: prime
resources: {}
securityContext:
allowPrivilegeEscalation: true
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
先ほどの問題とやることは同じです。
修正が完了したら apply します。
controlplane $ k apply -f pod.yaml
pod/prime created
次に、今立ち上げた pod の中に iptablesコマンド をインストールしていきます。
controlplane $ k exec prime -- apk add iptables
fetch https://dl-cdn.alpinelinux.org/alpine/v3.20/main/x86_64/APKINDEX.tar.gz
fetch https://dl-cdn.alpinelinux.org/alpine/v3.20/community/x86_64/APKINDEX.tar.gz
(1/4) Installing libmnl (1.0.5-r2)
(2/4) Installing libnftnl (1.2.6-r0)
(3/4) Installing libxtables (1.8.10-r3)
(4/4) Installing iptables (1.8.10-r3)
Executing busybox-1.36.1-r29.trigger
OK: 47 MiB in 70 packages
controlplane $
インストールが完了したら、iptables -Lコマンドを実行します。
iptablesコマンドは基本的にroot権限が必要なので、実行できていれば pod にroot権限が付与されていることになります。
controlplane $ k exec prime -- iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
controlplane $
これで完了です。
Create a privileged StatefulSet
There is an existing StatefulSet yaml at
/application/sts.yaml
.It should run as
privileged
but it seems like it cannot be applied.Fix it and create the StatefulSet.
ステートフルセットのマニフェストファイルに問題があって apply できないので修正して apply せよ、と言っています。
一旦 apply してみます。
controlplane $ k apply -f /application/sts.yaml
Error from server (BadRequest): error when creating "/application/sts.yaml": StatefulSet in version "v1" cannot be handled as a StatefulSet: strict decoding error: unknown field "spec.template.spec.securityContext.privileged"
spec.template.spec.securityContext.privileged が不明なフィールドだと言われています。
マニフェストファイルをチェックしてみましょう。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: habanero
spec:
selector:
matchLabels:
app: habanero
serviceName: habanero
replicas: 1
template:
metadata:
labels:
app: habanero
spec:
securityContext:
privileged: true
containers:
- name: habanero
image: nginx:alpine
command:
- sh
- -c
- apk add iptables && sleep 1d
spec.template.spec.securityContext.privilegedとありますが、正しい位置は
spec.template.spec.securityContext.container.privileged です。
マニフェストファイルを正しく書き換えると以下のようになります。
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: habanero
spec:
selector:
matchLabels:
app: habanero
serviceName: habanero
replicas: 1
template:
metadata:
labels:
app: habanero
spec:
containers:
- securityContext:
privileged: true
name: habanero
image: nginx:alpine
command:
- sh
- -c
- apk add iptables && sleep 1d
これを apply すれば完了です。