このページに記載されている情報は古い可能性があります
このページの更新日は英語版よりも古いため、記載されている情報が古い可能性があります。最新の情報をご覧になりたい方は英語版のページをご覧ください: Kubernetes API Server Bypass Risks
Kubernetes APIサーバーは、外部の関係者(ユーザーやサービス)がクラスターと対話するための主要なエントリポイントです。
この役割の一環として、APIサーバーには監査ログやアドミッションコントローラーなど、いくつかの重要なセキュリティ制御が組み込まれています。 しかし、これらの制御をバイパスしてクラスターの設定やコンテンツを変更する方法があります。
このページでは、Kubernetes APIサーバーに組み込まれているセキュリティ制御をバイパスする方法について説明します。 これにより、クラスター運用者やセキュリティアーキテクトは、これらのバイパスが適切に制限されるようにできます。
各ノードのkubeletは、特定のディレクトリに保存されているマニフェストや、特定のURLから取得したマニフェストをクラスター内のstatic Podとして読み込み、直接管理します。 APIサーバーはこれらのstatic Podを管理しません。 この場所への書き込みアクセス権を持つ攻撃者は、そのソースから読み込まれたstatic Podの設定を変更したり、新しいstatic Podを導入したりする可能性があります。
Static Podは、Kubernetes API内の他のオブジェクトへのアクセスが制限されています。
例えば、static PodにクラスターからSecretをマウントするように設定することはできません。
ただし、これらのPodは基盤となるノードからhostPathマウントを使用するなど、他のセキュリティ上機微な操作を行うことができます。
デフォルトでは、kubeletはミラーPodを作成し、static PodをKubernetes APIで参照できるようにします。 ただし、攻撃者がPod作成時に無効なNamespaceを指定した場合、Kubernetes APIで参照することはできず、影響を受けるホストにアクセスできるツールでのみ発見できます。
static Podがアドミッション制御に失敗した場合、kubeletはPodをAPIサーバーに登録しません。 ただし、Podはノード上で実行され続けます。 詳細については、kubeadm issue #1541を参照してください。
kubeletは通常、クラスターのワーカーノードのTCPポート10250で公開されるHTTP APIを提供します。 APIは、使用しているKubernetesディストリビューションによっては、コントロールプレーンノードでも公開される場合があります。 APIに直接アクセスすると、ノード上で実行されているPodに関する情報や、これらのPodからのログの開示、およびノード上で実行されているすべてのコンテナ内でのコマンド実行が可能になります。
KubernetesクラスターユーザーがNodeオブジェクトのサブリソースにRBACアクセスを持つ場合、そのアクセスはkubelet APIと対話するための認可を提供します。
正確なアクセスは、kubelet認証で詳しく説明されているように、付与されたサブリソースアクセスに依存します。
kubelet APIに直接アクセスすると、アドミッション制御の対象にならず、Kubernetesの監査ログにも記録されません。 このAPIに直接アクセスできる攻撃者は、特定のアクションを検出または防止する制御をバイパスできる可能性があります。
kubelet APIは、さまざまな方法でリクエストを認証するように構成できます。
デフォルトでは、kubeletの設定は匿名アクセスを許可します。
ほとんどのKubernetesプロバイダーは、デフォルトをwebhookおよび証明書認証を使用するように変更します。
これにより、コントロールプレーンは呼び出し元がnodes APIリソースまたはサブリソースにアクセスする権限があることを確認できます。
デフォルトの匿名アクセスでは、コントロールプレーンでこのアサーションは行われません。
nodes APIオブジェクトのサブリソースへのアクセスを制限します。
監視サービスなど、必要な場合にのみこのアクセスを許可してください。Kubernetesクラスターは、etcdをデータストアとして使用します。
etcdサービスは、TCPポート2379でリッスンします。
アクセスが必要なクライアントは、Kubernetes APIサーバーと使用しているバックアップツールのみです。
このAPIに直接アクセスすると、クラスター内のデータの開示または変更が可能になります。
etcd APIへのアクセスは通常、クライアント証明書認証によって管理されます。 etcdが信頼する認証局によって発行された証明書は、etcd内に保存されているデータへのフルアクセスを許可します。
etcdに直接アクセスすると、Kubernetesのアドミッション制御の対象にならず、Kubernetesの監査ログにも記録されません。 APIサーバーのetcdクライアント証明書の秘密鍵を読み取る権限を持つ(または新しい信頼できるクライアント証明書を作成できる)攻撃者は、クラスターのシークレットにアクセスしたり、アクセスルールを変更したりすることで、クラスター管理者権限を取得できます。 KubernetesのRBAC特権を昇格させなくとも、etcdを変更できる攻撃者は、任意のAPIオブジェクトを取得したり、クラスター内に新しいワークロードを作成したりできます。
多くのKubernetesプロバイダーは、相互TLS(クライアントとサーバーの両方が認証のために互いの証明書を検証)を使用するようにetcdを構成します。 etcd APIには広く受け入れられた認可の実装はありませんが、機能は存在します。 認可モデルが存在しないため、etcdへのクライアントアクセス権限を持つ証明書であれば、etcdへのフルアクセスを取得できます。 通常、ヘルスチェックのみに使用されるetcdクライアント証明書も、完全な読み取りおよび書き込みアクセスを付与できます。
Kubernetesクラスターの各ノードでは、コンテナと対話するためのアクセスはコンテナランタイム(1つ以上のランタイムを構成している場合はそれらのランタイム)によって制御されます。 通常、コンテナランタイムはkubeletがアクセスできるUnixソケットを公開します。 このソケットにアクセスできる攻撃者は、新しいコンテナを起動したり、実行中のコンテナと対話したりする可能性があります。
クラスターレベルでは、このアクセスの影響は、侵害されたノードで実行されているコンテナが、他のワーカーノードやコントロールプレーンのコンポーネントへの特権昇格のために、攻撃者が使用する可能性のあるSecretやその他の機密データにアクセスできるかどうかによって異なります。
rootユーザーにこのアクセスを制限してください。hostPathマウントの使用を、直接または親ディレクトリをマウントすることによって制限または禁止してください。
また、攻撃者がディレクトリ制限をバイパスするリスクを軽減するために、hostPathマウントは読み取り専用として設定する必要があります。