Gateway APIで作成したロードバランサーにCloud ArmorとIAPを構成する

記事タイトルとURLをコピーする

G-gen の佐々木です。当記事では、GKE で Gateway API を使用する際に、作成されたアプリケーションロードバランサーに対して Cloud Armor セキュリティポリシーIAP を構成する方法を解説します。

はじめに

GKE における Gateway API

Gateway API は、Kubernetes でレイヤ7の高度なトラフィックルーティングを提供するための Kubernetes アドオンであり、Google Cloud では GKE で L7 ロードバランサー(アプリケーションロードバランサー)を利用したい場合に使用されます。

従来から同様の用途で使用されていた Ingress API に様々な改良が加えられたものであり、高度なルーティング(ヘッダーベース、重み付けなど)や、異なる Namespace にあるリソースへのアクセスなどがネイティブにサポートされています。

Gateway API の基本については以下の記事を参照してください。

blog.g-gen.co.jp

当記事では、この Gateway API から作成したアプリケーションロードバランサーに対して、Cloud Armor セキュリティポリシーによるバックエンド保護と、Identity-Aware Proxy(IAP)による IAM 認証機能を構成していきます。

Cloud Armor とは

Cloud Armor は Google 製のクラウド型 WAF であり、Cloud Armor の セキュリティポリシー をアプリケーションロードバランサのバックエンドに紐づけることで、バックエンドに対するアクセス元の制限をかけることができます。

Cloud Armor の詳細については、以下の記事で解説しています

blog.g-gen.co.jp

Identity-Aware Proxy(IAP)とは

IAP は、Cloud Run や GKE、Compute Engine 上で実行されているアプリケーションに対して、IAM による認証機能を提供するサービスです。アプリケーションにアクセスできるユーザーを特定の IAM ロールがアタッチされた Google アカウント/グループに制限することができます。

IAP の基本については、以下の記事で解説しています。

blog.g-gen.co.jp

当記事の構成

当記事では、以下の記事で作成した Gateway API リソースと nginx のバックエンドを持つ環境に対して、Cloud Armor セキュリティポリシーと IAP を追加で構成していきます。以降の手順の前提となるサンプル環境を構成するためのマニフェストファイルについては、同記事を参照してください。

blog.g-gen.co.jp

当記事で前提となるサンプル構成

GCPBackendPolicy を使用して Cloud Armor や IAP を構成する

GCPBackendPolicy に関する注意点

Gateway API で作成したロードバランサーに対して Cloud Armor セキュリティポリシーや IAP を構成したい場合、Gateway API リソースの1つである Policy を使用します。

GKE で利用できる Gateway API の Policy には以下のような種類があります。

  • GCPGatewayPolicy
  • GCPBackendPolicy
  • HealthCheckPolicy

Cloud Armor や IAP を利用する場合は、GCPBackendPolicy を定義し、Gateway のバックエンド(ルーティング先)である Service リソースに紐付けます。

注意点として、GCPBackendPolicy は 1つの Service に対して1つしか紐付けることはできません。そのため、1つの Service に対して Cloud Armor セキュリティポリシーと IAP の両方を構成したい場合、その両方の定義を1つの BackendPolicy 内に記述する必要があります。

2つの GCPBackendPolicy を紐づけると、kubectl describe gcpbackendpolicies コマンドの出力として以下のエラーメッセージが確認できます。

Warning SYNC 14s (x2 over 63s) sc-gateway-controller Conflicted: Application of GCPBackendPolicy "default/nginx-backend-policy" failed: conflicted with GCPBackendPolicy "default/my-backend-policy" of higher precedence, hence not applied

Gateway リソースに対して Cloud Armor セキュリティポリシーを構成する手順

Cloud Armor セキュリティポリシーの作成

ここでは、サンプル構成に対して Cloud Armor のセキュリティポリシーを適用し、許可された IP アドレスからのみ、バックエンドのサービスにアクセスできるようにします。

まず、Cloud Armor のセキュリティポリシーを作成します。

# セキュリティポリシーの作成
$ gcloud compute security-policies create my-sec-policy

作成したポリシーのデフォルトルール(優先度2,147,483,647)では全ての通信が許可されているため、デフォルトルールを更新して全てのアクセス元を拒否します。

# デフォルトルールの更新
$ gcloud compute security-policies rules update 2147483647 \
    --security-policy my-sec-policy \
    --action "deny-403"

特定の IP アドレス範囲からのアクセスを許可するルールを追加します。

ルールの優先度は全拒否のデフォルトルールより高ければよいので、ここでは優先度1000で設定します。

# 許可ルールの追加
$ gcloud compute security-policies rules create 1000 \
    --security-policy my-sec-policy \
    --src-ip-ranges "<許可する IP アドレス範囲>" \
    --action "allow"

特定の IP アドレス範囲のみ許可するセキュリティポリシー

GCPBackendPolicy の作成

作成した Cloud Armor セキュリティポリシーを Gateway のバックエンドサービスに紐づけるための GCPBackendPolicy を作成します。

以下のマニフェストを使用して、バックエンドの Service リソースに対してセキュリティポリシーを紐づけます

# backend-policy.yaml
apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: nginx-backend-policy
spec:
  default:
    securityPolicy: my-sec-policy  # Cloud Armor セキュリティポリシーの名前
  targetRef:
    group: ""
    kind: Service
    name: nginx-service  # ルールを紐づけるバックエンドの Service リソース

動作確認

Cloud Armor セキュリティポリシーで許可していない IP アドレスから、ロードバランサーに設定しているドメインにアクセスしてみます。

セキュリティポリシーにより、アクセスが拒否されていることがわかります。

セキュリティポリシーで許可されてない IP アドレスからのアクセスが拒否される

許可した IP アドレスからのアクセスは成功する

このまま続けて次の IAP の構成手順に進む場合、一度 GCPBackendPolicy リソースを削除してください(Service に対して1つしか紐づけられないため)。

Gateway リソースに対して IAP を構成する手順

OAuth 同意画面の構成

使用しているプロジェクトで OAuth 同意画面 をまだ構成していない場合は、設定を行います。

手順は以下のドキュメントや記事を参照してください。

バックエンドサービスで IAP を有効化

Google Cloud コンソールから、バックエンドサービスに対して IAP を有効化します。

対象のサービスのトグルスイッチを ON にし、「IAP をオンにする」を選択します。

バックエンドサービスで IAP を有効化する

「IAP をオンにする」を選択

サービスへのアクセスを許可する Google アカウントに対して、IAP で保護されたウェブアプリ ユーザー(IAP-secured Web App User)ロールを付与します。

アカウント、グループに対してサービスへの IAP 経由のアクセスを許可する

OAuth 2.0 クライアント ID とシークレットの発行

Google Cloud コンソールの「API とサービス」から、OAuth 2.0 クライアント ID を作成していきます。

「OAuth クライアント ID」を選択する

以下の項目を入力し、「作成」を選択します。

項目
アプリケーションの種類 ウェブ アプリケーション
名前 任意の名前

OAuth クライアント ID を作成する

作成後、クライアント IDクライアントシークレットが表示されるので、この2つはメモしておきます。なお、メモするのを忘れてもクライアントの詳細画面から後で確認できます。

クライアント ID とクライアントシークレットをメモしておく

作成したクライアント ID の編集画面を開き、「承認済みのリダイレクト URI」項目を設定します。

値には、先ほどメモしておいたクライアント ID を含む以下の URI を設定します。

「承認済みのリダイレクト URI」の設定値
https://iap.googleapis.com/v1/oauth/clientIds/{クライアント ID の値}:handleRedirect

承認済みのリダイレクト URI を設定する

Secret の作成

メモしておいた OAuth クライアント シークレットを以下のようにテキストファイルにそのまま記述します。当記事では iap-secret.txt という名前でファイルを作成します。

<クライアント シークレットの値>

このテキストファイルを使用して、以下のコマンドで Secret リソースを作成します。

# Secret の作成
$ kubectl create secret generic my-secret --from-file=key=iap-secret.txt

GCPBackendPolicy の作成

作成した Secret リソースと、メモしておいた OAuth クライアント ID を使用し、バックエンドの Service に紐づける GCPBackendPolicy を作成します。

マニフェストファイルは以下のようになります。

# backend-policy.yaml
apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: nginx-backend-policy
spec:
  default:
    iap:
      enabled: true  # IAP を有効化
      oauth2ClientSecret:
        name: my-secret  # 作成した Secret リソースの名前
      clientID: <OAuth クライアント ID>  # メモしておいた OAuth クライアント ID
  targetRef:
    group: ""
    kind: Service
    name: nginx-service  # ルールを紐づけるバックエンドの Service リソース

動作確認

マニフェストファイル適用後、ロードバランサーに設定しているドメインにアクセスすると、IAP のログイン画面が表示されます。

IAP が有効化されたサービスにアクセスする

IAM で許可された Google アカウントでログインすることで、サービスにアクセスすることができます。

Cloud Armor セキュリティポリシーと IAP を同時に構成する手順

先述したように、バックエンドサービスである Service に対して、GCPBackendPolicy リソースは1つしか紐づけることができません。

Cloud Armor セキュリティポリシーと IAP を同時に構成したい場合、以下のように1つのマニフェストファイルに対してそれぞれの定義をします。

# backend-policy.yaml
apiVersion: networking.gke.io/v1
kind: GCPBackendPolicy
metadata:
  name: nginx-backend-policy
spec:
  default:
    securityPolicy: my-sec-policy  # Cloud Armor セキュリティポリシーの名前
    iap:
      enabled: true  # IAP を有効化
      oauth2ClientSecret:
        name: my-secret  # 作成した Secret リソースの名前
      clientID: <OAuth クライアント ID>  # メモしておいた OAuth クライアント ID
  targetRef:
    group: ""
    kind: Service
    name: nginx-service  # ルールを紐づけるバックエンドの Service リソース

なお、Cloud Armor セキュリティポリシーと IAP を同時に構成した場合、先にセキュリティポリシーによるアクセス許可/拒否が評価され、ポリシーで許可されたアクセスに対して後から IAP による認証が行われます。

Ingress API を使う場合

GKE で Cloud Load Balancing のアプリケーションロードバランサーを使用する場合、従来は Ingress API を使用していました。

Ingress API を使用している場合、ロードバランサーに対して Cloud Armor や IAP を構成するには BackendConfig リソースをバックエンドの Service リソースに紐付けます。

Ingress API を使用する場合の詳細な手順については、以下の記事を参照してください。

blog.g-gen.co.jp

blog.g-gen.co.jp

佐々木 駿太 (記事一覧)

G-gen 最北端、北海道在住のクラウドソリューション部エンジニア

2022年6月に G-gen にジョイン。Google Cloud Partner Top Engineer に選出(2024 / 2025 Fellow / 2026)。好きな Google Cloud プロダクトは Cloud Run。

趣味はコーヒー、小説(SF、ミステリ)、カラオケなど。