はじめに
Google Cloud上で特定の方々にだけ静的ページを公開したいんだけど・・・どうしたらよい?
というご相談を頂きましたので検討してみました。
意外と情報が乏しかったため各種方法を検証し、ブログで紹介します。
Cloud StorageにIP制限をかける方法は3つの方法
まず、Cloud StorageにIP制限をかける方法は以下3つあります。
1、VPC Service Controls
組織単位で実行する必要がありGoogle Cloud Projectを組織構成にする必要がある。組織単位で制御がかかるので今回の用途に合わないことが確認できました。
2、Bucket IP filtering
2024年11月14日にプレビューでリリースされた機能で
Cloud Storage へバケット単位で、IP フィルタリング設定を行うことが可能で
許可対象の IP アドレスを登録することが可能です。
実際のやり方については↓
Cloud Storage に対して Bucket IP filtering ができるようになりました
一見これが一番手軽で良さそうと思ったものの問題もありました。
GUIで制御ができずCLIベースでの制御となり、どのように制御がかかっているのかわかりづらい。
また、これが一番恐いのですが、誤ったIPを設定してしまうとバケットに接続できなくなってしまう。
オーナー権限を持っていても設定すら確認できなくなってしまう始末。。。。。
ここは意見がわかれるところかとは思いますが、
私はこのやり方を広めるにはまだ優しくない仕様なのかなという印象でもう少し成熟するのを待った方が良いと感じました。
3、Cloud Armor
Cloud ArmorはCloud Load Balancingと共に使う必要があるのでCloud Storageの前にCloud Load Balancingを設置する必要があります。
三つの中ではリカバリーも効くので一番やりやすそうということで今回はこちらをやってみたいと思います。
※以下、Cloud Load Balancing → CLB
今回実現したい構成はこちらです↓

それでは手順をご紹介します。
① HTMLを配置したCloud Storageを準備する
HTMLを配置するバケットを作成します。

② Cloud Load Balancingを準備する
Cloud Storageの前に配置するCLBを作成していきます。

ロードバランサタイプ
→アプリケーションロードバランサ(HTTP/HTTPS)
インターネット接続
→インターネット接続外部
グローバルまたはシングルリージョンデプロイ
→グローバル ワークロードに最適
ロードバランサーの世代
→グローバル外部アプリケーション ロードバランサ
フロントエンドの構成は任意でOK
バックエンドの構成でバックエンドサービスを作成

バックエンドタイプ→インターネット ネットワーク エンドポイントグループを選択
インターネットネットワーク エンドポイント グループを作成する

インターネット NEGを選択

ドメインに「storage.googleapis.com」を設定

これでCLBの作成は完了です。
③ Cloud ArmorでIP制限をかける
Cloud Armorを使ってIP制限をかけます。
Cloud Armorのポリシーはこちらです↓

ここでIP制限をかけることができます↓

④ HMAC鍵を発行しCLBのバックエンドに付与します。
最後にCLB経由でCloud Storageにアクセスできるようにします。
残念ながらCLBにはIAM権限を直接付与する事ができません。なのでCloud StorageをAllUsersを使用せずにアクセスすることができないのです。
Cloud Storageを公開させることなくCLB経由でアクセスするには以下のように一手間必要となります。
まずHMAC鍵を発行します。

サービスアカウントもしくはユーザーアカウントキーを作成します。
※本番運用ではサービスと紐づいたサービスアカウントキーが推奨されています。

この鍵を利用してCLBからCloud Storageのアクセスを確立させます。(非公開送信元の認証)
鍵の登録はGUIでは行えないのでCLIを使って実施します。
gcloud compute backend-services export BACKEND_SERVICE_NAME --destination={exportファイル名}
affinityCookieTtlSec: 0
backends:
- balancingMode: UTILIZATION
capacityScaler: 1.0
group:
------------------------追加
securitySettings:
awsV4Authentication:
accessKeyId: {先ほど取得したキーのアクセスキー}
accessKey: {先ほど取得したキーのシークレット}
originRegion: {作成したCloud Storageのリージョン}
------------------------追加
cdnPolicy:
cacheKeyPolicy:
includeHost: true
includeProtocol: true
includeQueryString: true
cacheMode: CACHE_ALL_STATIC
clientTtl: 3600
defaultTtl: 3600
maxTtl: 86400
negativeCaching: false
requestCoalescing: true
serveWhileStale: 0
gcloud compute backend-services import BACKEND_SERVICE_NAME --source={exportファイル名}
これでCLBのIPにアクセスすると接続することができました。

まとめ
この方法を使えば、比較的簡単に静的ページを特定の対象者に公開していくことが可能です。
HMAC鍵を登録する部分が若干手間ではあるので、Bucket IP fillteringがもう少し使い易くなることを願っております。