heguro_log

不定期メモ置き場

Cloudflareで送信元ポート番号を取得する

Cloudflareではヘッダーに発信元IPアドレスしか載らないから不可能だと思っていたら、最近出来るようになってたので記録します。

経緯

IPv4 アドレスが共有されている環境でよろしくないことをされた時のために、クライアント (発信者) の IP アドレスだけでなく送信元 (発信元) ポート番号も記録したほうがよいらしいです。

leia.5ch.net
www.jpne.co.jp

リンク先 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」 に変わっています

f:id:heguro:20211025004344p:plain
サイトのダッシュボードから、「ルール」 → 「変換ルール」 → 「変換ルールを作成」 → 「HTTP Request Header Modification」
f:id:heguro:20211025012148p:plain
デフォルトで表示される式ビルダーでは「条件なし」に設定できないので、「式を編集」をクリック
f:id:heguro:20211025002335p:plain
条件を true、ヘッダーの設定方法を Set dynamic、 値を cf.edge.client_port とする

CF- から始まるヘッダー名は使えません。 また、 X-Forwarded-Port などのありきたりな名前にすると、後に公式実装されて競合する可能性も無くはないので、被らさそうなものにするとよいでしょう。

これで、Cloudflareを経由する全てのリクエストでヘッダに送信元ポート番号が載るようになります。 Apache や nginx のログ対象に加える *1 なり、Webアプリの実装を弄るなりして、IPアドレスと一緒に記録しましょう。

他の情報も取得する

発信元ポート番号以外にも色々取得できます。

使えそうなフィールドを適当に載せてみました。

f:id:heguro:20211025014339p:plain

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 単体では出来ないようです
  • 10年ぶりくらいにブログ書いた… (この名義では初めて)

*1: 方法は 「サーバーソフトウェア名 x-forwarded-for ログ」 などでググれば出ます