diff options
| author | Quentin Aristote <quentin@aristote.fr> | 2021-08-14 19:33:50 +0200 |
|---|---|---|
| committer | Quentin Aristote <quentin@aristote.fr> | 2021-08-14 19:33:50 +0200 |
| commit | 098da93e5deb2fc0043e15f3817191f5bd668e34 (patch) | |
| tree | e779f777197a29a71dad5803b1d32f6302db7fb6 /config/services/web/searx | |
| parent | b08e8f21a4da329f0507eef1781a2e6922c27dc5 (diff) | |
restructure project
Diffstat (limited to 'config/services/web/searx')
| -rw-r--r-- | config/services/web/searx/default.nix | 32 | ||||
| -rw-r--r-- | config/services/web/searx/filtron/default.nix | 122 | ||||
| -rw-r--r-- | config/services/web/searx/morty/default.nix | 22 | ||||
| -rw-r--r-- | config/services/web/searx/searx/default.nix | 119 |
4 files changed, 295 insertions, 0 deletions
diff --git a/config/services/web/searx/default.nix b/config/services/web/searx/default.nix new file mode 100644 index 0000000..7c5e593 --- /dev/null +++ b/config/services/web/searx/default.nix @@ -0,0 +1,32 @@ +{ config, lib, ... }: + +let + cfg = { + searx = config.services.searx; + filtron = config.services.filtron; + }; +in { + imports = [ ./searx ./filtron ./morty ]; + + services.nginx.virtualHosts."searx.aristote.fr" = + lib.mkIf (cfg.searx.enable && cfg.filtron.enable) { + locations = { + "/" = { + proxyPass = "http://${cfg.filtron.listen.address}:${ + toString cfg.filtron.listen.port + }"; + 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}/sjare/static"; + }; + forceSSL = true; + enableACME = true; + }; +} diff --git a/config/services/web/searx/filtron/default.nix b/config/services/web/searx/filtron/default.nix new file mode 100644 index 0000000..cc637c3 --- /dev/null +++ b/config/services/web/searx/filtron/default.nix @@ -0,0 +1,122 @@ +{ ... }: + +{ + 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"; }; + } + ]; + } + ]; + } + ]; + }; +} diff --git a/config/services/web/searx/morty/default.nix b/config/services/web/searx/morty/default.nix new file mode 100644 index 0000000..1a2b0e7 --- /dev/null +++ b/config/services/web/searx/morty/default.nix @@ -0,0 +1,22 @@ +{ config, lib, ... }: + +let cfg = config.services.morty; +in { + services.nginx.virtualHosts."searx.aristote.fr".locations = + lib.mkIf cfg.enable { + "/morty/" = { + proxyPass = "http://127.0.0.1:${toString cfg.port}"; + 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; + ''; + }; + }; + + services.morty = { + enable = false; + }; +} diff --git a/config/services/web/searx/searx/default.nix b/config/services/web/searx/searx/default.nix new file mode 100644 index 0000000..575b978 --- /dev/null +++ b/config/services/web/searx/searx/default.nix @@ -0,0 +1,119 @@ +{ config, lib, ... }: + +let + cfg = { + morty = config.services.morty; + filtron = config.services.filtron; + }; +in { + services.searx = { + enable = true; + + runInUwsgi = true; + uwsgiConfig = { + cache2 = "name=searxcache,items=2000,blocks=2000,blocksize=4096,bitmap=1"; + http = "$http://${cfg.filtron.target.address}:${toString cfg.filtron.target.port}"; + }; + + 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 = { theme_args = { oscar_style = "pointhi"; }; }; + result_proxy = lib.mkIf cfg.morty.enable { + 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" + ]; + engines = let + disable = names: + map (name: { + inherit name; + disabled = true; + }) names; + in (disable [ + # general + "bing" + "currency" + "dictzone" + # files + "btdigg" + "torrentz" + # images + "bing images" + "ccengine" + "library of congress" + "qwant images" + # it + "hoogle" + # map + "photon" + ]) ++ [ + { + name = "emojipedia"; + engine = "xpath"; + search_url = "https://emojipedia.org/search/?q={query}"; + url_xpath = ''//ol[@class="search-results"]/li/h2/a/@href''; + title_xpath = ''//ol[@class="search-results"]/li/h2/a''; + content_xpath = ''//ol[@class="search-results"]/li/p''; + shortcut = "emoji"; + disabled = true; + about = { + website = "https://emojipedia.org/"; + wikidata_id = "Q22908129"; + official_api_documentation = ""; + use_official_api = false; + require_api_key = false; + results = "HTML"; + }; + } + { + name = "alternativeTo"; + engine = "xpath"; + paging = true; + search_url = + "https://alternativeto.net/browse/search?q={query}&p={pageno}"; + results_xpath = '' + //article[@class="row app-list-item"]/div[@class="col-xs-10 col-sm-10 col-md-11 col-lg-offset-1 col-lg-11"]''; + url_xpath = "./h3/a/@href"; + title_xpath = "./h3/a"; + content_xpath = + ''./div[@class="itemDesc read-more-box"]/p[@class="text"]''; + shortcut = "a2"; + categories = "it"; + disabled = true; + about = { + website = "https://alternativeto.net"; + wikidata_id = "Q3613175"; + official_api_documentation = ""; + use_official_api = false; + require_api_key = false; + results = "HTML"; + }; + } + ]; + }; + }; +} |
