From c4fa991b621d1008abea1958477d2a1c17ece531 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Tristan=20Dani=C3=ABl=20Maat?= <tm@tlater.net>
Date: Fri, 14 Oct 2022 01:11:15 +0100
Subject: [PATCH] treewide: Add fail2ban

---
 configuration/default.nix            | 21 +++++++++++++++++++++
 configuration/services/gitea.nix     | 19 +++++++++++++++++++
 configuration/services/nextcloud.nix | 23 +++++++++++++++++++++++
 3 files changed, 63 insertions(+)

diff --git a/configuration/default.nix b/configuration/default.nix
index 52be9a1..da5b45b 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -84,5 +84,26 @@
     acceptTerms = true;
   };
 
+  services.fail2ban = {
+    enable = true;
+    extraPackages = [pkgs.ipset];
+    banaction = "iptables-ipset-proto6-allports";
+    bantime-increment.enable = true;
+
+    jails = {
+      nginx-botsearch = ''
+        enabled = true
+        logpath = /var/log/nginx/access.log
+      '';
+    };
+
+    ignoreIP = [
+      "127.0.0.0/8"
+      "10.0.0.0/8"
+      "172.16.0.0/12"
+      "192.168.0.0/16"
+    ];
+  };
+
   system.stateVersion = "20.09";
 }
diff --git a/configuration/services/gitea.nix b/configuration/services/gitea.nix
index cd99951..f346097 100644
--- a/configuration/services/gitea.nix
+++ b/configuration/services/gitea.nix
@@ -28,4 +28,23 @@ in {
 
     locations."/".proxyPass = "http://${httpAddress}:${toString httpPort}";
   };
+
+  # Block repeated failed login attempts
+  #
+  # TODO(tlater): Update to the new regex, since apparently this one
+  # is deprecated (but the new one doesn't work on the current version
+  # of gitea yet): https://docs.gitea.io/en-us/fail2ban-setup/
+  environment.etc = {
+    "fail2ban/filter.d/gitea.conf".text = ''
+      [Definition]
+      failregex = .*(Failed authentication attempt|invalid credentials|Attempted access of unknown user).* from <HOST>
+      journalmatch = _SYSTEMD_UNIT=gitea.service + _COMM=gitea + SYSLOG_IDENTIFIER=gitea
+    '';
+  };
+
+  services.fail2ban.jails = {
+    gitea = ''
+      enabled = true
+    '';
+  };
 }
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index ce43280..070cd7e 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -96,4 +96,27 @@ in {
     forceSSL = true;
     enableACME = true;
   };
+
+  # Block repeated failed login attempts
+  environment.etc = {
+    "fail2ban/filter.d/nextcloud.conf".text = ''
+      [Definition]
+      _groupsre = (?:(?:,?\s*"\w+":(?:"[^"]+"|\w+))*)
+      failregex = \{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Login failed:
+                  \{%(_groupsre)s,?\s*"remoteAddr":"<HOST>"%(_groupsre)s,?\s*"message":"Trusted domain error.
+      datepattern = ,?\s*"time"\s*:\s*"%%Y-%%m-%%d[T ]%%H:%%M:%%S(%%z)?"
+      journalmatch = SYSLOG_IDENTIFIER=Nextcloud
+    '';
+  };
+
+  services.fail2ban.jails = {
+    nextcloud = ''
+      enabled = true
+
+      # Nextcloud does some throttling already, so we need to set
+      # these to something bigger.
+      findtime = 43200
+      bantime = 86400
+    '';
+  };
 }