🥷

Google Cloud StorageでBasic認証付きでWeb公開(サービス拡張プラグイン編)

に公開

はじめに

Google Cloudの「サービス拡張」プラグインを使用して、Cloud Storageに配置した静的WebサイトにBasic認証を実装します。
前回の記事「Rust × WebAssembly(Wasm) × Edge処理 Google Cloudで「サービス拡張」を試してみた」で紹介した内容を、より実用的な形に発展させました。

これまでGoogle Cloudで静的WebサイトにBasic認証をかける方法をいくつか紹介してきましたが、本記事の方法がもっともオススメです。

概要

Google Cloudのロードバランサーを使用して静的Webサイトを公開している環境を前提として、サービス拡張プラグインを追加してBasic認証を実装します。

Basic認証プラグインを2つに分割する理由

Basic認証の実装を「Basic認証を要求するプラグイン」と「Basic認証の検証と認証ヘッダーを削除するプラグイン」の2つに分けて構成します。

この記事を必要とされている方の多くは、Cloud Storageに静的Webサイトを配置していると思いますが、Cloud StorageはBasic認証ヘッダー付きのアクセスに対応していません。

プラグインを1つだけにした場合、ブラウザでBasic認証のページを閲覧中にサーバー側でBasic認証機能を解除しても、ブラウザを再起動するまでBasic認証ヘッダー付きでアクセスし続けるため、Cloud Storageにアクセスできなくなり、ページが表示できなくなります。

そのため、公開時には「Basic認証を要求するプラグイン」のみを無効化し、「Basic認証の検証と認証ヘッダーを削除するプラグイン」は有効のままにします。
これにより、Cloud StorageへのアクセスからBasic認証ヘッダーが削除され、問題なくページを表示できるようになります。

実装の流れ

  1. プラグインのアップ先となる、Artifact Registry作成とサービスの有効化
  2. プラグインをビルドしてArtifact Registryにアップロードする
  3. サービス拡張プラグインを登録する
  4. ロードバランサーにサービス拡張プラグインを設定する

プラグインの実装

Google CloudのConsoleで作業を行います。
コンソールのヘッダー右上からCloud Shellを起動します。

Cloud Shellが起動したら、以下の手順でプラグインを実装します。

1. プラグインのアップ先となる、Artifact Registry作成とサービスの有効化

サービス拡張プラグインのアップロード先として、Artifact Registryを作成します。

まず、Artifact RegistryとNetwork Services APIが有効になっていない場合は、有効化しておきます。

# Artifact Registryの有効化(一度だけ実行)
gcloud services enable artifactregistry.googleapis.com

# Network Services APIの有効化(一度だけ実行)
gcloud services enable networkservices.googleapis.com

次に、プラグインの保存場所として、Docker用のArtifact Registryリポジトリを作成します。

gcloud artifacts repositories create service-extensions-wasm-plugin-docker \
    --repository-format=docker \
    --location=asia \
    --project=${GOOGLE_CLOUD_PROJECT} \
    --description="サービス拡張プラグイン" \
    --async

これらの設定は一度だけ実行すればOKです。

2. プラグインをビルドしてArtifact Registryにアップロードする

サービスプラグインのソースコードをGitHubに公開しています。
GitHubからCloud Shellにクローンして使用してください。

git clone https://github.com/ToMGitHubN/google-cloud-service-extensions-plugins.git
cd google-cloud-service-extensions-plugins

プラグインのビルドとアップロード

クローンしたリポジトリ内のyamlファイルにビルド設定を記述しています。
Cloud Buildを使用してビルドとArtifact Registryへのアップロードを実行します。

Artifact Registryリポジトリ名を別の名前で作成した場合は、cloudbuild.yamlを適宜修正してください。

# Basic認証を要求するプラグインのビルド
gcloud builds submit --config=basic_auth_header_response_docker/cloudbuild.yaml ./basic_auth_header_response_docker

# Basic認証の検証と認証ヘッダーを削除するプラグインのビルド
gcloud builds submit --config=remove_auth_headers_docker/cloudbuild.yaml ./remove_auth_headers_docker

3. サービス拡張プラグインを登録する

アップロードしたプラグインをサービス拡張プラグインとして登録します。

ここからは、Google Cloud Consoleでの作業になります。

ロードバランサーのページに移動し、「サービス拡張」タブをクリックします。

「サービス拡張プラグインを作成」をクリックします。

「Basic認証を要求するプラグイン」を作成

まず、「Basic認証を要求するプラグイン」を作成します。

名前にbasic-auth-header-responseと入力します。

イメージURLには、先ほどビルドしてArtifact Registryにアップロードしたイメージを指定します。
複数のバージョンがある場合は、最新版(latest)を指定してください。

# ${GOOGLE_CLOUD_PROJECT}には自分のプロジェクトIDが入ります
asia-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/service-extensions-wasm-plugin-docker/basic-auth-header-response

「プラグイン作成」をクリックしてプラグインを作成します。

「Basic認証の検証と認証ヘッダーを削除するプラグイン」を作成

同様に、今度は「Basic認証の検証と認証ヘッダーを削除するプラグイン」を作成します。

名前にremove-auth-headersと入力します。

# ${GOOGLE_CLOUD_PROJECT}には自分のプロジェクトIDが入ります
asia-docker.pkg.dev/${GOOGLE_CLOUD_PROJECT}/service-extensions-wasm-plugin-docker/remove_auth_headers

「プラグイン作成」をクリックしてプラグインを作成します。

4. ロードバランサーにサービス拡張プラグインを設定する

ロードバランサーにサービス拡張プラグインを設定して、Basic認証を有効化します。

「拡張機能」タブに移動し、「拡張機能を作成」をクリックします。


対象のロードバランサーを選択し、拡張の種類は「エッジ拡張」を選択します。


サービス拡張の「チェーン」と「一致条件」について

サービス拡張機能では、複数の「チェーン」を登録できます。
サービス拡張機能の適用条件は「一致条件」で設定します。
上から順番に「一致条件」が評価され、最初に一致したチェーンが実行されます。
最初に条件を満たしたチェーンが実行されると、以降のチェーンは評価されません。

本記事では、「Basic認証を要求するプラグイン」と「認証ヘッダーを削除するプラグイン」の2つの「チェーン」を登録します。
登録順は、「認証ヘッダーを削除するプラグイン」を先に登録し、次に「Basic認証を要求するプラグイン」を登録します。

「認証ヘッダーを削除するプラグイン」の「一致条件」は、ヘッダーにBasic認証がある場合に実行されるように設定します。
Basic認証ヘッダーがある場合は、「認証ヘッダーを削除するプラグイン」が実行された後、通常の通信が行われます。
Basic認証ヘッダーがない場合は、次のチェーンである「Basic認証を要求するプラグイン」が実行され、Basic認証の入力を要求するレスポンスを返します。

「一致条件」にBasic認証の情報を設定することで、プログラムを書き換えることなくBasic認証のID/パスワードを変更できるようになります。
また、Basic認証を無効化したい場合も、「Basic認証を要求するプラグイン」を無効化するだけで済みます。

設定を行う

それでは、具体的な設定を行います。

「名前」には、わかりやすい名前を付けてください。
ここでは、開発環境用としてbasic-auth-extension-devとしました。

「転送ルール」には、設定対象のロードバランサーを選択します。

認証ヘッダーを削除するプラグインの設定

拡張機能チェーンの名前はextension-chain-remove-auth-headersとしました。

ここで重要なのは一致条件の設定です。
一致条件には、Basic認証のAuthorizationヘッダーを設定します。

まず、Basic認証に設定したいID/パスワードをBase64エンコードします。
Cloud Shellで以下のコマンドを実行してください。"user"と"password"を設定したいID/パスワードに変更してください。

# "user:password"を任意のID:パスワードに変更してください
echo -n "user:password" | base64

# 出力例: "dXNlcjpwYXNzd29yZA=="

一致条件のヘッダーには、以下の形式で設定します。
request.headers["Authorization"] == "Basic (ここにBase64エンコードした文字列を入れる)"

上記の例("user:password")の場合は、以下のようになります。
request.headers["Authorization"] == "Basic dXNlcjpwYXNzd29yZA=="

ここまで設定すると、以下のようになります


次に、プラグインを登録します。
名前はextension-remove-auth-headerとしました。
プラグインは、認証ヘッダーを削除するプラグイン「remove-auth-headers」を設定します。
イベントは、「リクエスト ヘッダー」を選択します。

設定が完了したら、「拡張機能チェーンを追加」をクリックして、次のチェーンを追加します。

Basic認証を要求するプラグインの設定

拡張機能チェーンの名前はextension-chain-basic-auth-header-responseとしました。

一致条件は、すべてのリクエストにBasic認証を設定するには、true(すべてヒット)と設定します。

もし、/api//static/などの特定のパス以下にBasic認証をかけたくない場合は、以下のように設定することもできます。
request.path.startsWith("/api") == false && request.path.startsWith("/static") == false


次に、プラグインを登録します。
名前はextension-basic-auth-header-responseとしました。
プラグインは、Basic認証を要求するプラグイン「basic-auth-header-response」を設定します。
イベントは、「リクエスト ヘッダー」を選択します。


すべての設定が完了したら、「拡張機能を作成」をクリックして拡張機能を作成します。
作成には数分かかります。
作成完了の表示後も、実際に反映されるまでさらに数分かかることに注意してください。
(AWSのCloudFrontの設定変更と似ています)

(番外編) Basic認証の無効化方法

サービス拡張の「編集」を開きます。
「Basic認証を要求するプラグイン」のチェーンを削除することで、Basic認証を無効化できます。

反映には数分かかります。

まとめ

以上で、Google Cloud Storageでホスティングしている静的WebサイトにBasic認証を実装できました。
サービス拡張プラグインを使用することで、柔軟かつ簡単にBasic認証の有効化/無効化が可能になります。

以上です。お疲れ様でした。

Discussion