fix(vps): rate limit by the real client IP behind Cloudflare - #702
fix(vps): rate limit by the real client IP behind Cloudflare#702nelitow wants to merge 2 commits into
Conversation
…d hop is a Cloudflare address The explorer's public domain is a Cloudflare-proxied CNAME to Railway, so the first X-Forwarded-For hop is a Cloudflare address for every visitor. A geo block over Cloudflare's published ranges, fetched at image build, selects CF-Connecting-IP only for those requests; direct traffic keeps the first hop, which Railway's edge rewrites. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR SummaryMedium Risk Overview The explorer Docker image downloads Cloudflare IPv4/IPv6 lists at build time into GitHub Actions add explicit least-privilege Reviewed by Cursor Bugbot for commit 8b59c98. Bugbot is set up for automated code reviews on this repo. Configure here. |
Summary
When app-testnet.fuel.network moves to Cloudflare in front of Railway, the first X-Forwarded-For hop is a Cloudflare address for every visitor, so the per-IP rate limit would collapse onto a handful of keys. nginx now keys on CF-Connecting-IP whenever the first hop is inside Cloudflare's published ranges, and on the first hop otherwise. This commit was on #699 but landed after the squash merge, so main did not get it. It also adds explicit GITHUB_TOKEN permissions to the two api-lite workflows, which CodeQL flagged on #700.
Changes
geoblock over Cloudflare's IP ranges plus amapthat picks CF-Connecting-IP behind Cloudflare and the first forwarded hop otherwise, exposed as$client_ip/etc/nginx/cloudflare-ips.conf; the build fails on an empty fetchRATE_LIMIT_KEY=$client_ipfor the explorer service, with the reasoning next to itpermissions: contents: readon the uptime probe;contents: readandpackages: readon the api-lite e2e job🤖 Generated with Claude Code