From 95414d4380b97b86807dd7a01775900dd8f76b51 Mon Sep 17 00:00:00 2001 From: Kaare Hoff Skovgaard Date: Sun, 20 Jul 2025 22:55:21 +0200 Subject: [PATCH] Tweak nginx fail2ban --- .../vault-loki-sender/loki_endpoint.alloy | 1 + .../vault-prometheus-sender/prometheus.alloy | 2 +- .../nixos/services/fail2ban/default.nix | 49 +++++++++++++++++++ nix/modules/nixos/services/nginx/default.nix | 34 ++++++++++++- nix/profiles/nixos/khs-server.nix | 1 + 5 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 nix/modules/nixos/services/fail2ban/default.nix diff --git a/nix/modules/nixos/infrastructure/vault-loki-sender/loki_endpoint.alloy b/nix/modules/nixos/infrastructure/vault-loki-sender/loki_endpoint.alloy index bf541fc..df7ac27 100644 --- a/nix/modules/nixos/infrastructure/vault-loki-sender/loki_endpoint.alloy +++ b/nix/modules/nixos/infrastructure/vault-loki-sender/loki_endpoint.alloy @@ -10,6 +10,7 @@ declare "loki_send" { cert_file = sys.env("LOKI_CLIENT_CERT") key_file = sys.env("LOKI_CLIENT_KEY") } + batch_wait = "1m" } external_labels = { job = argument.job.value, diff --git a/nix/modules/nixos/infrastructure/vault-prometheus-sender/prometheus.alloy b/nix/modules/nixos/infrastructure/vault-prometheus-sender/prometheus.alloy index e1c94b6..1ee6dff 100644 --- a/nix/modules/nixos/infrastructure/vault-prometheus-sender/prometheus.alloy +++ b/nix/modules/nixos/infrastructure/vault-prometheus-sender/prometheus.alloy @@ -50,7 +50,7 @@ prometheus.exporter.unix "integrations_node_exporter" { // Define how to scrape metrics from the node_exporter prometheus.scrape "integrations_node_exporter" { -scrape_interval = "15s" +scrape_interval = "1m" // Use the targets with labels from the discovery.relabel component targets = discovery.relabel.integrations_node_exporter.output // Send the scraped metrics to the relabeling component diff --git a/nix/modules/nixos/services/fail2ban/default.nix b/nix/modules/nixos/services/fail2ban/default.nix new file mode 100644 index 0000000..4717e05 --- /dev/null +++ b/nix/modules/nixos/services/fail2ban/default.nix @@ -0,0 +1,49 @@ +{ config, lib, ... }: +let + cfg = config.khscodes.services.fail2ban; +in +{ + options.khscodes.services.fail2ban = { + enable = lib.mkEnableOption "Enables fail2ban service for the instance"; + actions = lib.mkOption { + type = lib.types.listOf lib.types.path; + description = "Extra actions to add to fail2ban"; + default = [ ]; + }; + filters = lib.mkOption { + type = lib.types.listOf lib.types.path; + description = "Extra filters to add to fail2ban"; + default = [ ]; + }; + }; + + config = lib.mkIf cfg.enable { + environment.etc = + (lib.listToAttrs ( + lib.lists.map (a: { + name = "fail2ban/action.d/${builtins.baseNameOf a}"; + value = { + source = a; + }; + }) cfg.actions + )) + // (lib.listToAttrs ( + lib.lists.map (f: { + name = "fail2ban/filter.d/${builtins.baseNameOf f}"; + value = { + source = f; + }; + }) cfg.filters + )); + services.fail2ban = { + enable = true; + bantime = "1h"; + bantime-increment = { + enable = true; + multipliers = "1 2 4 8 16 32 64 128 256"; + maxtime = "168h"; # Do not ban for more than 1 week + overalljails = true; + }; + }; + }; +} diff --git a/nix/modules/nixos/services/nginx/default.nix b/nix/modules/nixos/services/nginx/default.nix index b69f63b..b8edf21 100644 --- a/nix/modules/nixos/services/nginx/default.nix +++ b/nix/modules/nixos/services/nginx/default.nix @@ -128,6 +128,34 @@ in message = "Cannot use `config.khscodes.services.nginx.virtualHosts..acme = {}` without setting config.khscodes.security.acme.dns01Enabled"; } ]; + services.fail2ban.jails = { + nginx-botsearch = { + 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 = "nginx-botsearch"; + action = ''${config.services.fail2ban.banaction}[name=HTTP, port="http,https"]''; + logpath = "/var/log/nginx/access.log"; + backend = "auto"; + findtime = 600; + maxretry = 5; + }; + }; + nginx-bad-request = { + 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 = "nginx-bad-request"; + action = ''${config.services.fail2ban.banaction}[name=HTTP, port="http,https"]''; + logpath = "/var/log/nginx/access.log"; + backend = "auto"; + findtime = 600; + maxretry = 1; + }; + }; + }; khscodes.networking.aliases = lib.attrsets.attrNames cfg.virtualHosts; khscodes.security.acme.enable = true; security.dhparams.enable = lib.mkIf (cfg.sslConfiguration == "intermediate") { @@ -138,7 +166,11 @@ in }; services.nginx = { enable = true; - package = lib.mkDefault pkgs.nginxStable; + package = lib.mkDefault ( + pkgs.nginxStable.overrideAttrs (oldAttrs: { + nativeBuildInputs = oldAttrs.nativeBuildInputs ++ [ pkgs.pkg-config ]; + }) + ); statusPage = config.khscodes.infrastructure.vault-prometheus-sender.enable; sslDhparam = lib.mkIf ( cfg.sslConfiguration == "intermediate" diff --git a/nix/profiles/nixos/khs-server.nix b/nix/profiles/nixos/khs-server.nix index b02b275..10ec0f6 100644 --- a/nix/profiles/nixos/khs-server.nix +++ b/nix/profiles/nixos/khs-server.nix @@ -5,6 +5,7 @@ environment.systemPackages = [ pkgs.khscodes.bao-import-secret ]; khscodes = { services.openssh.enable = true; + services.fail2ban.enable = true; machine.type = "server"; os.auto-update.enable = true; infrastructure = {