From 5c89bff35706ec370e9047a6ad4c57641bece6f3 Mon Sep 17 00:00:00 2001 From: cc-dan Date: Mon, 16 Mar 2026 05:20:40 +0000 Subject: [PATCH] =?UTF-8?q?feat:=20Tailscale/=E6=9C=AC=E6=9C=BAIP=E7=99=BD?= =?UTF-8?q?=E5=90=8D=E5=8D=95=EF=BC=8C=E5=85=8D=E5=8F=97=E9=98=B2=E7=88=86?= =?UTF-8?q?=E7=A0=B4=E5=B0=81=E7=A6=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- server.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/server.js b/server.js index 6147933..a62630e 100644 --- a/server.js +++ b/server.js @@ -439,6 +439,13 @@ const AUTH_FAIL_MAX = 3; const authFailures = new Map(); // ip -> [timestamp, ...] let bannedIPs = new Set(); +// Tailscale / loopback whitelist — never ban these IPs +function isWhitelistedIP(ip) { + if (!ip) return false; + const cleaned = ip.replace(/^::ffff:/, ''); + return cleaned === '127.0.0.1' || cleaned === '::1' || cleaned.startsWith('100.'); +} + function loadBannedIPs() { try { if (fs.existsSync(BANNED_IPS_PATH)) { @@ -461,7 +468,7 @@ function getClientIP(ws) { } function recordAuthFailure(ip) { - if (!ip) return false; + if (!ip || isWhitelistedIP(ip)) return false; const now = Date.now(); let list = authFailures.get(ip) || []; list.push(now);