Cloudflare Workers の IP ジオロケーション:キャッシュとコールドスタート
Cloudflare Workers での IP ジオロケーションとは、Worker の内部で訪問者の位置データを、組み込みの request.cf オブジェクトから読み取るか、エッジから外部の IP インテリジェンス API を呼び出して取得することです。2つの方法は異なる問いに答えるものであり、それぞれのキャッシュとコールドスタートの挙動を理解してから構築することをお勧めします。
Workers が無料で提供するもの
Worker に届くすべてのリクエストには、Cloudflare が設定する request.cf オブジェクトが付いています。そこには、訪問者の国、都市、地域、座標、タイムゾーン、ASN、AS の組織が含まれ、さらにリクエストを処理したデータセンターを示す colo フィールドも含まれます。CF-IPCountry ヘッダーも国コードを持っています。このデータはコードが実行される前に付与されるため、サブリクエストも遅延も追加で発生しません。
限界はスコープです。request.cf が説明するのは現在のリクエストの接続クライアントだけです。ログの行、フォームのフィールド、webhook のペイロード、X-Forwarded-For のチェーンに現れる IP アドレスについては何もわからず、VPN、Tor、不正利用のフラグといった評判のシグナルも含まれません。任意のアドレスを補完する必要が生じたら API を呼び出すことになり、そこからキャッシュの判断が始まります。
エッジでの補完データのキャッシュ
Worker からの IP ルックアップはサブリクエストなので、キャッシュされていないルックアップは、リクエストの経路にネットワークの往復を1回追加します。Cloudflare には、結果をキャッシュする場所がいくつかあります。Cache API(データセンターごとで、グローバルには複製されません)、KV(グローバルに読み取れますが結果整合性で、書き込みの伝播には時間がかかります)、そして単一の協調されたコピーが必要な場合の Durable Objects です。どれもそのまま使えるグローバルキャッシュではないので、許容できるものに応じて選んでください。読み取りの多いルックアップには Cache API が最も簡単で高速であり、KV はすべての拠点から見えるようにしたい値に向いています。
より有用な設計上の判断は、フィールドごとの有効期間(TTL)です。IP インテリジェンスのデータは均一に古くなるわけではないからです。国と ASN の割り当ては、アドレスブロックの再割り当てに数カ月から数年かかるため変化が遅く、数時間以上の TTL で問題ありません。評判フラグは別です。ipto の VPN、Tor、不正利用のフィードは6時間ごと、IP と ASN のデータセットは毎日更新されるため、is_tor のようなフラグを数時間より長くキャッシュすると、ソース自体より古い答えを返すことになります。実用的な分け方は、ネットワークの事実(asn、asn_org、国、都市)を1日程度、フラグ(is_vpn、is_tor、is_abuser、is_datacenter)をフィードの更新間隔以内でキャッシュすることです。
- キャッシュのキーには正規化した IP を使う(IPv6 では、ホスト単位ではなくネットワーク単位の用途なら /64 をキーにすることを検討する)。
- 否定的な結果もキャッシュし、リストにないアドレスの繰り返しのルックアップが毎回 API に届かないようにする。
- bogon の結果を誤って公開キーでキャッシュしない。
10.0.0.1のようなプライベートアドレスは、API を呼ばなくてもローカルで答えられる。
Workers のコールドスタート
Workers はコンテナではなく V8 isolate 上で動作するため、コールドスタートは通常、コンテナベースの関数でお馴染みの数百ミリ秒ではなく、数ミリ秒程度です。ただし、コード自体の初期化コストは発生します。大きなバンドル、大きなルックアップテーブルのモジュールレベルでの重い解析、トップレベルの await は、いずれも新しい isolate への最初のリクエストで実行されます。対策は平凡です。バンドルを小さく保ち、起動時に大きなメモリ内構造を構築せず、ジオロケーションデータベース全体を Worker に同梱するよりも、小さな API 呼び出しを1回行うほうを選んでください。
従来のサーバーレスで使われるウォームアップ用の ping は、ここではほとんど無駄になります。isolate は Cloudflare のスケジュールで作成・破棄され、ping が届くのは1つの拠点だけであり、コールドスタートのコストは十分に小さいため、isolate を維持するよりもルックアップ結果をキャッシュするほうがはるかに重要です。何かを最適化する前に、まず Workers のアナリティクスと、サブリクエスト周辺での独自の計測で測定してください。
ipto と組み合わせる
妥当なパターンは、接続クライアントについての即時で無料の情報には request.cf を使い、それ以上が必要なときだけ補完 API を呼び出すことです。ipto の API ドキュメントには IP ルックアップのレスポンスが示されており、国、都市、ASN、org、currency_code、そしてフラグ is_vpn、is_tor、is_abuser、is_datacenter、bogon/bogon_type を返します。サインアップ不要で、1日1,000リクエストまで無料なので、キー管理の手間なしに Worker のプロトタイプを作るには十分です。
ルックアップの結果、アドレスがホスティングネットワークに属するとわかった場合は、ASN ルックアップで運用者と広告しているレンジを確認できます。フラグが立ったトラフィックについては、VPN・Tor・プロキシチェッカーで is_vpn と is_tor の根拠を確認でき、IP 不正利用チェッカーで裏付けのあるスコアを確認できます。都市レベルの位置は、人がいる場所ではなく、ネットワークが登録またはルーティングされている場所の推定であることを忘れないでください。この限界は都市レベルの精度に限界がある理由で説明しています。
エッジはルックアップを速くしますが、元のデータをより正確にするわけではありません。request.cf も API の結果も同じ種類の証拠として扱い、それぞれ変化の速さに応じてキャッシュし、TTL はエッジの速度ではなくソースの鮮度で決めてください。