From 51e8302c298dc99bf2b7bbc6a8717219b782b3e3 Mon Sep 17 00:00:00 2001 From: Dennis Wuitz Date: Fri, 29 Dec 2023 20:54:12 +0100 Subject: [PATCH] add fail2ban --- modules/boot.nix | 8 +++---- modules/fail2ban.nix | 45 +++++++++++++++++++++++++++++++++++++++ modules/security.nix | 6 ++++++ systems/configuration.nix | 32 ++++++++++++++-------------- 4 files changed, 71 insertions(+), 20 deletions(-) create mode 100644 modules/fail2ban.nix diff --git a/modules/boot.nix b/modules/boot.nix index 09f2284..ab84933 100644 --- a/modules/boot.nix +++ b/modules/boot.nix @@ -1,12 +1,12 @@ { config, lib, libS, ... }: let - cfg = config.boot; +cfg = config.boot; in { - options = { - boot = { - default = libS.mkOpinionatedOption "enable the boot builder"; +options = { + boot = { + default = libS.mkOpinionatedOption "enable the boot builder"; cpuType = lib.mkOption { type = lib.types.str; example = "amd"; diff --git a/modules/fail2ban.nix b/modules/fail2ban.nix new file mode 100644 index 0000000..3e9bdff --- /dev/null +++ b/modules/fail2ban.nix @@ -0,0 +1,45 @@ +{ config, lib, libS, ... }: + +let + cfg = config.services.fail2ban; +in +{ + options = { + services.fail2ban = { + recommendedDefaults = libS.mkOpinionatedOption "use fail2ban with recommended defaults"; + }; + }; + + config.services.fail2ban = lib.mkIf cfg.recommendedDefaults { + maxretry = 5; + bantime = "24h"; + bantime-increment = { + enable = true; + formula = "ban.Time * math.exp(float(ban.Count+1)*banFactor)/math.exp(1*banFactor)"; + multipliers = "1 2 4 8 16 32 64"; + maxtime = "168h"; + overalljails = true; + }; + + jails = { + apache-nohome-iptables.settings = { + # Block an IP address if it accesses a non-existent + # home directory more than 5 times in 10 minutes, + # since that indicates that it's scanning. + filter = "apache-nohome"; + action = ''iptables-multiport[name=HTTP, port="http,https"]''; + logpath = "/var/log/httpd/error_log*"; + backend = "auto"; + findtime = 600; + bantime = 600; + maxretry = 5; + }; + dovecot = { + settings = { + filter = "dovecot[mode=aggressive]"; + maxretry = 3; + }; + }; + }; + }; +} \ No newline at end of file diff --git a/modules/security.nix b/modules/security.nix index 92da521..1da8dcb 100644 --- a/modules/security.nix +++ b/modules/security.nix @@ -1,7 +1,13 @@ +# BIASED { config, lib, ... }: { config = { services = lib.mkIf config.services.gitea.enable { + fail2ban = { + enable = true; + + }; + openssh = { extraConfig = '' Match User gitea diff --git a/systems/configuration.nix b/systems/configuration.nix index 384db50..2e01794 100644 --- a/systems/configuration.nix +++ b/systems/configuration.nix @@ -25,11 +25,16 @@ }; services = { + fail2ban = { + enable = lib.mkDefault true; + recommendedDefaults = true; + }; + openssh = { enable = true; fixPermissions = true; extraConfig = ''StreamLocalBindUnlink yes''; - # below is a modified default to include ecdsa (as per this https://infosec.mozilla.org/guidelines/openssh#modern-openssh-67) + hostKeys = [ { bits = 4096; @@ -46,13 +51,20 @@ } ]; settings = { - PermitRootLogin = "no"; + ClientAliveCountMax = 10; + Compression = "NO"; + IgnoreRhosts = "yes"; + MaxAuthTries = 3; + MaxSessions = 10; PasswordAuthentication = false; - # below config options from https://sysadministrivia.com/news/hardening-ssh-security + PermitEmptyPasswords = "no"; + PermitRootLogin = "no"; + KexAlgorithms = [ "curve25519-sha256@libssh.org" "diffie-hellman-group-exchange-sha256" ]; + Ciphers = [ "chacha20-poly1305@openssh.com" "aes256-gcm@openssh.com" @@ -61,6 +73,7 @@ "aes192-ctr" "aes128-ctr" ]; + Macs = [ "hmac-sha2-512-etm@openssh.com" "hmac-sha2-256-etm@openssh.com" @@ -69,19 +82,6 @@ "hmac-sha2-256" "umac-128@openssh.com" ]; - - # below config options from Lynis recommendations - ClientAliveCountMax =2; - Compression = "NO"; - MaxAuthTries = 3; - MaxSessions = 2; - # Commenting below as I'm not sure if this will break things - # TCPKeepAlive = "NO"; - # UseDNS = "NO"; - - # below config options from https://linux-audit.com/audit-and-harden-your-ssh-configuration/ - IgnoreRhosts = "yes"; - PermitEmptyPasswords = "no"; }; }; };