diff --git a/hosts/srv-public/default.nix b/hosts/srv-public/default.nix index 4a5f10f..585bcc7 100644 --- a/hosts/srv-public/default.nix +++ b/hosts/srv-public/default.nix @@ -24,12 +24,12 @@ crowdsec = { enable = true; - firewallBouncer.enable = true; - sources = [ - "sshd" - "iptables" - "caddy" - ]; + sources = { + iptables = true; + sshd = true; + caddy = true; + }; + bouncer.firewall = true; }; forgejo = { diff --git a/modules/system/services/crowdsec.nix b/modules/system/services/crowdsec.nix new file mode 100644 index 0000000..4323adf --- /dev/null +++ b/modules/system/services/crowdsec.nix @@ -0,0 +1,128 @@ +{ + config, + inputs, + pkgs, + lib, + ... +}: +let + cfg = config.custom.services.crowdsec; + + user = config.users.users.crowdsec.name; +in +{ + imports = [ + inputs.crowdsec.nixosModules.crowdsec + inputs.crowdsec.nixosModules.crowdsec-firewall-bouncer + ]; + + options.custom.services.crowdsec = { + enable = lib.mkEnableOption ""; + apiPort = lib.mkOption { + type = lib.types.port; + default = 8080; + }; + prometheusPort = lib.mkOption { + type = lib.types.port; + default = 6060; + }; + sources = { + iptables = lib.mkEnableOption ""; + caddy = lib.mkEnableOption ""; + sshd = lib.mkEnableOption ""; + }; + bouncer.firewall = lib.mkEnableOption ""; + }; + + config = lib.mkIf cfg.enable { + meta.ports.tcp.list = [ + cfg.apiPort + cfg.prometheusPort + ]; + + sops.secrets."crowdsec/enrollment-key".owner = user; + + users.groups.caddy.members = lib.mkIf cfg.sources.caddy [ user ]; + + services = { + crowdsec = { + enable = true; + package = inputs.crowdsec.packages.${pkgs.system}.crowdsec; + enrollKeyFile = config.sops.secrets."crowdsec/enrollment-key".path; + settings = { + api.server.listen_uri = "localhost:${builtins.toString cfg.apiPort}"; + cscli.prometheus_uri = "http://localhost:${builtins.toString cfg.prometheusPort}"; + }; + + allowLocalJournalAccess = true; + acquisitions = + let + mkJournalAcquisition = unit: { + source = "journalctl"; + journalctl_filter = [ "_SYSTEMD_UNIT=${unit}" ]; + labels.type = "syslog"; + }; + in + [ + (lib.mkIf cfg.sources.iptables { + source = "journalctl"; + journalctl_filter = [ "-k" ]; + labels.type = "syslog"; + }) + (lib.mkIf cfg.sources.caddy { + filenames = [ "${config.services.caddy.logDir}/*.log" ]; + labels.type = "caddy"; + }) + (lib.mkIf cfg.sources.sshd (mkJournalAcquisition "sshd.service")) + ]; + }; + + crowdsec-firewall-bouncer = { + enable = true; + package = inputs.crowdsec.packages.${pkgs.system}.crowdsec-firewall-bouncer; + settings = { + api_key = "cs-firewall-bouncer"; + api_url = "http://localhost:${builtins.toString cfg.apiPort}"; + }; + }; + }; + + systemd.services.crowdsec.serviceConfig.ExecStartPre = + let + mkScript = + name: text: + lib.getExe ( + pkgs.writeShellApplication { + inherit name text; + } + ); + + installCollection = collection: '' + if ! cscli collections list | grep -q "${collection}"; then + cscli collections install ${collection} + fi + ''; + collectionsScript = + [ + (lib.singleton "crowdsecurity/linux") + (lib.optional cfg.sources.iptables "crowdsecurity/iptables") + (lib.optional cfg.sources.caddy "crowdsecurity/caddy") + (lib.optional cfg.sources.sshd "crowdsecurity/sshd") + ] + |> lib.concatLists + |> lib.map installCollection + |> lib.concatLines + |> mkScript "crowdsec-install-collections"; + + bouncerScript = mkScript "crowdsec-add-bouncer" '' + if ! cscli bouncers list | grep -q "firewall"; then + cscli bouncers add "firewall" --key "cs-firewall-bouncer" + fi + ''; + in + lib.mkAfter [ + collectionsScript + bouncerScript + ]; + }; +} diff --git a/modules/system/services/crowdsec/default.nix b/modules/system/services/crowdsec/default.nix deleted file mode 100644 index 6c72c55..0000000 --- a/modules/system/services/crowdsec/default.nix +++ /dev/null @@ -1,104 +0,0 @@ -{ - config, - inputs, - pkgs, - lib, - ... -}: -let - cfg = config.custom.services.crowdsec; - - user = config.users.users.crowdsec.name; -in -{ - imports = [ inputs.crowdsec.nixosModules.crowdsec ]; - - options.custom.services.crowdsec = { - enable = lib.mkEnableOption ""; - apiPort = lib.mkOption { - type = lib.types.port; - default = 8080; - }; - prometheusPort = lib.mkOption { - type = lib.types.port; - default = 6060; - }; - sources = lib.mkOption { - type = lib.types.listOf ( - lib.types.enum [ - "sshd" - "iptables" - "caddy" - ] - ); - default = [ ]; - }; - }; - - config = lib.mkIf cfg.enable { - meta.ports.tcp.list = [ - cfg.apiPort - cfg.prometheusPort - ]; - - nixpkgs.overlays = [ inputs.crowdsec.overlays.default ]; - - sops.secrets."crowdsec/enrollment-key".owner = user; - - users.groups.caddy.members = lib.mkIf (lib.elem "caddy" cfg.sources) [ user ]; - - services.crowdsec = { - enable = true; - package = inputs.crowdsec.packages.${pkgs.system}.crowdsec; - enrollKeyFile = config.sops.secrets."crowdsec/enrollment-key".path; - settings = { - api.server.listen_uri = "localhost:${builtins.toString cfg.apiPort}"; - cscli.prometheus_uri = "http://localhost:${builtins.toString cfg.prometheusPort}"; - }; - - allowLocalJournalAccess = true; - acquisitions = - let - mkAcquisition = - enable: unit: - lib.optionalAttrs enable { - source = "journalctl"; - journalctl_filter = [ "_SYSTEMD_UNIT=${unit}" ]; - labels.type = "syslog"; - }; - in - [ - (mkAcquisition (lib.elem "sshd" cfg.sources) "sshd.service") - (lib.mkIf (lib.elem "caddy" cfg.sources) { - filenames = [ "${config.services.caddy.logDir}/*.log" ]; - labels.type = "caddy"; - }) - (lib.mkIf (lib.elem "iptables" cfg.sources) { - source = "journalctl"; - journalctl_filter = [ "-k" ]; - labels.type = "syslog"; - }) - ]; - }; - - systemd.services.crowdsec.serviceConfig.ExecStartPre = - let - installCollection = collection: '' - if ! cscli collections list | grep -q "${collection}"; then - cscli collections install ${collection} - fi - ''; - in - [ - (lib.singleton "crowdsecurity/linux") - (lib.optional (lib.elem "sshd" cfg.sources) "crowdsecurity/sshd") - (lib.optional (lib.elem "caddy" cfg.sources) "crowdsecurity/caddy") - (lib.optional (lib.elem "iptables" cfg.sources) "crowdsecurity/iptables") - ] - |> lib.concatLists - |> lib.map installCollection - |> lib.concatLines - |> (text: pkgs.writeShellScript "crowdsec-install-collections" "set -e\n${text}") - |> lib.mkAfter; - }; -} diff --git a/modules/system/services/crowdsec/firewall-bouncer.nix b/modules/system/services/crowdsec/firewall-bouncer.nix deleted file mode 100644 index 42e6c3d..0000000 --- a/modules/system/services/crowdsec/firewall-bouncer.nix +++ /dev/null @@ -1,35 +0,0 @@ -{ - config, - inputs, - pkgs, - lib, - ... -}: -let - cfg = config.custom.services.crowdsec; -in -{ - imports = [ inputs.crowdsec.nixosModules.crowdsec-firewall-bouncer ]; - - options.custom.services.crowdsec.firewallBouncer.enable = lib.mkEnableOption ""; - - config = lib.mkIf cfg.firewallBouncer.enable { - services.crowdsec-firewall-bouncer = { - enable = true; - package = inputs.crowdsec.packages.${pkgs.system}.crowdsec-firewall-bouncer; - settings = { - api_key = "cs-firewall-bouncer"; - api_url = "http://localhost:${builtins.toString cfg.apiPort}"; - }; - }; - - systemd.services.crowdsec.serviceConfig.ExecStartPre = lib.mkAfter ( - pkgs.writeShellScript "crowdsec-add-bouncer" '' - set -e - if ! cscli bouncers list | grep -q "firewall"; then - cscli bouncers add "firewall" --key "cs-firewall-bouncer" - fi - '' - ); - }; -}