diff options
| author | Quentin Aristote <quentin@aristote.fr> | 2021-08-06 16:20:44 +0200 |
|---|---|---|
| committer | Quentin Aristote <quentin@aristote.fr> | 2021-08-06 16:20:44 +0200 |
| commit | 210d4e7c2e7102355e8ef92681800157faa57d16 (patch) | |
| tree | c1c599a66e34cc86056c094c438fe742ae41c03e /config/searx | |
initial commit
Diffstat (limited to 'config/searx')
| -rw-r--r-- | config/searx/default.nix | 236 | ||||
| -rw-r--r-- | config/searx/filtron.json | 129 |
2 files changed, 365 insertions, 0 deletions
diff --git a/config/searx/default.nix b/config/searx/default.nix new file mode 100644 index 0000000..1181d22 --- /dev/null +++ b/config/searx/default.nix @@ -0,0 +1,236 @@ +{ pkgs, lib, ... }: + +let + ports = { + searx = 8888; + filtron = { + listen = 4004; + api = 4005; + }; + morty = 3000; + }; + keys = { morty = "1t/rvXuoX/9OKwZ6Zby1zBc5t1DRFYIiE15xhIi72TKX"; }; +in { + # Nginx + services.nginx.virtualHosts."searx.aristote.fr" = { + locations = { + "/" = { + proxyPass = "http://127.0.0.1:${toString ports.filtron.listen}"; + extraConfig = '' + proxy_set_header Host $host; + proxy_set_header Connection $http_connection; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Scheme $scheme; + # proxy_set_header X-Script-Name /; + ''; + }; + "/static/" = { alias = "${pkgs.searx}/share/static/"; }; + "/morty" = { + proxyPass = "http://127.0.0.1:${toString ports.morty}"; + extraConfig = '' + proxy_set_header Host $host; + proxy_set_header Connection $http_connection; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Scheme $scheme; + ''; + }; + }; + }; + + # Searx + services.searx = { + enable = true; + environmentFile = /etc/searx/secrets; + settings = { + use_default_settings = true; + general = { + debug = false; + contact_url = "mailto:quentin@aristote.fr"; + enable_stats = false; + }; + search = { + autocomplete = "dbpedia"; + default_lang = "fr-FR"; + }; + server = { + secret_key = "@SECRET_KEY@"; + image_proxy = true; + http_protocol_version = "1.0"; + method = "GET"; + }; + ui = { + # default_locale = "fr"; + theme_args = { oscar_style = "pointhi"; }; + }; + # result_proxy = { + # url = "http://searx.aristote.fr/morty"; + # key = ''!!binary | "${keys.morty}"''; + # }; + enabled_plugins = [ + "Open Access DOI rewrite" + "Hash plugin" + "HTTPS rewrite" + "Self Informations" + "Search on category select" + "Tracker URL remover" + "Vim-like hotkeys" + ]; + }; + runInUwsgi = true; + uwsgiConfig = { + cache2 = "name=searxcache,items=2000,blocks=2000,blocksize=4096,bitmap=1"; + http = ":${toString ports.searx}"; + }; + }; + + # Filtron + # users.users.filtron = { + # description = "Filtron daemon user"; + # group = "filtron"; + # isSystemUser = true; + # }; + # users.groups.filtron = { }; + + # systemd.services.filtron = { + # wantedBy = [ "multi-user.target" ]; + # after = [ "network.target" ]; + # description = "Start a filtron instance."; + # serviceConfig = { + # User = "filtron"; + # ExecStart = '' + # ${pkgs.personal.filtron}/bin/filtron -rules ${./filtron.json} \ + # -api "127.0.0.1:${toString ports.filtron.api}" \ + # -listen "127.0.0.1:${toString ports.filtron.listen}" \ + # -target "127.0.0.1:${toString ports.searx}" + # ''; + # }; + # }; + + services.filtron = { + enable = true; + rules = [ + { + name = "roboagent limit"; + filters = [ + "Header:User-Agent=(curl|cURL|Wget|python-requests|Scrapy|FeedFetcher|Go-http-client|Ruby|UniversalFeedParser)" + ]; + limit = 0; + stop = true; + actions = [ + { name = "log"; } + { + name = "block"; + params = { message = "Rate limit exceeded"; }; + } + ]; + } + { + name = "botlimit"; + filters = [ + "Header:User-Agent=(Googlebot|bingbot|Baiduspider|yacybot|YandexMobileBot|YandexBot|Yahoo! Slurp|MJ12bot|AhrefsBot|archive.org_bot|msnbot|MJ12bot|SeznamBot|linkdexbot|Netvibes|SMTBot|zgrab|James BOT)" + ]; + limit = 0; + stop = true; + actions = [ + { name = "log"; } + { + name = "block"; + params = { message = "Rate limit exceeded"; }; + } + ]; + } + { + name = "suspiciously frequent IP"; + filters = [ ]; + interval = 600; + limit = 30; + aggregations = [ "Header:X-Forwarded-For" ]; + actions = [{ name = "log"; }]; + } + { + name = "search request"; + filters = [ "Param:q" "Path=^(/|/search)$" ]; + interval = 61; + limit = 999; + subrules = [ + { + name = "missing Accept-Language"; + filters = [ "!Header:Accept-Language" ]; + limit = 0; + stop = true; + actions = [ + { name = "log"; } + { + name = "block"; + params = { message = "Rate limit exceeded"; }; + } + ]; + } + { + name = "suspiciously Connection=close header"; + filters = [ "Header:Connection=close" ]; + limit = 0; + stop = true; + actions = [ + { name = "log"; } + { + name = "block"; + params = { message = "Rate limit exceeded"; }; + } + ]; + } + { + name = "IP limit"; + interval = 61; + limit = 9; + stop = true; + aggregations = [ "Header:X-Forwarded-For" ]; + actions = [ + { name = "log"; } + { + name = "block"; + params = { message = "Rate limit exceeded"; }; + } + ]; + } + { + name = "rss/json limit"; + filters = [ "Param:format=(csv|json|rss)" ]; + interval = 121; + limit = 2; + stop = true; + actions = [ + { name = "log"; } + { + name = "block"; + params = { message = "Rate limit exceeded"; }; + } + ]; + } + { + name = "useragent limit"; + interval = 61; + limit = 199; + aggregations = [ "Header:User-Agent" ]; + actions = [ + { name = "log"; } + { + name = "block"; + params = { message = "Rate limit exceeded"; }; + } + ]; + } + ]; + } + ]; + }; + + # Morty + # services.morty = { + # enable = true; + # key = keys.morty; + # port = ports.morty; + # }; +} diff --git a/config/searx/filtron.json b/config/searx/filtron.json new file mode 100644 index 0000000..285d933 --- /dev/null +++ b/config/searx/filtron.json @@ -0,0 +1,129 @@ +[ + { + name = "roboagent limit"; + filters = [ + "Header:User-Agent=(curl|cURL|Wget|python-requests|Scrapy|FeedFetcher|Go-http-client|Ruby|UniversalFeedParser)" + ]; + limit = 0; + stop = true; + actions = [ + { name = "log"; }; + { name = "block"; + params = { + message = "Rate limit exceeded" + }; + }; + ]; + }; + { + name = "botlimit"; + filters = [ + "Header:User-Agent=(Googlebot|bingbot|Baiduspider|yacybot|YandexMobileBot|YandexBot|Yahoo! Slurp|MJ12bot|AhrefsBot|archive.org_bot|msnbot|MJ12bot|SeznamBot|linkdexbot|Netvibes|SMTBot|zgrab|James BOT)" + ]; + limit = 0; + stop = true; + actions = [ + { name = "log"; }; + { name = "block"; + params = { + message = "Rate limit exceeded" + }; + }; + ]; + }; + { + name = "suspiciously frequent IP"; + filters = []; + interval = 600; + limit = 30; + aggregations = [ + "Header:X-Forwarded-For" + ]; + actions =[ + {name ="log"; }; + ]; + }; + { + name = "search request"; + filters = [ + "Param:q"; + "Path=^(/|/search)$" + ]; + interval = 61; + limit = 999; + subrules = [ + { + name = "missing Accept-Language"; + filters = ["!Header:Accept-Language"]; + limit = 0; + stop = true; + actions = [ + {name ="log"; }; + {name = "block"; + params = {"message": "Rate limit exceeded"; }}; + ]; + }; + { + name = "suspiciously Connection=close header"; + filters = ["Header:Connection=close"]; + limit = 0; + stop = true; + actions = [ + {name ="log"; }; + {name = "block"; + params = {"message": "Rate limit exceeded"; }}; + ]; + }; + { + name = "IP limit"; + interval = 61; + limit = 9; + stop = true; + aggregations = [ + "Header:X-Forwarded-For" + ]; + actions = [ + { name = "log"; }; + { name = "block"; + params = { + message = "Rate limit exceeded" + }; + }; + ]; + }; + { + name = "rss/json limit"; + filters = [ + "Param:format=(csv|json|rss)" + ]; + interval = 121; + limit = 2; + stop = true; + actions = [ + { name = "log"; }; + { name = "block"; + params = { + message = "Rate limit exceeded" + }; + }; + ]; + }; + { + name = "useragent limit"; + interval = 61; + limit = 199; + aggregations = [ + "Header:User-Agent" + ]; + actions = [ + { name = "log"; }; + { name = "block"; + params = { + message = "Rate limit exceeded" + }; + }; + ]; + }; + ]; + }; +]; |
