はじめに

Google Cloud では Cloud Load Balancing に Cloud Storage バケットをバックエンドバケットとしてターゲットとすることが可能です。
そうすることでカスタムドメインで容易に静的コンテンツを公開できます。
ただ、バックエンドバケットとして設定した場合、Cloud Storage の URL にアクセスした際に、オブジェクトが閲覧できてしまいます。
今回は Cloud Load Balancing 経由でドメインを利用した場合のみアクセスさせ、直接 Cloud Storage へのアクセスを行わせない方法の1つを紹介します。

やりたいこと

今回は既に記載したとおり、Cloud Storage を Cloud Load Balancing 経由でのみ公開とし、Cloud Storage 自体は非公開バケットとします。
以下イメージです。
CloudStorage非公開設定での公開

ポイント

Cloud Storage へのアクセスに HMAC キーを利用する

HMACキーを設定
Cloud Storage の HAMC キーを利用します。
HMAC キーを払い出したら、バックエンドサービスの Securitysettings に HMACキー を設定することで、サービスアカウントを利用した Cloud Storage へのアクセスを行うことが可能です。
なお、HMAC キーは利用されるアクセスキー、シークレットキーと同様に認証に利用するものであるため、取り扱いには十分注意してください。

バックエンドバケットではなくバックエンドサービスをターゲットとして設定する

NEG関連
Cloud Storage をバックエンドのバケットとして設定したい意図があるので、本来バックエンドバケットとしてターゲットのバケットを設定しますが、バックエンドサービスとして NEG を利用したバックエンドサービスを設定することができます。
バックエンドサービスを設定する理由としては、Cloud Storage の HMAC キーを利用するためバックエンドサービスの Securitysettings を利用して、Cloud Load Balancing 経由でサービスアカウントを利用したアクセスを実現します。

バックエンドサービスに対してカスタムリクエストヘッダーを設定する

全体
Cloud Load Balancing を経由する際に、バックエンドサービスからのリクエストにヘッダーを追加します。
これを行うことで、対象バケットへアクセスできるようにします。

手順

0.事前に準備すること

外部 IPアドレスの予約及び SSL 証明書、ドメイン取得、バケットアクセス用サービスアカウントの作成は完了している前提となります。

1.Cloud Storage のバケットを作成します。

バケット作成時のポイントとしては、バケットは非公開で作成します。

2.NEG (Network Endpoint Group) を作成します。

NEG については利用頻度も少ないため、こちらに記載します。
NEG とインターネット エンドポイントを作成する

2の詳細手順。

Network Endpoint Group の設定
以下設定画面に従い設定します。

  • 名前は任意の名前を入力します。
  • ネットワークエンドポイントグループの種類はインターネット NEG とします。
  • 範囲は Global とします。
  • デフォルトポートは 443 とします。
  • 新しいネットワークエンドポイントは完全修飾ドメインとポート を選択し、FQDN は バケット名.storage.googleapis.com の形で記載します。
  • ポートタイプもデフォルトとします。

3.ロードバランサー及びバックエンドサービスを作成します。

こちらの Google Cloud 公式ドキュメントを参照し作成します。こちらにLoadbalancer と バックエンドサービス ともに作成する手順となっております。
※HTTPのロードバランサーを作成せずに、HTTPS にて HTTP をリダイレクトする設定とします。
※ロードバランサーから NEG への通信は HTTPS で作成します。
※カスタムリクエストヘッダーのヘッダーの値は [xxxx.storage.googleapis.com]とします。

バックエンドサービスを設定する際に注意事項がありますので、以下に詳細記載します。
なお、以下の記載には Load Balancer の作成は含みません。

3のバックエンドサービスの詳細手順

以下の内容をそれぞれ設定画面にて設定していきます。

  • バックエンドタイプに、インターネットネットワークエンドポイントグループ
  • プロトコル HTTP/2、タイムアウト 30 秒
  • バックエンドに作成した NEG を選択します。
  • Cloud CDN を有効にします。
  • キャッシュモード、ロギング、セキュリティは任意のものを設定します。
  • その他の CDN オプションとして、圧縮モード、古いデータの提供は任意のものを設定します。
  • 制限付きコンテンツ にて Cloud CDN によりキャッシュされたコンテンツへの公開アクセスを許可する(推奨) を設定します。
  • ネガティブキャッシュポリシーは任意の値を設定します。
  • カスタムリクエストヘッダーとして、 ヘッダー名:host 、 ヘッダーの値:バケット名.storage.googleapis.com の形で記載します。

4.HMACキー作成

Cloud Storage にサービスアカウントを登録し、HMAC キーを作成します。
サービスアカウントを選択し、キーを作成します。

次回以降、値は確認できないので、このときに確実にメモします。

5.バックエンドサービスの内容を更新します。

Google Cloud の公式ドキュメントを参照し、バックエンドサービスに対して、gcloud コマンドを利用し、HAMCキーを設定します。

5.バックエンドサービスの詳細手順

  • 以下コマンドを実行し、設定情報をエクスポートします。
    gcloud compute backend-services export BACKEND_SERVICE_NAME –destination=設定ファイルの出力ファイルパス
  • エクスポートしたファイルに対して Securitysettings を追加します。以下追記箇所位フォーカスした例です。
 name: shopping-cart-services
 backends:
   - description: cart-backend-1
     group: 'https://www.googleapis.com/compute/v1/projects/my-project-id/global/networkEndpointGroups/my-network-origin-group'
 securitySettings:
   awsV4Authentication:
     accessKeyId: AKIDEXAMPLE ※アクセスキーID
     accessKey: c4afb1cc5771d871763a393e44b703571b55cc28424d1a5e86da6ed3c154a4b9 ※シークレット
     accessKeyVersion: prod-access-key-v1.2 ※任意の名前
     originRegion: us-east-2 ※バケットを作成したリージョン
  • 以下コマンドを実行し、設定情報をインポートします。
gcloud compute backend-services import BACKEND_SERVICE_NAME --source=securitySettingsを追記したファイルパス

まとめ

これらにより、非公開バケットによる。バックエンドサービスを利用した、Cloud Load Balancing 経由のみのバケットへのアクセスが実現できます。
今までバケットを公開せずに静的コンテンツとして公開する方法について模索してきましたが、今回の方法により実現できました。
大きなメリットとしては、Cloud Storage の URL を利用したアクセスはできないため、Web サイトとしては、必ずドメインでのアクセスとすることができます。
なお、デメリットとしては、HMACキーの払い出しが必要となり、セキュリティ面を考慮する必要は出てきますので、注意してください。
※特にサービスアカウントでもキーの取り扱いに関する、デフォルトの組織ポリシーがセキュリティを意識した形で変わっていたりするので、要注意です。なお、サービスアカウントのキーの扱いの注意事項はよろしければ、[こちら]と(https://iret.media/69011)
Google Cloud の公式ドキュメントの文言を読んでみると、非公開のままバケットを静的ウェブホスティングする、という方法は無いように読み取れるので、もしその他方法でも可能であれば模索してみたいと思います。