From 6ec54454a28f4bf064f937b9631dfd45f087d1c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9o=20Barnouin?= Date: Fri, 4 Apr 2025 10:36:38 +0200 Subject: [PATCH] Add crowdsec module and cs-firewall-bouncer package --- flake.nix | 6 +- modules/cs-firewall-bouncer.nix | 102 ++++++++++++++++++++++++++++++++ modules/default.nix | 6 ++ 3 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 modules/cs-firewall-bouncer.nix create mode 100644 modules/default.nix diff --git a/flake.nix b/flake.nix index 5c9bdc0..279be37 100644 --- a/flake.nix +++ b/flake.nix @@ -66,12 +66,16 @@ "${inputs.nixpkgs}/nixos/modules/virtualisation/proxmox-lxc.nix" "${inputs.self}/systems/minimalLXCConfig.nix" "${inputs.self}/services" + "${inputs.self}/modules" { networking.hostName = "nginx"; - services + services = { vm_nginx = { enable = true; }; + crowdsec-firewall-bouncer = { + enable = true; + }; crowdsec = { enable = true; autoUpdateService = false; diff --git a/modules/cs-firewall-bouncer.nix b/modules/cs-firewall-bouncer.nix new file mode 100644 index 0000000..ea3896e --- /dev/null +++ b/modules/cs-firewall-bouncer.nix @@ -0,0 +1,102 @@ +{ + config, + pkgs, + lib, + ... +}: let + cfg = config.services.crowdsec-firewall-bouncer; + format = pkgs.formats.yaml {}; + configFile = format.generate "crowdsec.yaml" cfg.settings; + + pkg = cfg.package; + + backend = + if config.networking.nftables.enable + then "nftables" + else "iptables"; + + defaultSettings = with lib; { + log_mode = "stdout"; + + mode = mkDefault backend; + ipset_type = mkDefault "nethash"; + update_frequency = mkDefault "10s"; + deny_action = mkDefault "DROP"; + blacklists_ipv4 = mkDefault "crowdsec-blacklists"; + blacklists_ipv6 = mkDefault "crowdsec6-blacklists"; + iptables_chains = mkDefault ["INPUT"]; + }; +in { + options.services.crowdsec-firewall-bouncer = with lib; { + enable = mkEnableOption "CrowSec Firewall Bouncer"; + package = mkPackageOption pkgs "crowdsec-firewall-bouncer" {}; + settings = mkOption { + description = '' + Settings for CrowdSec Firewall Bouncer. Refer to for details. + ''; + type = format.type; + default = {}; + }; + }; + config = lib.mkIf (cfg.enable) { + services.crowdsec-firewall-bouncer.settings = defaultSettings; + + systemd.packages = [pkg]; + systemd.services = { + crowdsec-firewall-bouncer = { + description = "Crowdsec Firewall Bouncer"; + + path = [pkg pkgs.ipset pkgs.iptables pkgs.nftables]; + + wantedBy = ["multi-user.target"]; + partOf = ["firewall.service"]; + + serviceConfig = with lib; { + Type = "notify"; + Restart = "on-failure"; + RestartSec = 10; + + LimitNOFILE = mkDefault 65536; + + MemoryDenyWriteExecute = mkDefault true; + + CapabilityBoundingSet = mkDefault ["CAP_NET_ADMIN" "CAP_NET_RAW"]; + + NoNewPrivileges = mkDefault true; + LockPersonality = mkDefault true; + RemoveIPC = mkDefault true; + + ProtectSystem = mkDefault "strict"; + ProtectHome = mkDefault true; + + PrivateTmp = mkDefault true; + PrivateDevices = mkDefault true; + ProtectHostname = mkDefault true; + ProtectKernelTunables = mkDefault true; + ProtectKernelModules = mkDefault true; + ProtectControlGroups = mkDefault true; + + ProtectProc = mkDefault "invisible"; + ProcSubset = mkDefault "pid"; + + RestrictNamespaces = mkDefault true; + RestrictRealtime = mkDefault true; + RestrictSUIDSGID = mkDefault true; + + SystemCallFilter = mkDefault ["@system-service" "@network-io"]; + SystemCallArchitectures = ["native"]; + SystemCallErrorNumber = mkDefault "EPERM"; + + ExecPaths = ["/nix/store"]; + NoExecPaths = ["/"]; + + ExecStartPost = "${pkgs.coreutils}/bin/sleep 0.2"; + + ExecStart = "${pkg}/bin/cs-firewall-bouncer -c ${configFile}"; + ExecStartPre = ["${pkg}/bin/cs-firewall-bouncer -t -c ${configFile}"]; + }; + }; + }; + }; +} + diff --git a/modules/default.nix b/modules/default.nix new file mode 100644 index 0000000..cde80b7 --- /dev/null +++ b/modules/default.nix @@ -0,0 +1,6 @@ +{inputs, ...}: { + imports = [ + ./crowdsec.nix + ./cs-firewall-bouncer.nix + ]; +}