Kubernetes SecurityContext: 重要なのに見落とされがちなセキュリティ設定
SecurityContext とは¶
KubernetesのPod・Containerに対してセキュリティ設定を行うフィールド。 デフォルトはほぼ無制限なので、本番環境では必ず設定すべき。
PodレベルとContainerレベルの違い¶
apiVersion: v1
kind: Pod
spec:
securityContext: # ← Pod-level: 全コンテナに適用
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
containers:
- name: app
securityContext: # ← Container-level: このコンテナだけに適用(Pod-levelを上書き)
runAsUser: 2000 # Pod-levelの1000を上書き
allowPrivilegeEscalation: false
Container-levelの設定がPod-levelより優先される。
主要な設定項目¶
runAsNonRoot / runAsUser¶
コンテナがrootで動くと、コンテナ脱出時にホストrootへのアクセスリスクが高まる。
readOnlyRootFilesystem¶
攻撃者がコンテナ内でファイルを書き込めなくなる。書き込みが必要な場合は emptyDir ボリュームを使う。
allowPrivilegeEscalation¶
sudo や setuid バイナリを使った権限昇格攻撃を防ぐ。
capabilities¶
securityContext:
capabilities:
drop:
- ALL # 全Linux capabilityを削除
add:
- NET_BIND_SERVICE # 必要なものだけ追加(80/443ポートのバインド)
デフォルトのコンテナは不要なcapabilityを多く持っている。最小権限の原則でdrop: ALL + 必要なものだけadd。
seccompProfile¶
システムコールを制限してカーネルへの攻撃面を減らす。
ベストプラクティスのYAML例¶
apiVersion: v1
kind: Pod
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: myapp:1.0
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
volumeMounts:
- name: tmp
mountPath: /tmp # 書き込みが必要な場所だけemptyDir
volumes:
- name: tmp
emptyDir: {}
なぜ無視されやすいのか¶
- 設定しなくても動くから(デフォルトは緩い)
- 開発環境では問題が出にくい
- アプリが動かなくなることがある(例: rootで起動しようとするアプリ)