OS ディレクトリのマウント保護を確認すべき Kubernetes コンテナー

OS の重要なパスに書き込み可能なボリュームをマウントすると、システムファイルや設定を変更されるおそれがあります。

説明

/bin や /etc などの重要なパスに書き込み可能なボリュームをマウントすると、コンテナーが使用するバイナリや設定が変更される可能性があります。実際のボリュームが hostPath などでホストのファイルを提供する場合は、ノードにも影響します。コンテナーの mountPath だけでは、ホストのディレクトリが接続されているとは判断できません。

Linux では、readOnly: true だけでは配下のマウントまで読み取り専用になりません。それらも保護する必要がある場合は、対応する環境で recursiveReadOnly: Enabled を使用してください。

想定される影響

  • 書き込み可能なバイナリや設定の改ざんにより、アプリケーションの動作が変わるおそれがあります。
  • ホストのファイルを提供するボリュームでは、ノードや他のワークロードにも影響が及ぶ可能性があります。
  • 読み取り専用にしても、ファイルの内容を読む権限は残ります。

対処方法

  • 重要なパスへの不要なマウントを削除し、必要なファイルだけを適切なボリュームで提供してください。
  • 書き込みが不要なマウントには readOnly: true を設定してください。配下のマウントも保護する場合は recursiveReadOnly: Enabled を追加してください。
  • 再帰的な読み取り専用マウントは Kubernetes 1.33 で安定機能になりました。Linux 5.12 以降と対応するランタイムが必要で、mountPropagation は省略するか None にしてください。互換性とアプリケーションの動作を確認してください。

例

次の Pod の抜粋はマウントオプションを比較します。vol-0 のボリューム定義は省略しているため、実際のソースとコンテナーイメージを確認して設定してください。

変更前

yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-0
spec:
  containers:
    - name: pod-0
      image: k8s.gcr.io/test-webserver
      volumeMounts:
        - mountPath: /bin
          name: vol-0
          readOnly: false
          recursiveReadOnly: Disabled

このマウントは書き込みを許可します。公開されるファイルの範囲は、省略されたボリュームのソースとファイル権限によって異なります。

変更後

yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-0
spec:
  containers:
    - name: pod-0
      image: k8s.gcr.io/test-webserver
      volumeMounts:
        - mountPath: /bin
          name: vol-0
          readOnly: true
          recursiveReadOnly: Enabled

対象コンテナーのマウントとその配下のマウントを読み取り専用にします。カーネルやランタイムの必須条件を満たさなければ Enabled は失敗します。他のコンテナーやパスからの書き込みまで禁止するものではありません。

参考資料