堅牢化ガイド - 認証メカニズム
適切な認証メカニズムの選択はクラスターのセキュリティ確保において重要です。 Kubernetesはいくつかの組み込みのメカニズムを提供しており、それぞれに長所と短所があります。 クラスターに最適な認証メカニズムを選択する際は、これらを慎重に検討する必要があります。
一般的に、有効にする認証メカニズムをできるだけ少なくすることが推奨されています。 これはユーザー管理を単純化し、不要となったクラスターへのアクセス権をユーザーが保持し続けることを防ぐためです。
重要な注意点として、Kubernetesはクラスター内に組み込みのユーザーデータベースを持っていません。 代わりに、設定された認証システムからユーザー情報を取得し、それを使用して認可の判断を行います。 そのため、ユーザーアクセスを監査するには、設定されているすべての認証ソースの認証情報を確認する必要があります。
複数のユーザーが直接Kubernetes APIにアクセスする本番環境のクラスターでは、OIDCなどの外部認証ソースを使用することが推奨されています。 以下で説明するクライアント証明書やサービスアカウントトークンなどの内部認証メカニズムは、このユースケースには適していません。
X509クライアント証明書認証
Kubernetesは、kubeletがAPIサーバーに対して認証を行う場合など、システムコンポーネントにX509クライアント証明書認証を活用します。 このメカニズムはユーザー認証にも使用できますが、以下の制限により本番環境での使用には適さない可能性があります:
- クライアント証明書は個別に無効化することができません。 証明書が漏洩した場合、有効期限が切れるまで攻撃者に使用される可能性があります。 このリスクを軽減するため、クライアント証明書を使用して作成されたユーザー認証情報には短い有効期限を設定することが推奨されます。
- もし証明書を無効にする必要がある場合、認証局の鍵の再生成が必要となり、クラスターの可用性にリスクをもたらす可能性があります。
- クラスター内で作成されたクライアント証明書の永続的な記録は残りません。 そのため、証明書を追跡する必要がある場合は、発行されたすべての証明書を記録しておく必要があります。
- クライアント証明書認証に使用する秘密鍵はパスワードで保護することができません。 鍵を含むファイルを読み取ることができる人は誰でもそれを使用できます。
- クライアント証明書認証を使用するためには、クライアントからAPIサーバーへ直接接続する必要があり、TLS終端点を介在させることができません。 これにより、ネットワークアーキテクチャが複雑になる可能性があります。
- グループデータはクライアント証明書の
O
値に埋め込まれているため、証明書の有効期間中はユーザーのグループメンバーシップを変更することができません。
静的なトークンファイル
Kubernetesではコントロールプレーンノードのディスクにある静的なトークンファイルから認証情報を読み込むことができますが、以下の理由により本番環境のサーバーではこの方法は推奨されません:
- 認証情報がコントロールプレーンノードのディスクに平文で保存されるため、セキュリティ上のリスクとなる可能性があります。
- 認証情報を変更するためには、APIサーバーのプロセスを再起動する必要があり、可用性に影響を与える可能性があります。
- 認証情報のローテーションを可能にするメカニズムは存在しません。 認証情報をローテーションするためには、クラスター管理者がディスク上のトークンを変更し、ユーザーに配布する必要があります。
- ブルートフォース攻撃を防ぐためのロックアウトメカニズムは存在しません。
ブートストラップトークン
ブートストラップトークンはノードをクラスターに参加させるために使用されます。 以下の理由により、ユーザー認証には推奨されません:
- ハードコードされたグループメンバーシップを持っており、一般的な使用に適していないため、認証の目的には適していません。
- ブートストラップトークンを手動で生成すると、攻撃者が推測可能な脆弱なトークンが生成される可能性があり、セキュリティ上のリスクとなります。
- ブルートフォース攻撃を防ぐためのロックアウトメカニズムが存在しないため、攻撃者がトークンを推測または解読しやすくなります。
サービスアカウントシークレットトークン
サービスアカウントシークレットは、クラスター内で実行されるワークロードがAPIサーバーに対して認証を行うためのオプションとして利用できます。 Kubernetes 1.23より前のバージョンではデフォルトのオプションでしたが、現在はTokenRequest APIトークンに置き換えられています。 これらのSecretはユーザー認証に使用できますが、以下の理由により一般的に不適切です:
- 有効期限を設定することができず、関連付けられたサービスアカウントが削除されるまで有効なままとなります。
- トークンはそれらが定義されているNamespace内でSecretを読み取ることができる任意のクラスターユーザーが閲覧できます。
- サービスアカウントは任意のグループに追加できないため、それらを使用する場合にRBACの管理が複雑になります。
TokenRequest APIトークン
TokenRequest APIは、APIサーバーまたはサードパーティシステムへのサービス認証のために有効期間の短い認証情報を生成するために有用なツールです。 ただし、認証情報の失効方法が無いため、一般的にユーザー認証には推奨されず、ユーザーへの認証情報の安全な配布が困難です。
TokenRequestトークンをサービス認証に使用する場合、トークンが漏洩した際の影響を軽減するために、短い有効期間を設定することが推奨されます。
OpenID Connectトークン認証
Kubernetesは、OpenID Connect (OIDC)を使用した外部認証サービスとKubernetes APIとの統合をサポートしています。 Kubernetesをアイデンティティプロバイダーと統合するために使用できるソフトウェアは多岐にわたります。 しかし、KubernetesでOIDC認証を使用する際は、以下のセキュリティ強化策を考慮することが重要です:
- OIDC認証をサポートするためにクラスターにインストールされたソフトウェアは、高い権限で実行されるため、一般的なワークロードから分離する必要があります。
- 一部のKubernetesマネージドサービスでは、使用できるOIDCプロバイダーが制限されています。
- TokenRequestトークンと同様に、トークンが漏洩した際の影響を軽減するため、OIDCトークンは短い有効期間を設定する必要があります。
Webhookトークン認証
Webhookトークン認証は、外部認証プロバイダーをKubernetesに統合するもう一つのオプションです。 この認証メカニズムを用いると、クラスター内部または外部で実行される認証サービスに対してWebhookを介して認証の判断を問い合わせることができます。 この認証メカニズムへの適合性は認証サービスに使用されるソフトウェアに依存する可能性が高く、Kubernetes特有の考慮事項があることに注意が必要です。
Webhook認証を設定するには、コントロールプレーンサーバーのファイルシステムへのアクセスが必要です。 そのため、プロバイダーが特別に利用可能にしない限り、マネージドKubernetesでは使用できません。 また、このアクセスをサポートするためにクラスターにインストールされるソフトウェアは高い権限で実行されるため、一般的なワークロードから分離する必要があります。
認証プロキシ
認証プロキシは、外部認証システムをKubernetesに統合するもう一つのオプションです。 この認証メカニズムでは、Kubernetesは認可のために割り当てるユーザー名とグループメンバーシップを示す特定のヘッダー値が設定されたリクエストをプロキシから受け取ることを想定しています。 この認証メカニズムを使用する際には、特定の考慮事項に注意する必要があります。
まず、トラフィックの傍受やスニッフィング攻撃のリスクを軽減するため、プロキシとKubernetes APIサーバー間では安全に設定されたTLSを使用する必要があります。 これにより、プロキシとKubernetes APIサーバー間の通信の安全性が確保されます。
次に、リクエストヘッダーを改ざんできる攻撃者がKubernetesリソースへの不正アクセスを取得できる可能性があることを認識することが重要です。 そのため、ヘッダーが適切に保護され、改ざんされないようにすることが重要です。