From f240382b163bb6c94630d880c5201b6acd1cf869 Mon Sep 17 00:00:00 2001 From: Frans Veldman Date: Sat, 13 Jun 2026 04:58:41 +0000 Subject: [PATCH] Added a whitelist capability --- README.md | 31 ++++++---- captcha-whitelist.txt | 8 +++ captcha.jpg | Bin 34292 -> 30961 bytes captcha.lua | 135 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 162 insertions(+), 12 deletions(-) create mode 100644 captcha-whitelist.txt diff --git a/README.md b/README.md index a491adb..450daa0 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,11 @@ Instructions and code to add a 90-day captcha cookie to SearxNG. The captcha eng # Introduction My SearxNG instance on [searx.thefloatinglab.world](https://searx.thefloatinglab.world) suffered so badly from bots that it became unusable. Looking around at fellow SearxNG instances learned that they all suffer from the same problem. -Despite the deployment of botlists, limiters, and manually blocking the most obvious bots, it still remained an endless battle. Most of the time my instance was useless. So either I had to give up on this project, or find a way to block the bots and let the genuine users through. A captcha system might not be popular, but on the other hand, a useless site is well, pretty useless. +Despite the deployment of botlists, limiters, and manually blocking the most obvious bots, it still remained an endless battle. +A new problem is the rise of slow trickle bots. They don't hammer the site but launch a request once per 5 minutes or so. If you have 50 or so of these, you have a request every few seconds, enough to get the instance blocked by the upstream providers. And these slow trickle bots are indistinguishable from normal users... that is, until they hit a captcha... + +Most of the time my instance was useless. So either I had to give up on this project, or find a way to block the bots and let the genuine users through. A captcha system might not be popular, but on the other hand, a useless site is, well, pretty useless. + By combining the captcha system with a cookie, only once in 90 days the user has to solve the captcha. A small price to pay for access to a wonderfull instance! # Features @@ -13,7 +17,8 @@ By combining the captcha system with a cookie, only once in 90 days the user has - The captcha, once solved, stays valid for 90 days. - No puzzles to solve, just a confirmation click. - It is recommended to [self host the open source captcha system](https://github.com/tiagozip/cap), so no information leaks to the outside world. -- The privacy and security of SearxNG are fully maintained if this self hosted captcha system is used. +- The privacy and security of SearxNG are fully maintained if this self hosted open source captcha system is used. +- Effective against slow trickle bots. - Optional automatic reporting to [AbuseIPDB](https://www.abuseipdb.com). - Optionally, Cloudflare Turnstile can be used as captcha provider instead. - Everything is script based, no compilation is necessary. @@ -22,7 +27,7 @@ By combining the captcha system with a cookie, only once in 90 days the user has ![picture](https://git.thefloatinglab.world/TheFloatingLab/SearxNG-Captcha/raw/branch/main/captcha.jpg?raw=1) # Installation -This guide is not a complete walk through. I show you my code and how I have done it. Some tweaking might be necessary, and the locations of files on your system might be different than on mine. +This guide is not a complete walk through. I show you my code and how I have done it. Some tweaking might be necessary, and the locations, ownerships and permissions of files on your system might be different than on mine. I have not made an attempt to add subdirectories to this git, so you have to download the files and place them manually in the correct locations. ## Prerequisites @@ -60,6 +65,14 @@ TURNSTILE_SECRET_KEY = 0x4AAAAAADisca-OEq9hnPskVM6G57pTXsM Do not modify this file. +## captcha-whitelist.conf +*This file is in my /etc/nginx directory.* + +This is an ip-whitelist. IP numbers listed here are excempt from the captcha and cookie check. +If you have any monitors (uptime), regularly probing the site, put them in this list. +If you are on the public searxng instance list, it is a good idea to put the IP of check.searx.space here. +If you have a fixed IP yourself, you could add it here if you don't want to have to click every three months on the captcha. + ## captcha.lua *This file is in my /etc/nginx/lua directory.* @@ -71,7 +84,6 @@ You have to modify your nginx searxng vhost file to run the captcha. - Add the optional line "access_log /var/log/nginx/searx.access.log ts;" for enhanced logging features. - Add the required line "include snippets/captcha.conf;" - Add the line "access_by_lua_block { require("captcha").guard() }" in every "Location" block that needs protection. -- Add "Location" blocks for locations that should not be protected, such as the ones used for health checks/monitoring. - Duplicate your root location "/" to "/searxng/" to catch the bots that will entry from there. You likely have no "location" for "/searxng/stats" yet, but if you use a health checker or monitor bot on the /stats directory, you can add it without the reference to the captcha system, so it remains accessible without the need for solving the captcha first. @@ -83,11 +95,6 @@ Most bots search by using "/?q=" but some also from "/searxng/?q=". So both loca include snippets/captcha.conf; # <-- REQUIRED! - # Add this location if you want to keep /searxng/stats captcha free. A reason to do this is that you might have it checked by a monitor bot (uptime). - location = /searxng/stats { - proxy_pass http://127.0.0.1:8886; - } - # You need to mention this location specifically to catch the bots that do not search via the root but via /searxng. location /searxng/ { access_by_lua_block { require("captcha").guard() } # <-- Add this! @@ -116,12 +123,12 @@ Most bots search by using "/?q=" but some also from "/searxng/?q=". So both loca - Performance & UX. Cap's PoW is invisible-style: the user clicks one checkbox, then watches a brief spinner. Solve time depends on the client device (Cap reports a default-difficulty solve at roughly 2–3s on modern hardware) — much snappier than image puzzles, but slightly more "interactive" than Turnstile's typical zero-click case. ## AbuseIPDB -- Reporting to [AbuseIPDB](https://www.abuseipdb.com) is not just for others but it benefits you too! Abusers have their own lists, and you might end up on their lists for "sites to avoid because they report" and it might carry over to other services on your site(s) as well. -- Threshold of 10 per two hours is a reasonable default but tweak WALKAWAY_THRESHOLD and WALKAWAY_TTL to taste. With WALKAWAY_TTL = 3600, the counter auto-expires after an hour of silence, so a slow trickle never builds up. I have my treshold set on two hours. +- Reporting to [AbuseIPDB](https://www.abuseipdb.com) is not just for others but it benefits you too! Abusers have their own lists, and you might end up on their lists for "sites to avoid 'cause them report us" and the effects might carry over to other services on your site(s) as well. Having said that, I have submitted *over a million* automated reports to AbuseIPDB about bots that probe port 25, try to guess SSH credentials, etc., so the problem is huge. But all bits help, and the resulting list was what I used before to weed out at least half of the offenders. +- Threshold of 10 "Walk-aways" (not solving the captcha) per two hours is a reasonable default but tweak WALKAWAY_THRESHOLD and WALKAWAY_TTL to taste. With WALKAWAY_TTL = 3600, the counter auto-expires after an hour of silence, so a slow trickle never builds up. I have my treshold set on two hours. - One report per IP per 15 minutes. The ts_reported:add() with REPORT_COOLDOWN makes sure you don't spam AbuseIPDB if a botnet member keeps hitting you. Free tier caps at 1000 reports/day; with this design you'd need ~700 distinct repeat-offender IPs/day to come close. - Behind a CDN / reverse proxy? ngx.var.remote_addr would be the proxy's IP, not the client's. Either configure ngx_http_realip_module (set_real_ip_from/real_ip_header X-Forwarded-For) so $remote_addr reflects the real client, or change the calls to ngx.var.http_x_forwarded_for (and parse out the first hop yourself). Don't ship to AbuseIPDB without verifying which IP you're sending — reporting your CDN's IP would be embarrassing. - Reset on solve is per-IP. If a real human eventually solves from the same NAT/IP, the counter clears for the whole address. Good for shared exits. -- Don't report your own monitoring. If you have uptime checks (UptimeRobot, Pingdom, internal Prometheus blackbox) hitting an HTML path without ever solving the challenge, they'll trigger this. Either point them at a path that bypasses the gate, give them a static __ts_verified cookie minted manually with a far-future expiry, or whitelist their IPs in note_walkaway. +- Don't report your own monitoring. If you have uptime checks (UptimeRobot, Pingdom, internal Prometheus blackbox) hitting an HTML path without ever solving the challenge, they'll trigger this. Put their IP's in the provided captcha-whitelist.txt file. - Tor and shared VPNs. Mass reports against shared exit nodes are controversial. If your searx instance is publicly listed, expect a chunk of legitimate traffic from Tor exits — consider raising the threshold to 25–50, or excluding well-known shared-exit ASNs. - Where the counters live. lua_shared_dict is per-Nginx-instance, in shared memory across all workers, and lost on restart. That's fine here — we don't need persistence; a bot will simply rebuild its score within an hour. The dict is sized 10 MB, which fits ~100k IPs comfortably. - Async timing. ngx.timer.at(0, …) returns immediately, so the user's HTTP response (the 200 challenge page or the 302 redirect) is never delayed by the AbuseIPDB call. The report happens in a background light-thread inside the same worker. diff --git a/captcha-whitelist.txt b/captcha-whitelist.txt new file mode 100644 index 0000000..d48358f --- /dev/null +++ b/captcha-whitelist.txt @@ -0,0 +1,8 @@ +# IPs and CIDR blocks that bypass the captcha gate entirely. +# One entry per line. Lines starting with # are comments. +# Examples: +# 1.2.3.4 +# 10.0.0.0/24 +# 2001:db8::/32 +127.0.0.1 +::1 diff --git a/captcha.jpg b/captcha.jpg index e5ca22360ed677193975584a9772c9a596379cf8..d2883d25d1b314b603c500e8a587d765a5090e47 100644 GIT binary patch literal 30961 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 b-IMc4FOs-dE;0)RkZfcE|X{%rt?03{JI8S!IE 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 diff --git a/captcha.lua b/captcha.lua index db6b4f5..2a77c35 100644 --- a/captcha.lua +++ b/captcha.lua @@ -34,6 +34,140 @@ do end end +-- ---------- whitelist ---------- +local WHITELIST_FILE = "/etc/nginx/captcha-whitelist.txt" +local wl4, wl6 = {}, {} -- {{net=..., mask=..., bits=...}, ...} + +local function ip4_to_n(ip) + local a, b, c, d = ip:match("^(%d+)%.(%d+)%.(%d+)%.(%d+)$") + if not a then return nil end + a, b, c, d = tonumber(a), tonumber(b), tonumber(c), tonumber(d) + for _, n in ipairs({a, b, c, d}) do + if not n or n < 0 or n > 255 then return nil end + end + -- Build via arithmetic so this works on plain Lua 5.1 (no bit lib) + return ((a * 256 + b) * 256 + c) * 256 + d +end + +-- Expand an IPv6 string to 8 groups of 16-bit numbers +local function ip6_to_groups(ip) + if not ip:find(":") then return nil end + local head, tail = ip:match("^(.-)::(.*)$") + local h_parts, t_parts = {}, {} + if head then + for g in (head .. ":"):gmatch("([^:]*):") do h_parts[#h_parts+1] = g end + for g in (tail .. ":"):gmatch("([^:]*):") do t_parts[#t_parts+1] = g end + if #h_parts == 1 and h_parts[1] == "" then h_parts = {} end + if #t_parts == 1 and t_parts[1] == "" then t_parts = {} end + else + for g in (ip .. ":"):gmatch("([^:]*):") do h_parts[#h_parts+1] = g end + end + local groups = {} + for _, g in ipairs(h_parts) do groups[#groups+1] = tonumber(g, 16) or -1 end + local fill = 8 - #h_parts - #t_parts + if head then + for _ = 1, fill do groups[#groups+1] = 0 end + end + for _, g in ipairs(t_parts) do groups[#groups+1] = tonumber(g, 16) or -1 end + if #groups ~= 8 then return nil end + for _, g in ipairs(groups) do + if g < 0 or g > 0xFFFF then return nil end + end + return groups +end + +local function load_whitelist() + local new4, new6, count = {}, {}, 0 + local f = io.open(WHITELIST_FILE, "r") + if not f then + ngx.log(ngx.ERR, "captcha: cannot open whitelist ", WHITELIST_FILE) + wl4, wl6 = {}, {} + return + end + for raw in f:lines() do + local line = raw:gsub("#.*$", ""):match("^%s*(.-)%s*$") or "" + if line ~= "" then + local addr, bits = line:match("^([^/]+)/(%d+)$") + if not addr then addr = line end + + if addr:find(":", 1, true) then + local g = ip6_to_groups(addr) + if g then + bits = tonumber(bits or 128) + if bits >= 0 and bits <= 128 then + new6[#new6+1] = { groups = g, bits = bits } + count = count + 1 + else + ngx.log(ngx.ERR, "captcha: bad whitelist line: ", raw) + end + else + ngx.log(ngx.ERR, "captcha: bad whitelist line: ", raw) + end + else + local n = ip4_to_n(addr) + if n then + bits = tonumber(bits or 32) + if bits >= 0 and bits <= 32 then + -- mask = 2^32 - 2^(32-bits) + local mask = (bits == 0) and 0 + or (4294967296 - 2 ^ (32 - bits)) + new4[#new4+1] = { net = n - (n % (2 ^ (32 - bits))), + mask = mask } + count = count + 1 + else + ngx.log(ngx.ERR, "captcha: bad whitelist line: ", raw) + end + else + ngx.log(ngx.ERR, "captcha: bad whitelist line: ", raw) + end + end + end + end + f:close() + wl4, wl6 = new4, new6 + ngx.log(ngx.ERR, "captcha: whitelist loaded, ", count, " entries") +end + +local function ip_whitelisted(ip) + if not ip or ip == "" then return false end + if ip:find(":", 1, true) then + local g = ip6_to_groups(ip); if not g then return false end + for _, e in ipairs(wl6) do + local bits, ok = e.bits, true + for i = 1, 8 do + if bits >= 16 then + if g[i] ~= e.groups[i] then ok = false; break end + bits = bits - 16 + elseif bits > 0 then + local shift = 16 - bits + local m = 0xFFFF - (2 ^ shift - 1) + if (g[i] - g[i] % (2 ^ shift)) ~= e.groups[i] - e.groups[i] % (2 ^ shift) then + ok = false + end + break + else + break + end + end + if ok then return true end + end + return false + else + local n = ip4_to_n(ip); if not n then return false end + for _, e in ipairs(wl4) do + -- n AND mask == net → network match + if (n - n % (4294967296 - e.mask + 0.5 - 0.5)) - (n % (2 ^ 0)) then + -- placeholder; see real check below + end + -- real check using arithmetic AND via subtraction of remainder: + local block = 4294967296 - e.mask + if (n - n % block) == e.net then return true end + end + return false + end +end + +load_whitelist() local function provider() if cfg.cap_site_key ~= "" and cfg.cap_secret_key ~= "" and cfg.cap_url ~= "" then @@ -293,6 +427,7 @@ end -- ---------- public: gate ---------- function M.guard() if ngx.var.uri == VERIFY_PATH then return end + if ip_whitelisted(ngx.var.remote_addr) then return end if cookie_is_valid(ngx.var["cookie_" .. COOKIE_NAME]) then return end -- (re-add any monitoring bypasses you set up earlier here)