クラスタのセキュリティの強化

Kubernetes での開発速度に伴い、使用できるセキュリティ機能が新たに登場することがよくあります。このページでは、Google Kubernetes Engine クラスタを強化するための最新ガイダンスを実践する方法について説明します。セキュリティ トピックの概要については、セキュリティの概要をお読みください。

Kubernetes ウェブ UI(ダッシュボード)を無効にする

Kubernetes ウェブ UI(ダッシュボード)は、GKE で実行時には無効にする必要があります。

Kubernetes ウェブ UI(ダッシュボード)には、高い特権を持つ Kubernetes サービス アカウントが付いています。Cloud Console にほぼ同じ機能があるため、こうした権限は必要ありません。

Kubernetes ウェブ UI を無効にするには、次のコマンドを実行します。

gcloud container clusters update [CLUSTER_NAME] \
    --update-addons=KubernetesDashboard=DISABLED

ABAC を無効にする

GKE で、属性ベースのアクセス制御(ABAC)を無効にして、代わりに役割ベースのアクセス制御(RBAC)を使用する必要があります。

Kubernetes では、RBAC を使用してリソースに対する権限をクラスタレベルと名前空間レベルで付与します。RBAC では、一連の権限を含むルールを使用して役割を定義できます。RBAC には重要なセキュリティ上の利点があり、現在 Kubernetes で安定しているため、ABAC を無効にしてください。

まだ ABAC に依存している場合は、まず RBAC を使用する場合の前提条件を確認してください。クラスタを古いバージョンからアップグレードして ABAC を使用している場合は、次のようにアクセス制御の構成を更新する必要があります。

gcloud container clusters update [CLUSTER_NAME] \
    --no-enable-legacy-authorization

上記の推奨に従って新しいクラスタを作成するには、次のコマンドを実行します。

gcloud container clusters create [CLUSTER_NAME] \
    --no-enable-legacy-authorization

ポッド間のトラフィックをネットワーク ポリシーで制限する

デフォルトでは、クラスタ内のすべてのポッドが相互通信できます。ポッド間通信は、ワークロードのニーズに応じて制御する必要があります。

Kubernetes のネットワーク ポリシーを使用すると、攻撃者によるクラスタ内の移動をはるかに困難にできます。Kubernetes ネットワーク ポリシー API を使用して、ポッドレベルのファイアウォール ルールを作成することもできます。これらのファイアウォール ルールは、クラスタ内でどのポッドとどのサービスが互いにアクセスできるかを決定します。

新しいクラスタを作成するときにネットワーク ポリシーが適用されるようにするには、--enable-network-policy フラグを指定します。

gcloud container clusters create [CLUSTER_NAME] \
    --zone=[ZONE] \
    --enable-network-policy

ネットワーク ポリシーを有効にしたら、ポリシーを実際に定義する必要があります。これは実際のトポロジに固有のポリシーとなるため、具体的に推奨できません。しかし Kubernetes のドキュメントには、簡単な nginx デプロイの優れたチュートリアルがあります。

GKE のネットワーク ポリシーについて詳しくは、クラスタ ネットワーク ポリシーの設定をご覧ください。

権限が最小限のサービス アカウントをノードで使用する

各 GKE ノードには、IAM サービス アカウントが関連付けられています。デフォルトでは、ノードに Compute Engine のデフォルトのサービス アカウントが与えられています。このアカウントは、Cloud Console の IAM セクションに移動すると見つかります。このアカウントには広範なアクセス権がデフォルトであり、さまざまな用途に役立ちますが、Kubernetes Engine クラスタの実行に必要な権限より多くの権限があります。Compute Engine のデフォルト サービス アカウントを使用するのでなく、権限が最小限のサービス アカウントを作成して、GKE クラスタを実行するときに使用する必要があります。

GKE では、最低でも、サービス アカウントに monitoring.viewermonitoring.metricWriterlogging.logWriter の役割が必要です。詳細については、モニタリングの役割ロギングの役割をご覧ください。

以下のコマンドは、GKE を操作するために必要な最低限の権限を持つ IAM サービス アカウントを作成します。

gcloud iam service-accounts create [SA_NAME] \
    --display-name=[SA_NAME]

gcloud projects add-iam-policy-binding [PROJECT_ID] \
    --member "serviceAccount:[SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com" \
    --role roles/logging.logWriter

gcloud projects add-iam-policy-binding [PROJECT_ID] \
    --member "serviceAccount:[SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com" \
    --role roles/monitoring.metricWriter

gcloud projects add-iam-policy-binding [PROJECT_ID] \
    --member "serviceAccount:[SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com" \
    --role roles/monitoring.viewer

Google Container Registry の非公開イメージを使用する場合は、それらのイメージに対するアクセス権も付与する必要があります。

gcloud projects add-iam-policy-binding [PROJECT_ID] \
  --member "serviceAccount:[SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com" \
  --role roles/storage.objectViewer

クラスタがすでに存在する場合は、この新しいサービス アカウントを使用して新しいノードプールを作成できます。

gcloud container node-pools create [NODE_POOL] \
  --service-account=[SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com" \
  --cluster=[CLUSTER_NAME]

GKE クラスタが他の Google Cloud サービスにアクセスできるようにする必要がある場合は、追加のサービス アカウントを作成して、このサービス アカウントへのアクセス権をワークロードに与えるためにその秘密鍵を Kubernetes Secret に保存してください。詳しくは、サービス アカウントを使用した Google Cloud Platform への認証をご覧ください。

ノードのサービス アカウントのスコープを減らす

カスタム サービス アカウントを使用しない場合は、デフォルトのノードサービス アカウントの権限を減らすことをおすすめします。

デフォルトでは、ノードのサービス アカウントにはアクセス スコープがあります。アクセス スコープは、インスタンスの権限を指定するレガシーな方法です。IAM の役割が存在する前は、アクセス スコープがサービス アカウントに権限を付与する唯一のメカニズムでした。

ノードに個別のサービス アカウントを作成しない場合は、ノードサービス アカウントのスコープを制限して、攻撃における権限エスカレーションの可能性を減らす必要があります。 これにより、デフォルト サービス アカウントの権限が、クラスタを実行するために必要な権限を上回ることがなくなります。デフォルトのスコープは制限されていますが、クラスタの実行に必要な最小限のスコープを上回るスコープが含まれる場合があります。

GKE のノードのデフォルト スコープは、devstorage.read_onlylogging.writemonitoringservice.management.readonlyservicecontroltrace.append です。スコープを設定するとき、これらは gke-default として指定されます。Google Container Registry の非公開イメージにアクセスする場合、最小限必要なスコープは logging.writemonitoringdevstorage.read_only だけです。

カスタム スコープを指定してクラスタを作成するには、--scopes オプションを使用します。

gcloud container clusters create [CLUSTER_NAME] \
    --scopes=[CUSTOM_SCOPES]

スコープまたはカスタム サービス アカウントを指定しないと、gke-default が使用されます。カスタム サービス アカウントを指定すると、cloud-platformuserinfo.email が使用されます。

gcloud の構成に container/new_scopes_behavior true が含まれていると、この動作はすでにすべての Kubernetes バージョンで有効になっています。ご使用の環境にデフォルトを設定するには、次のコマンドを実行します。

gcloud config set container/new_scopes_behavior true

すべてのスコープの権限について詳しくは、Google のスコープをご覧ください。

クライアントの認証方法を制限する

Kubernetes API サーバーに対する認証の方法にはいくつかあります。GKE では、サポートされている方法は OpenID 接続トークン、x509 クライアント証明書、静的パスワードです。GKE が gcloud 経由で管理する認証では、OpenID 接続トークン方法を使用し、Kubernetes 構成を設定し、アクセス トークンを取得して最新の状態に保ちます。

他の認証方法である x509 証明書と静的パスワードでは、クラスタのセキュリティ侵害の攻撃範囲がより広くなります。これらの他の方法では、新しいクラスタを作成すると認証情報が自動的に生成されます。ご使用のアプリケーションでこうした認証方法を使用しない場合は、無効にする必要があります。OpenID 認証方法を使用し、クラスタのクライアント証明書および静的パスワードの認証方法は無効にしてください。

クライアント証明書と静的パスワードを取得できるのは、container.clusters.getCredentials 権限を持つユーザーだけです。roles/container.adminroles/ownerroles/editor の役割すべてにこの権限があるため、これらの役割を注意して使用してください。詳しくは、GKE の IAM の役割をご覧ください。

クライアント証明書による認証を無効にする

証明書認証では、クライアントが提示する証明書を、指定された認証局で API サーバーが検証します。GKE では、クライアント証明書はクラスタルート認証局により署名されます。

ABAC では、クライアント証明書はデフォルトで API サーバーに対して認証できます。しかし RBAC を有効にしている場合、クライアント証明書に権限を付与する必要があります。RBAC を有効にして ABAC を無効にしたクラスタにはこれらの証明書が残っていますが、実質的には役に立ちません。

クライアント証明書を生成せずにクラスタを作成するには、--no-issue-client-certificate フラグを使用します。

gcloud container clusters create [CLUSTER_NAME] \
    --no-issue-client-certificate

現在、既存のクラスタからクライアント証明書を削除する方法はありません。

静的パスワードによる認証を無効にする

静的パスワードとは、API サーバーが検証するユーザー名とパスワードの組み合わせです。GKE では、これらはデフォルトでユーザー名 "admin" に対して生成されます。

静的パスワードを生成せずにクラスタを作成するには、--no-enable-basic-auth オプションを使用します。

gcloud container clusters create [CLUSTER_NAME] \
    --no-enable-basic-auth

既存のクラスタを更新して静的パスワードを削除するには、次のコマンドを実行します。

gcloud container clusters update [CLUSTER_NAME] \
    --no-enable-basic-auth

ノードのメタデータを保護する

Kubernetes に対する実際の攻撃では、VM のメタデータ サーバーにアクセスしてノードの認証情報を取り出す攻撃があります。

上記で説明したように権限が最小限のサービス アカウントを使用することが、こうした攻撃を軽減するための第一歩です。次のステップは、ワークロードがノードを偽装するのを防ぐことです。以前のメタデータ サーバー API を無効にし、メタデータ隠蔽を使用して、潜在的に機密性の高いシステム メタデータをクラスタ上で実行されているワークロードから保護する必要があります。

詳細は、クラスタ メタデータの保護をご覧ください。

ノードを自動的にアップグレードする

Kubernetes のバージョンを最新の状態に保つことが、セキュリティを向上させるためにできる最も簡単なことの 1 つです。Kubernetes は頻繁に新しいセキュリティ機能を導入し、セキュリティ パッチを提供しています。

Google Kubernetes Engine では、マスターは自動的にパッチが適用され、アップグレードされますが、ノードについては担当者の責任です。ノードの自動アップグレードを有効にして、ノードプールに関するアップグレードとセキュリティ パッチを自動的に受信する必要があります。

詳細は、ノードの自動アップグレードをご覧ください。

ノードの自動アップグレードを有効にしない場合は、必ず Kubernetes Engine のセキュリティに関する情報でセキュリティ パッチに関する情報を注意してご確認ください。

ポッド セキュリティ ポリシーでポッド権限を制限する(ベータ版)

デフォルトでは、Kubernetes のポッドは、必要とする以上の機能で動作します。ポッドの機能は、そのワークロードに必要な機能だけに制限する必要があります。

Kubernetes には、ポッドを必要最小限の機能だけで実行するよう制限するための制御があります。ポッド セキュリティ ポリシーを使用すると、ポッドにスマートなデフォルトを設定して、ポッド全体で有効にする制御を実施できます。定義するポリシーは、アプリケーションのニーズに固有のものでなければなりません。restricted-psp.yaml サンプル ポリシーをはじめに利用することをおすすめします。

ポッド セキュリティ ポリシーについて詳しくは、PodSecurityPolicy の使用をご覧ください。

次のステップ

このページは役立ちましたか?評価をお願いいたします。

フィードバックを送信...