Container Service for Kubernetes では、コンテナー内のプロセスが隔離境界からエスケープしてホストにアクセスすることを防ぐことができます。これには、コンテナーが特権モードで実行されるのを制限し、アプリケーションプロセスが root ユーザーとして実行されるのを制限し、Service Account トークンの自動マウントを無効にすることが含まれます。Pod セキュリティポリシーを設定することで、クラスターのセキュリティを強化し、攻撃者の標的になるのを防ぐことができます。
コンテナー境界からのプロセスのエスケープと権限取得の防止
Kubernetes を使用する開発者または運用保守エンジニアにとって、コンテナー内のプロセスが隔離境界からエスケープしてホストにアクセスすることを防ぐことは非常に重要です。これには主に 2 つの理由があります:
第一に、コンテナー内のプロセスは、デフォルトで
Linux rootユーザーのコンテキストで実行されます。コンテナー内のrootユーザーの操作は、Docker がコンテナーに割り当てるLinux capabilitiesによって部分的に制限されますが、これらのデフォルトの権限により、攻撃者が権限を昇格させたり、ホスト上の機密情報にアクセスしたりする可能性があります。これには、SecretやConfigMapオブジェクトなどの機密リソースが含まれます。以下は、Docker コンテナーに割り当てられるデフォルトのcapabilitiesのリストです。詳細については、「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可能な限り、特権ステータス (
privileged) で Pod を実行することは避けてください。特権ステータスを持つ Pod は、ホスト上の root ユーザーに関連付けられたすべての Linuxcapabilitiesを継承するためです。第二に、すべての Kubernetes ワーカーノードは、ノードオーソライザーと呼ばれる権限付与モードを使用します。ノードオーソライザーは、Kubelet から発信されるすべての API リクエストに権限を付与し、ノードが次の操作を実行できるようにします:
読み取り操作:
サービス
エンドポイント
ノード
ポッド
Kubelet ノードにバインドされている Pod に関連する Secret、ConfigMap、PersistentVolume (PV)、および PersistentVolumeClaim (PVC)
書き込み操作:
ノードとノードステータス (
NodeRestrictionアドミッションプラグインを有効にして、Kubelet が自身のノードオブジェクトのみを変更できるように制限します)Pod と Pod ステータス (
NodeRestrictionアドミッションプラグインを有効にして、Kubelet が自身にバインドされている Pod のみを変更できるように制限します)イベント
認証関連の操作:
TLS ブートストラップのための
CertificateSigningRequest (CSR)API への読み取り/書き込みアクセス委任された ID 認証と認可チェックのための
TokenReviewおよびSubjectAccessReviewの作成機能
ACK クラスターは、デフォルトで Node Restriction アドミッションコントローラーを使用します。このコントローラーは、ノードが限られたセットのノードプロパティと、それにバインドされた Pod オブジェクトのみを変更できるようにします。しかし、ホストへのアクセスに成功した攻撃者は、Kubernetes API を通じて環境から機密情報を取得する可能性があります。詳細については、「Node Restriction アドミッションコントローラー」をご参照ください。
Pod セキュリティ設定の推奨事項
特権モードでのコンテナーの実行の制限
前述のように、特権ステータスで実行されるコンテナーは、ホスト上の root ユーザーに割り当てられたすべての Linux capabilities を継承します。ほとんどのシナリオでは、コンテナーが正しく機能するためにこれらの権限は必要ありません。Pod セキュリティポリシーを作成して、特権モードで実行するように設定された Pod を拒否できます。Pod セキュリティポリシーは、Pod が作成される前に満たす必要があるセキュリティ制約のセットです。ACK は、Open Policy Agent (OPA) と Gatekeeper に基づくコンテナーセキュリティポリシー機能を提供します。これらの機能は、ユーザーが設定したセキュリティルールに基づいて、クラスター上の Pod の作成および更新リクエストを検証します。Pod の作成または更新リクエストが定義されたルールに準拠していない場合、システムはリクエストを拒否し、エラーを返します。同様に、ACKPSPPrivilegedContainer ポリシーをデプロイして、クラスター内の指定された名前空間での特権コンテナーのデプロイメントを制限できます。
root ユーザーとしてのアプリケーションプロセスの実行の制限
デフォルトでは、コンテナーは root ユーザーとして実行されます。これは、攻撃者がアプリケーションの脆弱性を悪用して実行中のコンテナーへのシェルアクセスを取得した場合、セキュリティ上の問題になる可能性があります。このリスクはいくつかの方法で軽減できます。1 つの方法は、コンテナーイメージからシェルを削除することです。もう 1 つの方法は、Dockerfile に USER 命令を追加するか、Pod 内のコンテナーを非 root ユーザーとして実行することです。Kubernetes の podSpec には、
spec.securityContext、runAsUser、およびrunAsGroupフィールドが含まれています。これらのフィールドを使用すると、アプリケーションを実行するユーザーとグループを指定できます。この制限を強制するために、ACKPSPAllowedUsers ポリシーを作成できます。Docker-in-Docker モードでのコンテナーの実行またはコンテナーへの Docker.sock のマウントの禁止
ネストされたコンテナーを使用したり、Docker.sock をマウントしたりすると、Docker コンテナー内でコンテナーイメージを簡単にビルドまたは実行できます。ただし、これにより、コンテナー内で実行されているプロセスがノードを制御できるようになります。Kubernetes でのコンテナーイメージのビルドに関する詳細については、「Enterprise Edition インスタンスを使用したイメージのビルド」、「Kaniko」、および「img」をご参照ください。
HostPath の使用の制限、および使用が必須な場合は、指定されたプレフィックスを持つディレクトリのみをマウントし、ボリュームを読み取り専用として設定
HostPathを使用して、ホストディレクトリをコンテナーに直接マウントできます。この機能は、一部のビジネスシナリオでのみ必要です。ビジネスでこの機能が必要な場合は、関連するリスクを理解する必要があります。デフォルトでは、root として実行されている Pod は、HostPathによって公開されたファイルシステムへの書き込みアクセス権を持ちます。このアクセスにより、攻撃者はKubeletの設定を変更したり、HostPathを通じて直接公開されていないディレクトリやファイル (/etc/shadowなど) へのシンボリックリンクを作成したり、SSH キーをインストールしたり、ホストにマウントされたシークレットを読み取ったり、その他の悪意のある操作を実行したりする可能性があります。HostPathの使用に伴うリスクを軽減するには、spec.containers.volumeMountsフィールドを読み取り専用に設定します。例:volumeMounts: - name: hostPath-volume readOnly: true mountPath: /host-path同様に、ACKPSPHostFilesystem ポリシーインスタンスをデプロイして、クラスターの指定された名前空間にデプロイされた Pod がマウントできるホストディレクトリの範囲を制限できます。
各コンテナーへのリクエストとリソース制限の設定によるリソース競合または DoS 攻撃の回避
リクエストまたはリソース制限のない Pod は、理論的にはホストで利用可能なすべてのリソースを消費する可能性があります。Pod がこのノードにスケジュールされると、ノードで CPU またはメモリが不足する可能性があります。これにより、
Kubeletがクラッシュしたり、他の Pod がノードから退去させられたりする可能性があります。これを完全に回避することはできませんが、リクエストとリソース制限を設定することで、リソース競合を最小限に抑えることができます。また、不適切に記述されたアプリケーションによる過剰なリソース消費のリスクも軽減されます。podSpec を使用すると、CPU とメモリの使用量を制限できます。Resource Quota を設定するか、名前空間に Limit Range を作成することで、リクエストとリソースの制限を強制できます。リソースクォータを使用すると、CPU や RAM など、名前空間に割り当てられるリソースの総量を指定できます。名前空間に適用すると、その名前空間にデプロイされるすべてのコンテナーに対してリクエストと制限を指定する必要があります。対照的に、リミットレンジは、リソース割り当てをより詳細に制御します。リミットレンジを使用すると、名前空間内の各 Pod またはコンテナーの最小および最大の CPU およびメモリリソースを設定できます。値が指定されていない場合は、デフォルトのリクエスト値と制限値を設定することもできます。詳細については、「コンテナーのリソース管理」をご参照ください。
同様に、ACKContainerLimits ポリシーインスタンスをデプロイして、クラスターの指定された名前空間にデプロイされたアプリケーション Pod にリソース制限が設定されていることを要求できます。
権限昇格設定の無効化
権限昇格により、プロセスは実行されるセキュリティコンテキストを変更できます。例としては、
sudoやSUIDまたはSGIDビットを持つバイナリファイルなどがあります。権限昇格により、ユーザーは別のユーザーまたはグループの権限でファイルを実行できます。allowPrivilegeEscalationをfalseに設定するpodセキュリティポリシーを使用するか、podSpecでsecurityContext.allowPrivilegeEscalationを設定することで、コンテナーが権限を昇格するのを防ぐことができます。同様に、ACKPSPAllowPrivilegeEscalationContainer ポリシーインスタンスをデプロイして、クラスターの指定された名前空間にデプロイされた Pod に allowPrivilegeEscalation パラメーターが設定されていることを要求できます。
Service Account トークンの自動マウントの無効化
Kubernetes API にアクセスする必要がない Pod については、
PodSpecでServiceAccountトークンの自動マウントを無効にできます。また、特定のServiceAccountを使用するすべての Pod に対して無効にすることもできます。apiVersion: v1 kind: Pod metadata: name: pod-no-automount spec: automountServiceAccountToken: false ...ServiceAccountの自動マウントを無効にしても、Pod の Kubernetes API へのネットワークアクセスはブロックされません。Pod の Kubernetes API へのネットワークアクセスをブロックするには、ACK クラスターのEndpointのアクセス方法を変更し、ネットワークポリシーを使用して Pod のネットワークアクセスをブロックします。詳細については、「ACK クラスターでのネットワークポリシーの使用」をご参照ください。apiVersion: v1 kind: ServiceAccount metadata: name: sa-no-automount automountServiceAccountToken: false ...同様に、ACKBlockAutomountToken ポリシーインスタンスをデプロイして、アプリケーション Pod に
automountServiceAccountToken: falseフィールドを設定して Service Account の自動マウントを防ぐことを要求できます。サービスディスカバリーの無効化
クラスターサービスを検出または呼び出す必要がない Pod については、Pod に提供される情報を制限できます。Pod の DNS ポリシーを CoreDNS を使用しないように設定し、名前空間内の Service が Pod 内の環境変数として公開されるのを防ぐことができます。詳細については、「環境変数」をご参照ください。
Pod の DNS ポリシーのデフォルト値は
ClusterFirstで、クラスター内 DNS を使用します。値Defaultはデフォルト設定ではなく、Pod が基盤となるノードの DNS 解像度を使用するように設定します。詳細については、「Pod の DNS ポリシーに関する Kubernetes ドキュメント」をご参照ください。サービスリンクを無効にし、Pod の DNS ポリシーを変更しても、Pod のクラスター内 DNS サービスへのネットワークアクセスはブロックされません。攻撃者は、クラスター内 DNS サービスにアクセスすることで、クラスター内のサービスを列挙できます (例:
dig SRV *.*.svc.cluster.local @$CLUSTER_DNS_IP)。クラスター内サービスディスカバリーをブロックするには、「ACK クラスターでのネットワークポリシーの使用」をご参照ください。apiVersion: v1 kind: Pod metadata: name: pod-no-service-info spec: dnsPolicy: Default # 値 "Default" は実際のデフォルトではありません。 enableServiceLinks: false ...読み取り専用ファイルシステムを持つイメージの設定
イメージが読み取り専用ファイルシステムを持つように設定することで、攻撃者がアプリケーションが使用するファイルシステム上のファイルを上書きするのを防ぐことができます。アプリケーションがファイルシステムに書き込む必要がある場合は、一時ディレクトリに書き込むか、追加のボリュームをマウントできます。これは、Pod の
SecurityContextを次のように設定することで強制できます:... securityContext: readOnlyRootFilesystem: true ...同様に、ACKPSPReadOnlyRootFilesystem ポリシーインスタンスをデプロイして、クラスターの指定された名前空間にデプロイされた Pod が読み取り専用のルートファイルシステムのみを使用するように制限できます。