summaryrefslogtreecommitdiff
path: root/searx/botdetection/limiter.py
diff options
context:
space:
mode:
authorMarkus Heiser <markus.heiser@darmarit.de>2023-06-03 13:43:34 +0200
committerMarkus Heiser <markus.heiser@darmarit.de>2023-06-05 14:07:19 +0200
commitf3763d73ad8cf93ea32d7e12713662f7963d950f (patch)
treed64964ad9d6c49e0c2c7b1d6da14ccca9d4a7c55 /searx/botdetection/limiter.py
parentde2f396e5020228db2a88babdd818fa20d7c44e3 (diff)
[mod] limiter: blocklist and passlist (ip_lists)
A blocklist and a passlist can be configured in /etc/searxng/limiter.toml:: [botdetection.ip_lists] pass_ip = [ '51.15.252.168', # IPv4 of check.searx.space ] block_ip = [ '93.184.216.34', # IPv4 of example.org ] Closes: https://github.com/searxng/searxng/issues/2127 Closes: https://github.com/searxng/searxng/pull/2129 Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
Diffstat (limited to 'searx/botdetection/limiter.py')
-rw-r--r--searx/botdetection/limiter.py33
1 files changed, 31 insertions, 2 deletions
diff --git a/searx/botdetection/limiter.py b/searx/botdetection/limiter.py
index 18ffc8407..366665854 100644
--- a/searx/botdetection/limiter.py
+++ b/searx/botdetection/limiter.py
@@ -40,6 +40,7 @@ and set the redis-url connection. Check the value, it depends on your redis DB
from __future__ import annotations
from pathlib import Path
+from ipaddress import ip_address
import flask
import werkzeug
@@ -53,6 +54,7 @@ from . import (
http_connection,
http_user_agent,
ip_limit,
+ ip_lists,
)
from ._helpers import (
@@ -84,16 +86,41 @@ def get_cfg() -> config.Config:
def filter_request(request: flask.Request) -> werkzeug.Response | None:
+ # pylint: disable=too-many-return-statements
cfg = get_cfg()
- real_ip = get_real_ip(request)
+ real_ip = ip_address(get_real_ip(request))
network = get_network(real_ip, cfg)
+
+ if request.path == '/healthz':
+ return None
+
+ # link-local
+
if network.is_link_local:
return None
- if request.path == '/healthz':
+ # block- & pass- lists
+ #
+ # 1. The IP of the request is first checked against the pass-list; if the IP
+ # matches an entry in the list, the request is not blocked.
+ # 2. If no matching entry is found in the pass-list, then a check is made against
+ # the block list; if the IP matches an entry in the list, the request is
+ # blocked.
+ # 3. If the IP is not in either list, the request is not blocked.
+
+ match, msg = ip_lists.pass_ip(real_ip, cfg)
+ if match:
+ logger.warning("PASS %s: matched PASSLIST - %s", network.compressed, msg)
return None
+ match, msg = ip_lists.block_ip(real_ip, cfg)
+ if match:
+ logger.error("BLOCK %s: matched BLOCKLIST - %s", network.compressed, msg)
+ return flask.make_response(('IP is on BLOCKLIST - %s' % msg, 429))
+
+ # methods applied on /
+
for func in [
http_user_agent,
]:
@@ -101,6 +128,8 @@ def filter_request(request: flask.Request) -> werkzeug.Response | None:
if val is not None:
return val
+ # methods applied on /search
+
if request.path == '/search':
for func in [