Something went wrong. Try again.
🌿 Collaborative wiki on ATProto
Something went wrong. Try again.
2.4 kB · 76 lines
TypeScript
at main
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677import { BlockList, isIP, isIPv4 } from "node:net";
// Loopback is the Caddy in front of us, the rest Cloudflare's edge, from// https://www.cloudflare.com/ips (2026-08-22). Refresh when that list changes.const TRUSTED_PROXY_CIDRS = [ "127.0.0.0/8", "::1/128", "173.245.48.0/20", "103.21.244.0/22", "103.22.200.0/22", "103.31.4.0/22", "141.101.64.0/18", "108.162.192.0/18", "190.93.240.0/20", "188.114.96.0/20", "197.234.240.0/22", "198.41.128.0/17", "162.158.0.0/15", "104.16.0.0/13", "104.24.0.0/14", "172.64.0.0/13", "131.0.72.0/22", "2400:cb00::/32", "2606:4700::/32", "2803:f800::/32", "2405:b500::/32", "2405:8100::/32", "2a06:98c0::/29", "2c0f:f248::/32",];
const trustedProxies = new BlockList();for (const cidr of TRUSTED_PROXY_CIDRS) { const [net, prefix] = cidr.split("/"); if (!net || !prefix) continue; trustedProxies.addSubnet(net, Number(prefix), isIPv4(net) ? "ipv4" : "ipv6");}
function isTrustedProxy(ip: string): boolean { return trustedProxies.check(ip, isIPv4(ip) ? "ipv4" : "ipv6");}
// ::ffff:127.0.0.1 and 127.0.0.1 are one visitor, not two buckets.function normalizeIp(raw: string | null | undefined): string | null { const value = raw?.trim(); if (!value) return null; const unmapped = value.startsWith("::ffff:") ? value.slice(7) : value; return isIP(unmapped) ? unmapped : null;}
export interface PeerAddressSource { requestIP(request: Request): { address: string } | null;}
// The address to rate-limit on, or null when the request came through no socket// we can read — headers alone are the client's to write, so they never decide.export function getClientIp( request: Request, server: PeerAddressSource | null | undefined,): string | null { const peer = normalizeIp(server?.requestIP(request)?.address); if (!peer) return null;
// Each hop appends the address it saw, so walking in from the peer is // trustworthy exactly as far as the hops are ours. const forwarded = request.headers.get("x-forwarded-for")?.split(",") ?? []; const hops = [...forwarded, peer]; for (let i = hops.length - 1; i >= 0; i--) { const hop = normalizeIp(hops[i]); if (hop && !isTrustedProxy(hop)) return hop; }
// Reached only when the whole chain is Cloudflare's or ours, so this header // is Cloudflare's, which overwrites whatever the client sent. return normalizeIp(request.headers.get("cf-connecting-ip")) ?? peer;}