すべてのプロダクト
Search
ドキュメントセンター

Container Service for Kubernetes:ポッドのセキュリティ

最終更新日:Dec 14, 2024

Container Service for Kubernetesでは、複数の方法を使用して、攻撃者がコンテナーのホストにアクセスできるコンテナーエスケープを防ぐことができます。 たとえば、コンテナーの特権モードでの実行を禁止したり、アプリケーションポッドを非rootユーザーとして実行したり、ServiceAccountトークンの自動マウントを無効にしたりできます。 このトピックでは、ポッドのセキュリティポリシーを設定してACKクラスターのセキュリティを強化し、攻撃者からACKクラスターを保護する方法について説明します。

攻撃者が特権をエスカレートできるコンテナエスケープを防止する

Kubernetesの開発者とO&M管理者は、プロセスがコンテナから逃げるのを防ぐ方法に集中する必要があります。 コンテナエスケープを使用すると、攻撃者はコンテナのホストを制御する特権をエスカレートできます。 コンテナのエスケープを防ぐことは、次の理由から重要です。

  • デフォルトでは、コンテナ内のプロセスはLinuxのrootユーザーのコンテキストで実行されます。 rootユーザーが実行できる操作は、Dockerによってコンテナーに割り当てられたLinux機能によって制限されます。 ただし、攻撃者はデフォルトの機能を悪用して特権をエスカレートしたり、ホスト上の機密情報 (SecretsConfigMapsなど) にアクセスしたりする可能性があります。 次のリストは、Dockerコンテナに割り当てられるデフォルトの機能を示しています。 詳細については、「capabilities (7) Linux manual page」をご参照ください。

    cap_chown、cap_dac_override、cap_fowner、cap_fsetid、cap_kill、cap_setgid、cap_setuid、cap_setpcap、cap_net_bind_service、cap_net_raw、cap_sys_chroot、cap_mknod、cap_audit_write、cap_setfcap

    特権コンテナーにはrootユーザーのすべてのLinux機能が割り当てられるため、コンテナーのエスケープを防ぐには、Dockerコンテナーを特権モードで実行しないようにする必要があります。

  • すべてのKubernetesワーカーノードは、特別な権限付与モードであるノードオーソライザを使用します。 ノード承認者は、kubeletによって送信されるすべてのAPIリクエストを承認するために使用されます。 ノード承認者は、ノードが次の操作を実行できるようにもします。

    読み取り操作:

    • サービス

    • エンドポイント

    • ノード

    • ポッド

    • kubeletが実行されているノードにデプロイされているポッドのSecrets、ConfigMaps、永続ボリューム (PV) 、および永続ボリュームクレーム (PVC)

    書き込み操作:

    • ノードとノードのステータス。 NodeRestrictionアドミッションコントローラーを有効にして、kubeletが実行されているノードのみを変更できるようにすることができます。

    • ポッドとポッドのステータス。 NodeRestrictionアドミッションコントローラーを有効にして、kubeletが実行されているノードにバインドされているポッドのみをkubeletが変更できるようにすることができます。

    • Events

    認証関連の操作:

    • トランスポート層セキュリティ (TLS) ブートストラップ用のCertificateSigningRequest (CSR) APIの読み取りおよび書き込み権限

    • 委任されたID認証と承認を確認するためにTokenReviewSubjectAccessReviewを作成する権限

デフォルトでは、ACKクラスターはNodeRestrictionアドミッションコントローラーを使用します。 NodeRestrictionアドミッションコントローラーを使用すると、kubeletはノードにバインドされているノード属性とポッドオブジェクトの限られたセットのみを変更できます。 ただし、承認コントローラーは、攻撃者がKubernetes APIを使用してクラスター環境に関する機密情報を収集するのを防ぐことはできません。 詳細については、「NodeRestriction」をご参照ください。

ポッドのセキュリティに関する提案

  • コンテナーの特権モードでの実行を禁止

    特権コンテナは、同じホスト上のrootユーザーのすべてのLinux機能を継承します。 ほとんどのシナリオでは、コンテナーはワークロードを処理するためにこれらの機能を必要としません。 ポッドを特権モードで実行することを禁止するポッドセキュリティポリシーを作成できます。 ポッドセキュリティポリシーは、ポッドを作成する前にポッドが満たす必要がある制約のグループです。 ACKを使用すると、Open Policy Agent (OPA) とGatekeeperに基づいてポッドセキュリティポリシーを設定できます。 ポリシーは、設定したセキュリティルールに基づいて、クラスター内のポッドの作成と更新の要求を検証するために使用されます。 ポッドを作成または更新する要求が設定されたルールを満たさない場合、要求は拒否され、エラーが返されます。 ACKPSPBrivilegedContainerセキュリティポリシーを使用して、クラスターの指定された名前空間内での特権コンテナのデプロイを禁止することもできます。

  • ポッドを非rootユーザーとして実行する

    デフォルトでは、すべてのコンテナーはrootユーザーとして実行されます。 攻撃者は、アプリケーションの脆弱性を悪用し、実行中のコンテナのシェルにアクセスできます。 そのため、セキュリティ上のリスクが発生します。 複数の方法を使用してリスクを軽減できます。 コンテナイメージからシェルを削除できます。 DockerfileにUSER命令を追加したり、非rootユーザーとしてコンテナーを実行したりすることもできます。 podSpecのspec.securityContext属性には、runAsUserフィールドとrunAsGroupフィールドが含まれます。 2つのフィールドは、コンテナーを実行するユーザーとユーザーグループを指定します。 ACKPSPAllowedUsersポリシーを作成して、指定されたユーザーとユーザーグループのみがコンテナーを実行できるようにすることができます。

  • ユーザーがDocker-in-Dockerモードでコンテナを実行したり、Docker.sockをコンテナにマウントしたりすることを禁止

    Docker-in-Dockerメソッドを使用するか、Docker.sockをコンテナーにマウントすることで、Dockerコンテナー内にコンテナーイメージを効率的にビルドまたはデプロイできます。 ただし、そうすることで、コンテナ内で実行されているプロセスにノードの制御が許可されます。 Kubernetesでコンテナイメージを構築する方法の詳細については、「container Registry Enterprise Editionインスタンスを使用してイメージを構築する」、「kaniko」、および「img」をご参照ください。

  • hostPathボリュームの使用を制限するか、プレフィックスを指定したディレクトリへのhostPathボリュームのマウントのみを許可し、ボリュームを読み取り専用に設定します

    hostPathボリュームは、ホストからポッドにディレクトリをマウントします。 ほとんどの場合、ポッドはhostPathボリュームを必要としません。 hostPathボリュームを使用する必要がある場合は、必ずリスクを理解してください。 デフォルトでは、root権限で実行されるポッドには、hostPathボリュームを使用して公開されるファイルシステムに対する書き込み権限があります。 攻撃者は、kubelet設定を変更し、hostPathボリュームによって直接公開されないディレクトリまたはファイルへのシンボリックリンクを作成できます。 たとえば、攻撃者は /etc/shadowへのアクセス、SSHキーのインストール、ホストにマウントされているSecretsの読み取り、その他の悪意のあるアクティビティを実行できます。 hostPathボリュームから発生するリスクを軽減するには、spec.containers.volumeMountsを読み取り専用に設定します。 サンプルコード:

    volumeMounts:
    - name: hostPath-volume
        readOnly: true
        mountPath: /host-path

    また、ACKPSPHostFlesystemポリシーを展開して、hostPathボリュームを使用して、クラスターの指定された名前空間内のポッドにマウントできるホストディレクトリを制限することもできます。

  • リソースの競合を防ぎ、DoS攻撃から保護するために、各コンテナにリソース要求と制限を設定します

    リソース要求または制限がないポッドは、ホスト上のすべてのリソースを消費する可能性があります。 追加のポッドがノードにスケジュールされている場合、ノードのCPUまたはメモリリソースが不十分になる可能性があります。 その結果、kubeletがクラッシュしたり、ポッドがノードから追い出されたりする可能性があります。 この問題は避けられません。 ただし、リソース要求と制限を設定して、リソースの競合を最小限に抑え、不適切にプログラムされたアプリケーションが過剰なリソースを消費するリスクを減らすことができます。

    podSpecでCPUおよびメモリリソースのリクエストと制限を指定できます。 名前空間にリソースクォータまたは制限範囲を設定して、リクエストとリソースの使用を強制的に制限できます。 リソースクォータは、CPUリソースやメモリリソースなど、名前空間に割り当てられるリソースの合計量を指定します。 名前空間にリソースクォータを適用すると、その名前空間にデプロイされたすべてのコンテナのリクエストと制限を強制的に指定します。 制限範囲を使用して、割り当てられるリソースに対してきめ細かい制御を実施することができる。 制限範囲を設定して、名前空間内の各ポッドまたはコンテナーが使用できるCPUおよびメモリリソースの最大量と最小量を指定できます。 制限範囲を使用して、デフォルトのリクエスト値を設定したり、デフォルト値が指定されていない場合は制限値を設定したりできます。 詳細については、「コンテナーのリソースの管理」をご参照ください。

    ACKContainerLimitsポリシーをデプロイして、クラスターの指定された名前空間のポッドにリソース制限を適用することもできます。

  • 特権エスカレーションの禁止

    特権エスカレーションは、プロセスが実行するセキュリティコンテキストを変更することを可能にする。 たとえば、sudoファイルは、SUIDまたはSGIDビットを持つバイナリファイルです。 特権エスカレーションは、ユーザーが別のユーザーまたはユーザーグループの権限を持つファイルを実行するために使用できるメソッドです。 特権エスカレーションを防止するには、allowPriviledgedEscalationパラメーターをfalseに設定するpodセキュリティポリシーを使用するか、podSpecsecurityContext.allowPrivilegedEscalationを指定します。

    ACKPSPAllowPrivilegeEscalationContainerポリシーをデプロイして、クラスターの指定された名前空間のポッドに対してallowPrivilegeEscalationパラメーターの設定を強制することもできます。

  • ServiceAccountトークンの自動マウントを無効にする

    Kubernetes APIにアクセスする必要がないポッドの場合は、特定のポッドのpodSpecServiceAccountトークンの自動マウントを無効にするか、特定のServiceAccountを使用するすべてのポッドでこの機能を無効にできます。

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-no-automount
    spec:
      automountServiceAccountToken: false

    ポッドのServiceAccountトークンの自動マウントを無効にした後も、ポッドはKubernetes APIにアクセスできます。 ポッドがKubernetes APIにアクセスしないようにするには、ACKクラスターのエンドポイントのアクセス制御を規制し、ポッドをブロックするようにネットワークポリシーを設定する必要があります。 詳細については、「ACKクラスターでのネットワークポリシーの使用」をご参照ください。

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: sa-no-automount
    automountServiceAccountToken: false

    ACKBlockAutomountTokenポリシーをデプロイして、アプリケーションポッドのautomountServiceAccountToken: falseフィールドの設定を強制し、ServiceAccountトークンの自動マウントを防止することもできます。

  • サービス検出の無効化

    ポッドがクラスターサービスを検索したり呼び出したりする必要がない場合は、ポッドに提供される情報量を減らすことができます。 ポッドのドメインネームシステム (DNS) ポリシーを設定して、CoreDNSを使用せず、ポッドの名前空間の環境変数としてサービスを公開しないようにすることができます。 詳しくは、『Environment variables』をご参照ください。

    デフォルトでは、ポッドのDNSポリシーはClusterFirstに設定されているため、ポッドはクラスター内DNSサービスを使用する必要があります。 DNSポリシーがデフォルトに設定されている場合、ポッドは基になるノードからDNS解決設定を使用する必要があります。 詳細については、「ポッドのDNSポリシー」をご参照ください。

    サービスリンクを無効にしてポッドのDNSポリシーを変更しても、ポッドは引き続きクラスター内DNSサービスにアクセスできます。 攻撃者は、クラスター内DNSサービスにアクセスすることで、ACKクラスター内のサービスを列挙できます。 たとえば、攻撃者はdig SRV *.*.svc.cluster.local @$CLUSTER_DNS_IPコマンドを実行して、クラスター内のサービスを検出できます。 クラスターでのサービス検出を防止する方法の詳細については、「ACKクラスターでのネットワークポリシーの使用」をご参照ください。

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-no-service-info
    spec:
        dnsPolicy: Default # The value Default does not indicate the default setting of a DNS policy. 
        enableServiceLinks: false
  • 読み取り専用ファイルシステムを使用するようにコンテナイメージを構成する

    読み取り専用ファイルシステムを使用するようにコンテナイメージを構成して、アプリケーションで使用されるファイルシステム内のファイルを攻撃者が上書きしないようにすることができます。 アプリケーションがファイルシステムにデータを書き込む必要がある場合は、一時ディレクトリに書き込むか、ボリュームをアプリケーションにマウントするようにアプリケーションを設定できます。 次のポッドSecurityContextを設定することで、読み取り専用ファイルシステムを使用するようにコンテナイメージを構成できます。

    ...
    securityContext:
      readOnlyRootFilesystem: true
    ...

    ACKPSPReadOnlyRootFilesystemポリシーをデプロイして、クラスターの指定された名前空間内のポッドに対して読み取り専用のルートファイルシステムの使用を強制することもできます。