Japan

関連リンク

関連リンク

関連リンク

関連リンク

サイト内の現在位置

KubernetesのPod Security Policy非推奨化と今後

NECセキュリティブログ

2022年12月9日

NECサイバーセキュリティ戦略統括部 セキュリティ技術センターの森本です。
本ブログでは、Kubernetesのポリシ制御機能の動向について紹介したいと思います。
コンテナ技術には計算機リソースの節約や可搬性の高さといったメリットがありますが、管理するコンテナが増加することで運用が煩雑となってしまう側面も存在します。Kubernetesをはじめとしたオーケストレーションシステムの導入は、コンテナのデプロイ、スケーリング、管理が自動化でき、運用コストを低減できるとされています。
Kubernetesには、意図しない権限を持つアカウントによるコンテナの実行を拒否するPod Security Policy(PSP)と呼ばれる機能が組み込まれていました。この機能は、コンテナ本体のセキュリティ対策を担保する上で重要な機能でしたが、Kubernetesのv1.21から非推奨となりました。今回はこの非推奨化の背景や後継機能について紹介します。なお、コンテナセキュリティの考え方については以前の記事[1]でも取り上げていますので、こちらもご参照ください。

Kubernetesのアーキテクチャ

Kubernetesのシステム(図1)は、コンテナを実行するワーカノードとそれらを集中管理するコントロールプレーンで構成されます。

図1. Kubernetesシステムの構成

コントロールプレーンは、いくつかのサービス(表1)が連携することで動作しますが、あらゆる要求を処理するAPI Server以外の機能は抽象化(隠蔽)されるため、管理者はAPI Server以外のコンポーネントを強く意識せずとも、コンテナアプリケーションを管理できる仕組みとなっています。

表1. Kubernetesのコントロールプレーンコンポーネント

コンポーネント 機能
API Server Kubernetesに関するあらゆる要求を受け付ける
Controller Manager 各リソースの制御プログラム群を管理する
Etcd Kubernetesのリソースの保存する
Scheduler コンテナを実行するノードを決定する

また、Kubernetesは、構造化されたデータ(YAMLファイル)をもとにリソースを管理する宣言的APIの仕組みを採用しています。宣言的API(宣言型)は、サービスに実行すべき命令をすべて伝えるのではなく、サービスのあるべき状態のみを指示できる機能になります。対の概念となる命令型は、アプリケーションに対して具体的に実行させたいコマンドを命令することで順次実行させる方式です。

例えば、二つのコンテナで動作するシステムで障害が発生した際の復旧方法として、命令型では、障害の検出やコンテナの再起動などの手順をすべて定義しておく必要があります。一方、宣言型では、運用者はコンテナの起動数を指定するのみで、障害の検出やコンテナの再起動はシステム側で自動化されます。このように、宣言型の機能は自動化によって運用者の負担を軽減できる特徴があります。特に、Kubernetes上のリソースの状態を監視して自動で運用するプログラムはコントローラと呼ばれ、各リソースに対応するコントローラがコントロールプレーンで動作します。

Kubernetesでは、コンテナをPodと呼ばれる最小単位で管理しますが、同じ内容のPodを複製して冗長化するReplicaSetリソースやそれらを管理するDeploymentリソースも定義されています。このReplicaSetリソースやDeploymentリソースの作成や削除についても専用のコントローラが制御を行っています。

ここで、ReplicaSetリソースが作成される手順について説明します。図2は、運用者が作成したReplicaSetリソースの定義(YAMLファイル)から実際にReplicaSetリソースが作成されるまでの流れを表しています。

  • 1:
    管理者からAPI ServerにReplicaSetリソースの作成を要求する
  • 2:
    ReplicaSetリソースの定義を保存する
  • 3:
    ReplicaSet ControllerがReplicaSetのリソースからPodのリソースを作成する
  • 4:
    ReplicaSetの実行ワーカノードを決定する
  • 5:
    ワーカノードでReplicaSetを実行する
図2. ReplicaSetリソースの作成フロー

特に注目すべき点は、管理者自身がPodの作成を行っているわけではなく、ReplicaSet Controllerが間接的にPodを作成している点になります。この仕組みから発生する課題がPod Security Policy(PSP)非推奨化の背景の一つになります。

Pod Security Policy非推奨化の背景

Pod Security Policy(PSP)の機能は、Kubernetes のRBAC(Role-based access control)に紐づく形で構成されます。クラスタ管理者、コントロールプレーンの各サービス、ワーカノードで動作する各ポッドなどに、それぞれ個別のポリシを割り当てることで、不適切なPodの実行要求を拒否することが可能でした。図3はポリシの例ですが、特権付与(privileged: false)やnamespaceの共有(hostNetwork: false)など、各種パラメータで許可する項目と拒否する項目を自由に設定できることが分かります。

apiVersion: extensions/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restricted
  annotations:
    seccomp.security.alpha.kubernetes.io/allowedProfileNames: '*'
spec:
  privileged: false  
  allowPrivilegeEscalation: false 
  allowedCapabilities:
  - '*'
  volumes:
  - '*'
  hostNetwork: false 
  hostPorts:
  - min: 0
    max: 65535
  hostIPC: true 
  hostPID: true 
  runAsUser:
    rule: 'MustRunAsNonRoot' 
  seLinux:
    rule: 'RunAsAny'
  supplementalGroups:
    rule: 'RunAsAny'
  fsGroup:
    rule: 'RunAsAny'

図3. Pod Security Policyの制限ポリシ

PSPが廃止される背景として下記のような課題が挙げられています。

  1. DeploymentやReplicaSetでポリシの適用が複雑となる点
  2. 複数のポリシが存在した場合に優先付けを行えない点
  3. Dry-runの機能がなく有効化直後にデフォルトで拒否設定となってしまう点

特に1の課題は、前述したKubernetesの宣言的なアーキテクチャに起因するものといえます。DeploymentやReplicaSetの作成において、Pod作成のリクエストを送信するのはユーザではなくそれぞれのコントローラとなるため、作成を試みた際に、コントローラが利用可能なPSPが存在せずPodが起動しないといったことが起こります。

この挙動を回避するためにはコントローラ自体に権限の高いPSPを付与する、または、必要なPSPが利用できるServiceAccount(Podやユーザに紐づくアカウント)をPodの定義に指定する方法が考えられます。コントローラ自体に権限の高いPSPを付与する方法は、間接的に制限がなくなることを意味するため、不適切といえます。一方、ServiceAccountをPodに指定する方法は、ユーザ自体に紐づけられたPSPが制限されていたとしても、より高い権限のServiceAccount(PSP)でPodを起動できることを意味します。

この仕組みは、API Server以外のコンポーネント(コントローラ等)を意識せずにコンテナアプリケーションを管理している運用者にとっては理解しづらく設定ミスを誘発しやすい仕様と言えます。さらに、PSPはデフォルトで拒否ルールとなる点から事前に適切なポリシを完璧に設定する必要があり、導入の難しさに拍車をかけていました。

Pod Security Policyの代替機能

Pod Security Admissionは、Kubernetes v1.25でGA (General Availability)となったビルトインのポリシ制御機能で、Pod Security Policyの後継機能に該当します。Pod Security AdmissionはPod Security Standardsnew window[2] に準拠した3種類のポリシ(表2)と3種類のモード(表3)を組み合わせてnamespace(Kubernetesにおけるリソースのグループ単位)に紐づけることで適用します。

表2. Pod Security Admissionのポリシ

ポリシ 概要 セキュリティ
privileged コンテナの設定項目に制限を設けないポリシ
Baseline リスクが明確な設定項目のみを制限したポリシ
Restricted 推奨される設定項目までを規定したベストプラクティスに該当するポリシ

表3. Pod Security Admissionのモード

モード ポリシに違反するPodのデプロイに対する挙動
Enforce Podのデプロイを禁止する
audit KubernetesのAudit Logに記録する
warn 警告を表示する

例として、図4のルールを適用した場合、下記のような挙動になります。

  • Baselineポリシに違反するPodのデプロイを禁止する
  • Restrictedポリシに違反するPodのデプロイを検知した場合はAudit Logに記録する
  • Restrictedポリシに違反するPodのデプロイを検知した場合は警告を表示する

apiVersion: v1
kind: Namespace
metadata:
  name: namespace-sample
  labels:
    pod-security.kubernetes.io/enforce: baseline
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

図4. Pod Security Admissionの適用

なお、Pod Security Admission では、DeploymentやReplicaSetのようにPodを内包するリソース自体の制限は行われず、内部処理のPod作成のみがブロックされる仕様になります。また、すべてのnamespaceで適用されるデフォルトポリシの設定では、特定のユーザ(ServiceAccount)やnamespaceを除外することも可能となっています。

注意点として、ReplicaSet ControllerのようにPod作成に関わるコントローラのServiceAccountを制限の対象外とした場合、制限対象のnamespaceであっても、ポリシをバイパスすることが可能になります(図5)。加えて、namespaceの操作権限があればポリシの変更も可能となるため、基本的なRBAC制御にも気を配る必要があります。

図5. Pod Security Admissionのバイパス

総じて、Pod Security Admissionはポリシを単純化することで、設定ミスを誘発する仕様を改善している点が特徴といえます。ただ、ポリシが3種類しかなくPod Security Policyのような柔軟な設定が行えない点は不便となる場合も考えられます。

Pod Security Policy やPod Security AdmissionはKubernetesのビルトイン機能ですが、同様のサードパーティツールとしてOPA Gatekeepernew window[3]、Kyvernonew window[4] 、jsPolicynew window[5]なども開発されています。ここでは、OPA GatekeeperをPod Security Admissionの比較対象として取り上げます。

OPA Gatekeeperは、Kubernetesで取り扱われるリソース定義ファイルに対する検査が可能なポリシ制御ツールです。ポリシはRego言語で記述されるため、Regoに馴染みのない人にとっては導入には一定の学習コストが生じますが、namespaceやpodなどの様々なリソースのパラメータを検査・ブロックすることが可能になります。特に、Podに関するポリシは豊富な設定テンプレート(Gatekeeper Library)が用意されているため、導入が容易かつ柔軟なポリシ設定が行えます。

図6は、特権フラグの付与されたPodをブロックするポリシの例です。このポリシでは、Podの定義ファイルにsecurityContext.privilegedのパラメータが含まれていれば、デプロイの拒否と併せて出力されるメッセージも記述されています。

violation[{"msg": msg, "details": {}}] {
            c := input_containers[_]
            not is_exempt(c)
            c.securityContext.privileged
            msg := sprintf("Privileged container is not allowed: %v, securityContext: %v", [c.name, c.securityContext])
        }

図6. 特権コンテナの制限ポリシ

表4はPod Security Admission と Gatekeeper LibraryにおけるPod(コンテナ)に関連するポリシへの対応状況です。

表4. コンテナ関連対策の対応状況

対策内容 Pod Security Admission Gatekeeper Library
特権コンテナの禁止 対応 対応
namespace共有の禁止 対応 対応
/procにおけるマスクの有効化 対応 対応
HostPathの禁止 対応 対応
HostPortの禁止 対応 対応
Sysctlsの制限 対応 対応
Capabilityの制限 対応 対応
セキュリティ機能(AppArmor、SELinux、Seccomp)の設定 対応 対応
rootユーザでのコンテナ起動の禁止 対応 対応
rootグループでのコンテナ起動の禁止 対応 対応
コンテナ内特権昇格の禁止 対応 対応
Volumeタイプの制限 対応 対応
読取り専用のファイルシステム 非対応 対応
信頼されたリポジトリ 非対応 対応
automountServiceAccountTokenの制限 非対応 対応
計算機リソースの制限 非対応 対応
コンテナイメージタグの制限 非対応 対応
コンテナイメージダイジェストの設定 非対応 対応
コンテナイメージの脆弱性検査 非対応 非対応
コンテナイメージの署名検査 非対応 非対応
コンテナイメージの機密情報 非対応 非対応
コンテナイメージの機能最小化 非対応 非対応

現状は、Gatekeeper Libraryの方が広範囲の対策に対応していることが分かります。加えて、Gatekeeper Libraryはパラメータ単位の設定や対象範囲の調整が可能など、自由度の高い仕様となっています。そのため、厳格なポリシ設定が求められるケースではPod Security Admissionよりも優れた機能といえます。一方、サードパーティツールの導入では、開発終了やKubernetesのバージョン対応のように開発ライフサイクルを意識した運用が求められる点、導入したポリシエンジン自体がアタックサーフェスとなり得る点new window[6]に注意が必要です。Pod Security Admissionは、上記リスクが小さく、導入も容易であるため、厳格なセキュリティ要件が求められないケースでは、選択の余地があるといえます。

まとめ

今回はPod Security Policyが廃止された背景から、Kubernetesのポリシ制御機能に関するテーマを取り上げました。Pod Security Policyの代替となるPod Security AdmissionやOSSでは、課題の一部が解決されているものの、完全解決までには至っておらず、いまだ慎重な運用が求められる状況といえます。

Kubernetesのポリシ制御は扱いが難しいものの、コンテナ本体のセキュリティ対策を担保する上で重要な機能になります。選択肢となる機能・ツールも一長一短であるため、今回ご紹介したビルトイン機能やOSSの特徴が導入判断の参考になれば幸いです。

参考資料

執筆者プロフィール

森本 康太(もりもと こうた)
セキュリティ技術センター セキュリティ実装技術チーム

NECグループのセキュア開発・運用を推進。

執筆者の他の記事を読む

Escキーで閉じる 閉じる