Cloudflareで送信元ポート番号を取得する
Cloudflareではヘッダーに発信元IPアドレスしか載らないから不可能だと思っていたら、最近出来るようになってたので記録します。
経緯
IPv4 アドレスが共有されている環境でよろしくないことをされた時のために、クライアント (発信者) の IP アドレスだけでなく送信元 (発信元) ポート番号も記録したほうがよいらしいです。
リンク先 PDF の p71 「サーバのアクセスログに関する対応」 より:
- RFC 6302 では、ログに送信元ポート番号を含めることを推奨
- 平成27年に、プロバイダ責任制限法第4条第1項 「発信者情報を定める省令」 の一部が改正され、開示の対象となる発信者情報にポート番号が追加
やり方
今年6月に実装された、 変換ルール (Transform Rules) の中の HTTP Request Header Modification (HTTPリクエストヘッダの修正) という機能を使います。
blog.cloudflare.com
※2021/10/25時点では 「ヘッダーを (の) 修正」 (Header Modification) という名前でしたが、2021/12/05現在「 HTTP Request Header Modification」 に変わっています
CF- から始まるヘッダー名は使えません。 また、 X-Forwarded-Port などのありきたりな名前にすると、後に公式実装されて競合する可能性も無くはないので、被らさそうなものにするとよいでしょう。
これで、Cloudflareを経由する全てのリクエストでヘッダに送信元ポート番号が載るようになります。 Apache や nginx のログ対象に加える *1 なり、Webアプリの実装を弄るなりして、IPアドレスと一緒に記録しましょう。
他の情報も取得する
発信元ポート番号以外にも色々取得できます。
- フィールド (変数) 一覧
- 関数一覧
- 文字結合の concat と、 concat に数値を渡すための to_string が使えます。
- concat の引数は4つまでで、各行で1回しか使えません。
使えそうなフィールドを適当に載せてみました。
Mod-CF-ASN: ip.geoip.asnum Mod-CF-Client-Port: cf.edge.client_port Mod-CF-Client-Trust-Score: cf.client_trust_score Mod-CF-Geo: concat("continent=", ip.geoip.continent, "; country=", ip.geoip.country) Mod-CF-Http-Version: http.request.version Mod-CF-Is-Good-Bot: cf.client.bot Mod-CF-Original-Host: http.host Mod-CF-Recieved-Timestamp: http.request.timestamp.sec Mod-CF-Recieved-Timestamp-Msec: http.request.timestamp.msec Mod-CF-Threat-Score: cf.threat_score
実際のヘッダー例
2021/10/25 に、この設定をして実際にサーバーで取得できた情報です。 ブラウザが送信したヘッダは除いています。 xxxx や example の部分は伏せてます。
CDN-Loop: cloudflare CF-Connecting-IP: xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx CF-IPCountry: JP CF-Ray: 6a34abf38fdc0a66-KIX CF-Visitor: {"scheme":"http"} Mod-CF-ASN: xxxx Mod-CF-Client-Port: 58846 Mod-CF-Client-Trust-Score: 90 Mod-CF-Geo: continent=AS; country=JP Mod-CF-Http-Version: HTTP/3 Mod-CF-Is-Good-Bot: false Mod-CF-Original-Host: xxxx.example.com Mod-CF-Recieved-Timestamp-Msec: 10 Mod-CF-Recieved-Timestamp: 1635093886 Mod-CF-Threat-Score: 0 X-Forwarded-For: xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx X-Forwarded-Proto: http
注意点
Freeプランだと、URLリライトとヘッダーの修正で合わせて2→10枠まで
2021/12/05時点で10枠になってました!!
まだドキュメントでは2枠のままなので、正式な変更なのかわかりませんが…
以下古い記述です:
2枠埋まっていると新規作成ができません。 ルールを無効化しても枠が減らないので、複数のルールで運用したい場合かなりつらいです。
ページルールのように枠を買うこともできません。
Proプランにすると5枠に増えますが、このためだけに$20/月はなかなか払えないと思います…
枠数が少ない中でやりくりしていると、間違ってルールを消してしまう可能性も高まります。
該当するヘッダーの行が無くても不具合が起こらないよう実装しましょう。
Cloudflare Workers で再度同じドメインに fetch する場合、 クライアントでなく Workers の情報が入る
変換ルールの適用条件を絞る、 Workers 側でヘッダを弄るなどで対応しましょう。
そのほか
- Cloudflare Workers 単体では出来ないようです
- IncomingRequestCfProperties (request.cf) に送信元ポート番号がない
- 10年ぶりくらいにブログ書いた… (この名義では初めて)
*1: 方法は 「サーバーソフトウェア名 x-forwarded-for ログ」 などでググれば出ます