🛡️

Cloud RunをCloudflareからしか繋げないようにする

2024/06/23に公開

皆さんはCloud RunのカスタムドメインやCloud Load Balancingの外部アプリケーション ロードバランサを用いて、Cloud RunをCloudflareでプロキシしていませんか?
どちらの場合も、特殊な検索エンジンを用いることでOriginが割り出されて直接アクセスされる可能性があります。
この場合、EDoS攻撃の被害に遭ったり、本来CloudflareのWAFで弾かれるはずのリクエストを受け付けてしまう可能性があります。

本記事ではCloudflare Tunnelを用いて、インバウンド通信を一切受け付けずにサービスを運用する方法をまとめます。

本記事が実現するインフラ構成

インフラ構成図
この手の図を書くのが苦手であるため分かりづらいのですが...。
Internet -> Cloudflare -> Compute Engine -> Cloud Load Balancing -> Cloud Run
という流れで通信が行われるようにします。

Cloud Load Balancingを挟んでいる理由を説明します。
Cloud Runはインバウンド通信のためにドメインが割り当てられ、VPC内の他サービスからはそれにアクセスします。
しかし、Cloudflare Tunnelは接続先にIPアドレスしか指定できないためです。

GoogleのドキュメントによるとPrivate Service Connectも利用できるようですが、ドキュメントを読んだ限りでは設定がかなり複雑に感じたため、Cloud Load Balancingを採用しました。
コストを考慮する際には両方を比較することを推奨します。

Cloudflare Tunnelはcloudflaredを常時実行する必要があるため、サーバーレスとの相性は悪いです。

たしかにGCPのインフラに対する接続を受け付けないためには、他にもCloudflareがVery secureとしているいくつかの手段があります。

  • Authenticated Origin Pulls: 自前のSSL証明書を用いて、それを管理する必要がある
  • Cloudflare AccessのJWT: アプリケーションかコンテナに手を入れる必要があり、Cloudflare Accessはアクセス元が限定される場合の利用が想定されている
  • Cloudflare Magic Transit / Cloudflare Network Interconnect: Enterpriseプランでないと利用できない
  • Cloudflare API ShieldのJWT: Enterpriseプランでないと利用できず、現在プレビュー版

このように、公開アプリケーションでは選択肢が限られてきます。
どうしてもCompute Engineを保守したくない場合、Origin Pullsを用いるのが適切だと思います。
しかし、Origin PullsはL4までの接続を許容することになるため、私はCloudflare Tunnelを推奨します。

設定

VPCの設定

VPCのファイアウォールを上りのポート22のTCPだけ許可しておきます。
これはSSHでCompute Engineを設定するためです。
今回インバウンド通信を受け付ける必要があるのはこれだけなので、他の設定は削除しておきます。

Compute Engineのデプロイ

今回はe2-microインスタンスでSpot VMを利用し、OSはUbuntu 24.04 LTS Minimal、ファイアウォールの設定は一切チェックを入れずにデプロイします。
マシンタイプやVM プロビジョニング モデル、OSは状況に応じて変更してください。

Cloud Runのデプロイ

上り(内向き)の制御を内部に設定し、HTTP/2はオフにしてください。
(追記) HTTP/2はアプリケーションが対応していればオンでもいけるかもしれないです。
他に特筆すべき点はないため、Googleのドキュメントを参考にデプロイします。

Cloud Load Balancingのデプロイ

ロード バランシング画面にてロードバランサを作成を選択します。
アプリケーション ロードバランサ -> 内部 -> リージョン ワークロードに最適と選択します。
ロードバランサに任意の名前をつけ、リージョンとネットワークを指定します。
この際、プロキシ専用サブネットを作成する必要がある場合があります。
バックエンド タイプはサーバーレス ネットワーク エンドポイント グループに指定し、バックエンドを画面に従い作成します。
フロントエンドも同様に画面に従い作成します。
これでCloud Load Balancingをデプロイできます。

Compute Engine -> Cloud Load Balancing の疎通チェック

ここで、Compute EngineからCloud Load BalancingにHTTP通信が通るか確認します。
Cloud Load Balancingのフロントエンドタブのテーブルに住所という項目があるので、それに対してCompute EngineからcurlでHTTP通信を行います。
Cloud Runにデプロイしたアプリケーションで想定されるレスポンスが返ってきたらOKです。

cloudflaredの設定

Cloudflareのダッシュボードで任意のアカウントを選択し、Zero TrustからNetworks -> Tunnelsと進みます。
Create a tunnelを選択し、Cloudflaredが選択されていることを確認しNextを選択します。
任意のトンネル名を指定し、Save tunnelを選択します。
OSの選択画面でDebianを選択すると、cloudflaredのインストールから設定までのスクリプトが表示されるので、これを先程デプロイしたCompute Engineで実行します。

Cloudflare TunnelのPublic HostnameタブからAdd a public hostnameを選択します。
適切なサブドメイン、ドメイン、パスを入力してください。
TypeはHTTPを選択し、URLに疎通チェックで得たIPアドレスを入力します。
入力した サブドメイン.ドメイン/パス から正常なレスポンスが返ってきたら成功です。

Discussion