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

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

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

GKE での実行時には Kubernetes ウェブ UI(ダッシュボード)を無効にしてください。

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=[COMPUTE_ZONE] \
    --enable-network-policy

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

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

NetworkPolicy と PodSecurityPolicy を同時に使用する

NetworkPolicy を使用していて、PodSecurityPolicy の対象となるポッドがある場合は、PodSecurityPolicy を使用する権限を持つ RBAC 役割または ClusterRole を作成します。その後、役割または ClusterRole をポッドのサービス アカウントにバインドします。この場合、ユーザー アカウントに権限を付与するだけでは不十分です。詳細については、ポリシーの承認をご覧ください。

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

各 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:@[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 iam service-accounts add-iam-policy-binding \
  [SA_NAME]@[PROJECT_ID].iam.gserviceaccount.com \
  --member=user:[USER] \
  --role=roles/iam.serviceAccountUser

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

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 を無効にし、メタデータ隠蔽を使用して、潜在的に機密性の高いシステム メタデータをクラスタ上で実行されているワークロードから保護するようにしてください。

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

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

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

Google Kubernetes Engine のマスターについてはパッチ適用とアップグレードが自動的に実行されますが、ノードについてはご自身の責任となります。ノードの自動アップグレードを有効にして、ノードプールに関するアップグレードとセキュリティ パッチを自動的に受信するようにしてください。

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

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

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

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

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

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

クラスタでネットワーク ポリシーとポッド セキュリティ ポリシーの両方を使用している場合は、ネットワーク ポリシーとポッド セキュリティ ポリシーを同時に使用するをご覧ください。

次のステップ

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

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