From 210d4e7c2e7102355e8ef92681800157faa57d16 Mon Sep 17 00:00:00 2001 From: Quentin Aristote Date: Fri, 6 Aug 2021 16:20:44 +0200 Subject: initial commit --- config/boot.nix | 12 ++ config/default.nix | 22 ++++ config/environment.nix | 16 +++ config/hardware-configuration.nix | 28 +++++ config/networking.nix | 37 ++++++ config/searx/default.nix | 236 ++++++++++++++++++++++++++++++++++++++ config/searx/filtron.json | 129 +++++++++++++++++++++ config/users.nix | 11 ++ 8 files changed, 491 insertions(+) create mode 100644 config/boot.nix create mode 100644 config/default.nix create mode 100644 config/environment.nix create mode 100644 config/hardware-configuration.nix create mode 100644 config/networking.nix create mode 100644 config/searx/default.nix create mode 100644 config/searx/filtron.json create mode 100644 config/users.nix (limited to 'config') diff --git a/config/boot.nix b/config/boot.nix new file mode 100644 index 0000000..df60fea --- /dev/null +++ b/config/boot.nix @@ -0,0 +1,12 @@ +{ ... }: + +{ + boot = { + loader.grub = { + enable = true; + version = 2; + enableCryptodisk = true; + device = "/dev/vda"; + }; + }; +} diff --git a/config/default.nix b/config/default.nix new file mode 100644 index 0000000..39de497 --- /dev/null +++ b/config/default.nix @@ -0,0 +1,22 @@ +{ pkgs, modulesPath, ... }: + +{ + imports = [ + (modulesPath + "/profiles/headless.nix") + (modulesPath + "/profiles/minimal.nix") + ./boot.nix + ./environment.nix + ./hardware-configuration.nix + ./networking.nix + ./searx + ./users.nix + ]; + + # This value determines the NixOS release from which the default + # settings for stateful data, like file locations and database versions + # on your system were taken. It‘s perfectly fine and recommended to leave + # this value at the release version of the first install of this system. + # Before changing this value read the documentation for this option + # (e.g. man configuration.nix or on https://nixos.org/nixos/options.html). + system.stateVersion = "20.03"; # Did you read the comment? +} diff --git a/config/environment.nix b/config/environment.nix new file mode 100644 index 0000000..e8faf42 --- /dev/null +++ b/config/environment.nix @@ -0,0 +1,16 @@ +{ pkgs, ... }: + +{ + environment.systemPackages = with pkgs; [ vim ]; + programs.bash.promptInit = '' + PS1='\n\[\033[1;32m\][\[\e]0;\u@\H: \w\a\]\u@\H:\w]\$\[\033[0m\] ' + ''; + + i18n.defaultLocale = "en_US.UTF-8"; + console = { + font = "Lat2-Terminus16"; + keyMap = "fr"; + }; + + time.timeZone = "Europe/Paris"; +} diff --git a/config/hardware-configuration.nix b/config/hardware-configuration.nix new file mode 100644 index 0000000..efcdb77 --- /dev/null +++ b/config/hardware-configuration.nix @@ -0,0 +1,28 @@ +{ lib, modulesPath, ... }: + +{ + imports = [ (modulesPath + "/profiles/qemu-guest.nix") ]; + + boot.initrd.availableKernelModules = + [ "ata_piix" "uhci_hcd" "virtio_pci" "sr_mod" "virtio_blk" ]; + boot.initrd.kernelModules = [ ]; + boot.kernelModules = [ "kvm-amd" ]; + boot.extraModulePackages = [ ]; + + fileSystems."/" = { + device = "/dev/disk/by-uuid/2b302948-5608-41c6-b54c-1c0e39ff6a58"; + fsType = "ext4"; + }; + + boot.initrd.luks.devices."root".device = + "/dev/disk/by-uuid/eaec758b-ba22-42ab-8992-e765cec9be55"; + + fileSystems."/boot" = { + device = "/dev/disk/by-uuid/74d78eba-c29a-4724-8fb7-624e0a03faa5"; + fsType = "ext4"; + }; + + swapDevices = [{ device = "/swap"; }]; + + nix.maxJobs = lib.mkDefault 1; +} diff --git a/config/networking.nix b/config/networking.nix new file mode 100644 index 0000000..21bcc83 --- /dev/null +++ b/config/networking.nix @@ -0,0 +1,37 @@ +{ ... }: + +{ + networking = { + hostName = "hermes.aristote.fr"; + + useDHCP = false; + interfaces.ens3.ipv4.addresses = [{ + address = "93.95.228.53"; + prefixLength = 16; + }]; + defaultGateway = "93.95.228.1"; + nameservers = [ "93.95.224.28" "93.95.224.29" ]; + + firewall = { + enable = true; + allowedTCPPorts = [ 80 443 ]; + }; + }; + + services.nginx = { + enable = true; + virtualHosts = { + "quentin.aristote.fr" = { root = "${pkgs.personal.academic-webpage}"; }; + }; + }; + + services.openssh = { + enable = true; + permitRootLogin = "no"; + passwordAuthentication = false; + extraConfig = '' + AcceptEnv PS1 + ''; + }; + services.fail2ban.enable = true; +} 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" + }; + }; + ]; + }; + ]; + }; +]; diff --git a/config/users.nix b/config/users.nix new file mode 100644 index 0000000..99a497d --- /dev/null +++ b/config/users.nix @@ -0,0 +1,11 @@ +{ ... }: + +{ + users.users.qaristote = { + isNormalUser = true; + extraGroups = [ "wheel" ]; + openssh.authorizedKeys.keys = [ + "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIK4wGbl3++lqCjLUhoRyABBrVEeNhIXYO4371srkRoyq qaristote@latitude-7490" + ]; + }; +} -- cgit v1.2.3