From 8e1905a695add77d18ca8a2e16cd4c40437bbca9 Mon Sep 17 00:00:00 2001 From: Mustafa <104644957+Blacks-Army@users.noreply.github.com> Date: Sun, 12 Apr 2026 20:19:32 +0200 Subject: [PATCH] Exclude local/private/CGNAT IPs from COUNTRY=ALL and ASN=ALL/AS0 geo-blocking rules --- server/routers/badger/verifySession.ts | 57 ++++++++++++++++++++++---- 1 file changed, 50 insertions(+), 7 deletions(-) diff --git a/server/routers/badger/verifySession.ts b/server/routers/badger/verifySession.ts index e2e5f6766..d3c110728 100644 --- a/server/routers/badger/verifySession.ts +++ b/server/routers/badger/verifySession.ts @@ -1003,7 +1003,11 @@ async function checkRules( isIpInCidr(clientIp, rule.value) ) { return rule.action as any; - } else if (clientIp && rule.match == "IP" && clientIp == rule.value) { + } else if ( + clientIp && + rule.match == "IP" && + clientIp == rule.value + ) { return rule.action as any; } else if ( path && @@ -1013,16 +1017,35 @@ async function checkRules( return rule.action as any; } else if ( clientIp && - rule.match == "COUNTRY" && - (await isIpInGeoIP(ipCC, rule.value)) + rule.match == "COUNTRY" ) { - return rule.action as any; + // COUNTRY=ALL should not affect local/private/CGNAT addresses. + if ( + rule.value.toUpperCase() === "ALL" && + isLocalOrCarrierGradeNatIp(clientIp) + ) { + continue; + } + + if (await isIpInGeoIP(ipCC, rule.value)) { + return rule.action as any; + } } else if ( clientIp && - rule.match == "ASN" && - (await isIpInAsn(ipAsn, rule.value)) + rule.match == "ASN" ) { - return rule.action as any; + // ASN=ALL/AS0 should not affect local/private/CGNAT addresses. + if ( + (rule.value.toUpperCase() === "ALL" || + rule.value.toUpperCase() === "AS0") && + isLocalOrCarrierGradeNatIp(clientIp) + ) { + continue; + } + + if (await isIpInAsn(ipAsn, rule.value)) { + return rule.action as any; + } } else if ( clientIp && rule.match == "REGION" && @@ -1184,6 +1207,26 @@ async function isIpInGeoIP( return ipCountryCode?.toUpperCase() === checkCountryCode.toUpperCase(); } +function isLocalOrCarrierGradeNatIp(ip: string): boolean { + const localAndCgnatCidrs = [ + "10.0.0.0/8", + "172.16.0.0/12", + "192.168.0.0/16", + "100.64.0.0/10", + "127.0.0.0/8", + "169.254.0.0/16", + "::1/128", + "fc00::/7", + "fe80::/10" + ]; + + try { + return localAndCgnatCidrs.some((cidr) => isIpInCidr(ip, cidr)); + } catch { + return false; + } +} + async function isIpInAsn( ipAsn: number | undefined, checkAsn: string