diff --git a/configuration/default.nix b/configuration/default.nix
index 456d12d..ef68727 100644
--- a/configuration/default.nix
+++ b/configuration/default.nix
@@ -1,4 +1,5 @@
{
+ pkgs,
lib,
modulesPath,
flake-inputs,
@@ -53,6 +54,19 @@
};
logrotate.enable = true;
+
+ postgresql = {
+ package = pkgs.postgresql_14;
+ enable = true;
+
+ # Only enable connections via the unix socket, and check with the
+ # OS to make sure the user matches the database name.
+ #
+ # See https://www.postgresql.org/docs/current/auth-pg-hba-conf.html
+ authentication = ''
+ local sameuser all peer
+ '';
+ };
};
security = {
diff --git a/configuration/services/configs/starbound.json b/configuration/services/configs/starbound.json
deleted file mode 100644
index d995fdf..0000000
--- a/configuration/services/configs/starbound.json
+++ /dev/null
@@ -1,50 +0,0 @@
-{
- "allowAdminCommands" : true,
- "allowAdminCommandsFromAnyone" : false,
- "allowAnonymousConnections" : true,
- "allowAssetsMismatch" : true,
- "anonymousConnectionsAreAdmin" : false,
- "bannedIPs" : [],
- "bannedUuids" : [],
- "checkAssetsDigest" : false,
- "clearPlayerFiles" : false,
- "clearUniverseFiles" : false,
- "clientIPJoinable" : false,
- "clientP2PJoinable" : true,
- "configurationVersion" : {
- "basic" : 2,
- "server" : 4
- },
- "crafting" : {
- "filterHaveMaterials" : false
- },
- "gameServerBind" : "::",
- "gameServerPort" : 21025,
- "interactiveHighlight" : true,
- "inventory" : {
- "pickupToActionBar" : true
- },
- "maxPlayers" : 8,
- "maxTeamSize" : 4,
- "monochromeLighting" : false,
- "playerBackupFileCount" : 3,
- "queryServerBind" : "::",
- "queryServerPort" : 21025,
- "rconServerBind" : "::",
- "rconServerPassword" : "",
- "rconServerPort" : 21026,
- "rconServerTimeout" : 1000,
- "runQueryServer" : false,
- "runRconServer" : false,
- "safeScripts" : true,
- "scriptInstructionLimit" : 10000000,
- "scriptInstructionMeasureInterval" : 10000,
- "scriptProfilingEnabled" : false,
- "scriptRecursionLimit" : 100,
- "serverFidelity" : "automatic",
- "serverName" : "tlater.net",
- "serverOverrideAssetsDigest" : null,
- "serverUsers" : {
- },
- "tutorialMessages" : true
-}
diff --git a/configuration/services/crowdsec.nix b/configuration/services/crowdsec.nix
index 174115b..819403d 100644
--- a/configuration/services/crowdsec.nix
+++ b/configuration/services/crowdsec.nix
@@ -1,45 +1,80 @@
+{ config, lib, ... }:
{
- pkgs,
- config,
- lib,
- ...
-}:
-{
- security.crowdsec = {
- enable = true;
+ services = {
+ crowdsec = {
+ enable = true;
+ autoUpdateService = true;
- parserWhitelist = [ "10.45.249.2" ];
+ settings = {
+ general.api.server = {
+ enable = true;
+ online_client.sharing = false;
+ };
- extraGroups = [
- "systemd-journal"
- "nginx"
- ];
+ lapi.credentialsFile = "/var/lib/crowdsec/state/local_credentials.yaml";
+ };
- acquisitions = [
- {
- source = "journalctl";
- labels.type = "syslog";
- journalctl_filter = [ "SYSLOG_IDENTIFIER=Nextcloud" ];
- }
+ hub = {
+ collections = [
+ "crowdsecurity/base-http-scenarios"
+ "crowdsecurity/http-cve"
+ "crowdsecurity/linux"
+ "crowdsecurity/nextcloud"
+ "crowdsecurity/nginx"
+ "crowdsecurity/sshd"
+ ];
+ };
- {
- source = "journalctl";
- labels.type = "syslog";
- journalctl_filter = [ "SYSLOG_IDENTIFIER=sshd-session" ];
- }
+ localConfig = {
+ acquisitions = [
+ {
+ labels.type = "syslog";
+ journalctl_filter = [
+ "SYSLOG_IDENTIFIER=Nextcloud"
+ "SYSLOG_IDENTIFIER=sshd-session"
+ ];
+ source = "journalctl";
+ }
- {
- labels.type = "nginx";
- filenames = [
- "/var/log/nginx/*.log"
- ]
- ++ lib.mapAttrsToList (
- vHost: _: "/var/log/nginx/${vHost}/access.log"
- ) config.services.nginx.virtualHosts;
- }
- ];
+ {
+ labels.type = "nginx";
+ filenames = [
+ "/var/log/nginx/*.log"
+ ]
+ ++ lib.mapAttrsToList (
+ vHost: _: "/var/log/nginx/${vHost}/access.log"
+ ) config.services.nginx.virtualHosts;
+ }
+ ];
- remediationComponents.firewallBouncer = {
+ parsers.s02Enrich = [
+ {
+ name = "nixos/parser-whitelist";
+ description = "Parser whitelist generated by the crowdsec NixOS module";
+ whitelist = {
+ reason = "Filtered by NixOS whitelist";
+ ip = [ "10.45.249.2" ];
+ };
+ }
+ ];
+
+ postOverflows.s01Whitelist = [
+ {
+ description = "custom matrix whitelist";
+ name = "tetsumaki/matrix";
+ whitelist = {
+ reason = "whitelist false positive for matrix";
+ expression = [
+ "evt.Overflow.Alert.Events[0].GetMeta('target_fqdn') == '${config.services.matrix-conduit.settings.global.server_name}'"
+ "evt.Overflow.Alert.GetScenario() in ['crowdsecurity/http-probing', 'crowdsecurity/http-crawl-non_statics']"
+ ];
+ };
+ }
+ ];
+ };
+ };
+
+ crowdsec-firewall-bouncer = {
enable = true;
settings.prometheus = {
enabled = true;
@@ -47,37 +82,23 @@
listen_port = "60601";
};
};
- };
- # Add whitelists for matrix
- systemd.tmpfiles.settings."10-matrix" =
- let
- stateDir = config.security.crowdsec.stateDirectory;
- in
- {
- "${stateDir}/config/postoverflows".d = {
- user = "crowdsec";
- group = "crowdsec";
- mode = "0700";
- };
+ victoriametrics.scrapeConfigs = {
+ crowdsec.targets =
+ let
+ cfg = config.services.crowdsec.settings.general;
+ address = cfg.prometheus.listen_addr;
+ port = cfg.prometheus.listen_port;
+ in
+ [ "${address}:${toString port}" ];
- "${stateDir}/config/postoverflows/s01-whitelist".d = {
- user = "crowdsec";
- group = "crowdsec";
- mode = "0700";
- };
-
- "${stateDir}/config/postoverflows/s01-whitelist/matrix-whitelist.yaml"."L+".argument =
- ((pkgs.formats.yaml { }).generate "crowdsec-matrix-whitelist.yaml" {
- name = "tetsumaki/matrix";
- description = "custom matrix whitelist";
- whitelist = {
- reason = "whitelist false positive for matrix";
- expression = [
- "evt.Overflow.Alert.Events[0].GetMeta('target_fqdn') == '${config.services.matrix-conduit.settings.global.server_name}'"
- "evt.Overflow.Alert.GetScenario() in ['crowdsecurity/http-probing', 'crowdsecurity/http-crawl-non_statics']"
- ];
- };
- }).outPath;
+ csFirewallBouncer.targets =
+ let
+ cfg = config.services.crowdsec-firewall-bouncer.settings;
+ address = cfg.prometheus.listen_addr;
+ port = cfg.prometheus.listen_port;
+ in
+ [ "${address}:${toString port}" ];
};
+ };
}
diff --git a/configuration/services/default.nix b/configuration/services/default.nix
index 1624653..bee8f44 100644
--- a/configuration/services/default.nix
+++ b/configuration/services/default.nix
@@ -11,8 +11,6 @@
./ntfy-sh
./minecraft.nix
./nextcloud.nix
- ./postgres.nix
- # ./starbound.nix -- Not currently used
./webserver.nix
./wireguard.nix
];
diff --git a/configuration/services/metrics/grafana.nix b/configuration/services/metrics/grafana.nix
index 078f27c..3b757df 100644
--- a/configuration/services/metrics/grafana.nix
+++ b/configuration/services/metrics/grafana.nix
@@ -8,80 +8,93 @@ in
443
];
- services.grafana = {
- enable = true;
- settings = {
- server = {
- http_port = 3001; # Default overlaps with gitea
- root_url = "https://metrics.tlater.net";
- };
-
- security = {
- admin_user = "tlater";
- admin_password = "$__file{${config.sops.secrets."grafana/adminPassword".path}}";
- secret_key = "$__file{${config.sops.secrets."grafana/secretKey".path}}";
- cookie_secure = true;
- cookie_samesite = "strict";
- content_security_policy = true;
- };
-
- database = {
- user = "grafana";
- name = "grafana";
- type = "postgres";
- host = "/run/postgresql";
- };
- };
-
- declarativePlugins = [
- pkgs.grafanaPlugins.victoriametrics-metrics-datasource
- pkgs.grafanaPlugins.victoriametrics-logs-datasource
- ];
-
- provision = {
+ services = {
+ grafana = {
enable = true;
+ settings = {
+ server = {
+ http_port = 3001; # Default overlaps with gitea
+ root_url = "https://metrics.tlater.net";
+ };
- datasources.settings.datasources = [
- {
- name = "Victoriametrics - tlater.net";
- url = "http://localhost:8428";
- type = "victoriametrics-metrics-datasource";
- access = "proxy";
- isDefault = true;
- }
+ security = {
+ admin_user = "tlater";
+ admin_password = "$__file{${config.sops.secrets."grafana/adminPassword".path}}";
+ secret_key = "$__file{${config.sops.secrets."grafana/secretKey".path}}";
+ cookie_secure = true;
+ cookie_samesite = "strict";
+ content_security_policy = true;
+ };
- {
- name = "Victorialogs - tlater.net";
- url = "http://${config.services.victorialogs.bindAddress}";
- type = "victoriametrics-logs-datasource";
- access = "proxy";
- }
+ database = {
+ user = "grafana";
+ name = "grafana";
+ type = "postgres";
+ host = "/run/postgresql";
+ };
+ };
+
+ declarativePlugins = [
+ pkgs.grafanaPlugins.victoriametrics-metrics-datasource
+ pkgs.grafanaPlugins.victoriametrics-logs-datasource
];
- alerting.contactPoints.settings.contactPoints = [
- {
- name = "ntfy";
- receivers = [
- {
- uid = "ntfy";
- type = "webhook";
- settings.url = "http://${config.services.ntfy-sh.settings.listen-http}/local-alerts?template=grafana";
- }
- ];
- }
- ];
+ provision = {
+ enable = true;
+
+ datasources.settings.datasources = [
+ {
+ name = "Victoriametrics - tlater.net";
+ url = "http://localhost:8428";
+ type = "victoriametrics-metrics-datasource";
+ access = "proxy";
+ isDefault = true;
+ }
+
+ {
+ name = "Victorialogs - tlater.net";
+ url = "http://${config.services.victorialogs.bindAddress}";
+ type = "victoriametrics-logs-datasource";
+ access = "proxy";
+ }
+ ];
+
+ alerting.contactPoints.settings.contactPoints = [
+ {
+ name = "ntfy";
+ receivers = [
+ {
+ uid = "ntfy";
+ type = "webhook";
+ settings.url = "http://${config.services.ntfy-sh.settings.listen-http}/local-alerts?template=grafana";
+ }
+ ];
+ }
+ ];
+ };
};
- };
- services.nginx.virtualHosts."${domain}" = {
- forceSSL = true;
- useACMEHost = "tlater.net";
- enableHSTS = true;
- locations = {
- "/".proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}";
- "/api/live" = {
- proxyWebsockets = true;
- proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}";
+ postgresql = {
+ ensureUsers = [
+ {
+ name = "grafana";
+ ensureDBOwnership = true;
+ }
+ ];
+
+ ensureDatabases = [ "grafana" ];
+ };
+
+ nginx.virtualHosts."${domain}" = {
+ forceSSL = true;
+ useACMEHost = "tlater.net";
+ enableHSTS = true;
+ locations = {
+ "/".proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}";
+ "/api/live" = {
+ proxyWebsockets = true;
+ proxyPass = "http://localhost:${toString config.services.grafana.settings.server.http_port}";
+ };
};
};
};
diff --git a/configuration/services/metrics/victoriametrics.nix b/configuration/services/metrics/victoriametrics.nix
index 71741b5..3befec0 100644
--- a/configuration/services/metrics/victoriametrics.nix
+++ b/configuration/services/metrics/victoriametrics.nix
@@ -68,22 +68,6 @@ in
coturn.targets = [ "127.0.0.1:9641" ];
- crowdsec.targets =
- let
- address = config.security.crowdsec.settings.prometheus.listen_addr;
- port = config.security.crowdsec.settings.prometheus.listen_port;
- in
- [ "${address}:${toString port}" ];
-
- csFirewallBouncer.targets =
- let
- address =
- config.security.crowdsec.remediationComponents.firewallBouncer.settings.prometheus.listen_addr;
- port =
- config.security.crowdsec.remediationComponents.firewallBouncer.settings.prometheus.listen_port;
- in
- [ "${address}:${toString port}" ];
-
immich.targets = [
"127.0.0.1:8081"
"127.0.0.1:8082"
diff --git a/configuration/services/nextcloud.nix b/configuration/services/nextcloud.nix
index 30f79ed..6628d07 100644
--- a/configuration/services/nextcloud.nix
+++ b/configuration/services/nextcloud.nix
@@ -103,6 +103,17 @@ in
};
};
+ services.postgresql = {
+ ensureUsers = [
+ {
+ name = "nextcloud";
+ ensureDBOwnership = true;
+ }
+ ];
+
+ ensureDatabases = [ "nextcloud" ];
+ };
+
# Ensure that this service doesn't start before postgres is ready
systemd.services.nextcloud-setup.after = [ "postgresql.target" ];
diff --git a/configuration/services/postgres.nix b/configuration/services/postgres.nix
deleted file mode 100644
index 85a6843..0000000
--- a/configuration/services/postgres.nix
+++ /dev/null
@@ -1,35 +0,0 @@
-{ pkgs, ... }:
-{
- services.postgresql = {
- package = pkgs.postgresql_14;
- enable = true;
-
- # Only enable connections via the unix socket, and check with the
- # OS to make sure the user matches the database name.
- #
- # See https://www.postgresql.org/docs/current/auth-pg-hba-conf.html
- authentication = ''
- local sameuser all peer
- '';
-
- # Note: The following options with ensure.* are set-only; i.e.,
- # when permissions/users/databases are removed from these lists,
- # that operation needs to be performed manually on the system as
- # well.
- ensureUsers = [
- {
- name = "grafana";
- ensureDBOwnership = true;
- }
- {
- name = "nextcloud";
- ensureDBOwnership = true;
- }
- ];
-
- ensureDatabases = [
- "grafana"
- "nextcloud"
- ];
- };
-}
diff --git a/configuration/services/starbound.nix b/configuration/services/starbound.nix
deleted file mode 100644
index 888fc3e..0000000
--- a/configuration/services/starbound.nix
+++ /dev/null
@@ -1,129 +0,0 @@
-{
- flake-inputs,
- pkgs,
- lib,
- ...
-}:
-let
- inherit (lib) concatStringsSep;
-in
-{
- networking.firewall.allowedTCPPorts = [ 21025 ];
-
- # Sadly, steam-run requires some X libs
- environment.noXlibs = false;
-
- systemd.services.starbound = {
- description = "Starbound";
- after = [ "network.target" ];
-
- serviceConfig = {
- ExecStart = "${
- flake-inputs.self.packages.${pkgs.stdenv.hostPlatform.system}.starbound
- }/bin/launch-starbound ${./configs/starbound.json}";
-
- Type = "simple";
-
- # Credential loading for steam auth (if necessary; prefer
- # anonymous login wherever possible).
- LoadCredential = "steam:/run/secrets/steam/tlater";
-
- # Security settings
- DynamicUser = true;
-
- # This is where the StateDirectory ends up
- WorkingDirectory = "/var/lib/starbound";
- # Creates /var/lib/starbound (or rather, a symlink there to
- # /var/lib/private/starbound), and sets it up to be writeable to
- # by the dynamic user.
- StateDirectory = "starbound";
-
- # Note some settings below are basically tautologous with
- # `NoNewPrivileges`, but they all work slightly differently so
- # add additional layers in case of bugs.
-
- ## THESE SETTINGS ARE A GOOD IDEA BUT THE STEAM CLIENT IS
- ## REALLY, REALLY BAD, AND FOR SOME REASON I NEED TO USE IT TO
- ## DOWNLOAD GAME SERVERS AS WELL:
- ##
- # To guarantee the above (only permits 64-bit syscalls, 32-bit
- # syscalls can circumvent the above restrictions).
- #
- # Obviously, if running a 32 bit game server, change this.
- # SystemCallArchitectures = "native";
- # Game servers shouldn't need to create new namespaces ever.
- #
- # TODO: Since steam uses namespaces for things *entirely
- # unrelated* to installing game servers, we need to allow
- # namespace access. Ideally I'd instead do this in an
- # ExecStartPre, but alas, this isn't possible because of
- # https://github.com/systemd/systemd/issues/19604.
- #
- # RestrictNamespaces = true;
-
- # Don't need to let the game server see other user accounts
- PrivateUsers = true;
- # *Probably* not harmful for game servers, which probably don't update dynamically
- ProtectHostname = true;
- # Yeah, if a game server tries to edit the hardware clock something's fishy
- ProtectClock = true;
- # Don't let game servers modify kernel settings, duh
- ProtectKernelTunables = true;
- ProtectKernelModules = true;
- ProtectKernelLogs = true;
- # Game servers shouldn't use cgroups themselves either
- ProtectControlGroups = true;
- # Most game servers will never need other socket types
- RestrictAddressFamilies = [ "AF_UNIX AF_INET AF_INET6" ];
- # Also a no-brainer, no game server should ever need this
- LockPersonality = true;
- # Some game servers will probably try to set this, but they
- # don't need it. It's only required for audio processing and
- # such, which the server end doesn't need to do.
- RestrictRealtime = true;
- # Don't allow a variety of syscalls that gameservers have no
- # business using anyway
- SystemCallFilter =
- "~"
- + (concatStringsSep " " [
- "@clock"
- "@cpu-emulation"
- "@debug"
- "@keyring"
- "@memlock"
- "@module"
- # "@mount" TODO: Consider adding when steamcmd is run in ExecStartPre
- "@obsolete"
- "@raw-io"
- "@reboot"
- # "@resources" TODO: Ditto
- "@setuid"
- "@swap"
- ]);
- # Normally only "read-only", but steamcmd will puke if there is
- # no home directory to write to (though the nix package will
- # implicitly symlink to the path that we set in its override, so
- # no actual files are created, besides a symlink).
- ProtectHome = "tmpfs";
-
- # Implied by DynamicUser anyway, but it doesn't hurt to add
- # these explicitly, at least for reference.
- RemoveIPC = true;
- PrivateTmp = true;
- PrivateDevices = true;
- NoNewPrivileges = true;
- RestrictSUIDSGID = true;
- ProtectSystem = "strict";
- # ProtectHome = "read-only"; # See further up
- };
- };
-
- services.backups.starbound = {
- user = "root";
- paths = [ "/var/lib/private/starbound/storage/universe/" ];
- pauseServices = [ "starbound.service" ];
- };
-
- # Accessed via systemd cred through /run/secrets/steam
- sops.secrets."steam/tlater" = { };
-}
diff --git a/modules/crowdsec/default.nix b/modules/crowdsec/default.nix
deleted file mode 100644
index 9cb26f9..0000000
--- a/modules/crowdsec/default.nix
+++ /dev/null
@@ -1,383 +0,0 @@
-{
- pkgs,
- lib,
- config,
- ...
-}:
-let
- cfg = config.security.crowdsec;
- settingsFormat = pkgs.formats.yaml { };
-
- hub = pkgs.fetchFromGitHub {
- owner = "crowdsecurity";
- repo = "hub";
- rev = "7a3b4753f4577257c0cbeb8f8f90c7f17d2ae008";
- hash = "sha256-HB4jHyhiO8gjBkLmpo6bDbwhfm5m5nAtNlKhDkZjt2I=";
- };
-
- cscli = pkgs.writeShellScriptBin "cscli" ''
- export PATH="$PATH:${cfg.package}/bin/"
-
- sudo=exec
- if [ "$USER" != "crowdsec" ]; then
- sudo='exec /run/wrappers/bin/sudo -u crowdsec'
- fi
-
- $sudo ${cfg.package}/bin/cscli "$@"
- '';
-
- acquisitions = ''
- ---
- ${lib.concatMapStringsSep "\n---\n" builtins.toJSON cfg.acquisitions}
- ---
- '';
-in
-{
- imports = [ ./remediations ];
-
- options.security.crowdsec =
- let
- inherit (lib.types)
- nullOr
- listOf
- package
- path
- str
- ;
- in
- {
- enable = lib.mkEnableOption "crowdsec";
-
- package = lib.mkOption {
- type = package;
- default = pkgs.crowdsec;
- };
-
- stateDirectory = lib.mkOption {
- type = path;
- readOnly = true;
-
- description = ''
- The state directory of the crowdsec instance. Cannot be
- changed, but is exposed for downstream use.
- '';
- };
-
- settings = lib.mkOption {
- inherit (settingsFormat) type;
- default = { };
-
- description = ''
- The crowdsec configuration. Refer to
-
- for details on supported values.
- '';
- };
-
- parserWhitelist = lib.mkOption {
- type = listOf str;
- default = [ ];
- description = ''
- Set of IP addresses to add to a parser-based whitelist.
-
- Addresses can be specified either as plain IP addresses or
- in CIDR notation.
- '';
- };
-
- acquisitions = lib.mkOption {
- type = listOf settingsFormat.type;
- default = [ ];
- description = ''
- Log acquisitions.
- '';
- };
-
- extraGroups = lib.mkOption {
- type = listOf str;
- default = [ ];
- description = ''
- Additional groups to make the service part of.
-
- Required to permit reading from various log sources.
- '';
- };
-
- hubConfigurations = {
- collections = lib.mkOption {
- type = listOf str;
- description = ''
- List of pre-made crowdsec collections to install.
- '';
- };
-
- scenarios = lib.mkOption {
- type = listOf str;
- description = ''
- List of pre-made crowdsec scenarios to install.
- '';
- };
-
- parsers = lib.mkOption {
- type = listOf str;
- description = ''
- List of pre-made crowdsec parsers to install.
- '';
- };
-
- postoverflows = lib.mkOption {
- type = listOf str;
- description = ''
- List of pre-made crowdsec postoverflows to install.
- '';
- };
-
- appsecConfigs = lib.mkOption {
- type = listOf str;
- description = ''
- List of pre-made crowdsec appsec configurations to install.
- '';
- };
-
- appsecRules = lib.mkOption {
- type = listOf str;
- description = ''
- List of pre-made crowdsec appsec rules to install.
- '';
- };
- };
-
- centralApiCredentials = lib.mkOption {
- type = nullOr path;
- default = null;
-
- description = ''
- The API key to access crowdsec's central API - this is
- required to access any of the shared blocklists.
-
- Use of this feature is optional, entering no API key (the
- default) turns all sharing or receiving of blocked IPs off.
-
- Note that adding the API key by itself does not enable
- sharing of blocked IPs with the central API. This limits the
- types of blocklists this instance can access.
-
- To also turn sharing blocked IPs on, set
- `api.server.online_client.sharing = true;`.
- '';
- };
-
- ctiApiKey = lib.mkOption {
- type = nullOr path;
- default = null;
-
- description = ''
- The API key for crowdsec's CTI offering.
- '';
- };
- };
-
- config = lib.mkIf cfg.enable {
- # Set up default settings; anything that *shouldn't* be changed is
- # set to the default priority so that users need to use
- # `lib.mkForce`.
- security.crowdsec = {
- stateDirectory = "/var/lib/crowdsec";
-
- settings = {
- common = {
- daemonize = true;
- # The default logs to files, which isn't the preferred way
- # on NixOS
- log_media = "stdout";
- };
-
- config_paths = {
- config_dir = "${cfg.stateDirectory}/config/";
- data_dir = "${cfg.stateDirectory}/data/";
- # This "config" file is intended to be written to using the
- # cscli tool, so you can temporarily make it so rules don't
- # do anything but log what they *would* do for
- # experimentation.
- simulation_path = "${cfg.stateDirectory}/config/simulation.yaml";
-
- pattern_dir = lib.mkDefault "${cfg.package}/share/crowdsec/config/patterns";
-
- hub_dir = hub;
- index_path = "${hub}/.index.json";
-
- # Integrations aren't supported for now
- notification_dir = lib.mkDefault "/var/empty/";
- plugin_dir = lib.mkDefault "/var/empty/";
- };
-
- crowdsec_service.acquisition_path =
- # Using an if/else here because `mkMerge` does not work in
- # YAML-type options
- if cfg.acquisitions == [ ] then
- "${cfg.package}/share/crowdsec/config/acquis.yaml"
- else
- pkgs.writeText "acquis.yaml" acquisitions;
-
- cscli = {
- prometheus_uri = lib.mkDefault "127.0.0.1:6060";
- };
-
- db_config = {
- type = lib.mkDefault "sqlite";
- db_path = lib.mkDefault "${cfg.stateDirectory}/data/crowdsec.db";
- use_wal = lib.mkDefault true;
- flush = {
- max_items = lib.mkDefault 5000;
- max_age = lib.mkDefault "7d";
- };
- };
-
- api = {
- cti = {
- enabled = cfg.ctiApiKey != null;
- key = cfg.ctiApiKey;
- };
- client.credentials_path = "${cfg.stateDirectory}/local_credentials.yaml";
- server = {
- listen_uri = lib.mkDefault "127.0.0.1:8080";
- profiles_path = lib.mkDefault "${cfg.package}/share/crowdsec/config/profiles.yaml";
- console_path = lib.mkDefault "${cfg.package}/share/crowdsec/config/console.yaml";
-
- online_client = {
- # By default, we don't let crowdsec phone home, since
- # this is usually within NixOS users' concerns.
- sharing = lib.mkDefault false;
- credentials_path = cfg.centralApiCredentials;
- };
- };
- };
-
- # We enable prometheus by default, since cscli relies on it
- # for metrics
- prometheus = {
- enabled = lib.mkDefault true;
- level = lib.mkDefault "full";
- listen_addr = lib.mkDefault "127.0.0.1";
- listen_port = lib.mkDefault 6060;
- };
- };
- };
-
- systemd.packages = [ cfg.package ];
-
- environment = {
- systemPackages = [
- # To add completions; sadly need to hand-roll this since
- # neither `symlinkJoin` nor `buildEnv` have collision
- # handling.
- (pkgs.runCommandLocal "cscli" { } ''
- mkdir -p $out
- ln -s ${cscli}/bin $out/bin
- ln -s ${cfg.package}/share $out/share
- '')
- ];
-
- etc."crowdsec/config.yaml".source = settingsFormat.generate "crowdsec-settings.yaml" cfg.settings;
- };
-
- systemd = {
- tmpfiles.settings."10-crowdsec" = {
- "${cfg.stateDirectory}".d = {
- user = "crowdsec";
- group = "crowdsec";
- mode = "0700";
- };
-
- # This must be created for the setup service to work
- "${cfg.stateDirectory}/config".d = {
- user = "crowdsec";
- group = "crowdsec";
- mode = "0700";
- };
-
- "${cfg.stateDirectory}/config/parsers".d = lib.mkIf (cfg.parserWhitelist != [ ]) {
- user = "crowdsec";
- group = "crowdsec";
- mode = "0700";
- };
-
- "${cfg.stateDirectory}/config/parsers/s02-enrich".d = lib.mkIf (cfg.parserWhitelist != [ ]) {
- user = "crowdsec";
- group = "crowdsec";
- mode = "0700";
- };
-
- "${cfg.stateDirectory}/config/parsers/s02-enrich/nixos-whitelist.yaml" =
- lib.mkIf (cfg.parserWhitelist != [ ])
- {
- "L+".argument =
- (settingsFormat.generate "crowdsec-nixos-whitelist.yaml" {
- name = "nixos/parser-whitelist";
- description = "Parser whitelist generated by the crowdsec NixOS module";
- whitelist = {
- reason = "Filtered by NixOS whitelist";
- ip = lib.lists.filter (ip: !(lib.hasInfix "/" ip)) cfg.parserWhitelist;
- cidr = lib.lists.filter (ip: lib.hasInfix "/" ip) cfg.parserWhitelist;
- };
- }).outPath;
- };
- };
-
- services = {
- crowdsec-setup = {
- # TODO(tlater): Depend on tmpfiles path for
- # /var/lib/crowdsec/config
- description = "Crowdsec database and config preparation";
-
- script = ''
- if [ ! -e '${cfg.settings.config_paths.simulation_path}' ]; then
- cp '${cfg.package}/share/crowdsec/config/simulation.yaml' '${cfg.settings.config_paths.simulation_path}'
- fi
-
- if [ ! -e '${cfg.settings.api.client.credentials_path}' ]; then
- ${cfg.package}/bin/cscli machines add --auto --file '${cfg.settings.api.client.credentials_path}'
- fi
- '';
-
- serviceConfig = {
- User = "crowdsec";
- Group = "crowdsec";
- StateDirectory = "crowdsec";
-
- Type = "oneshot";
- RemainAfterExit = true;
- };
- };
-
- # Note that the service basics are already defined upstream
- crowdsec = {
- enable = true;
-
- after = [ "crowdsec-setup.service" ];
- bindsTo = [ "crowdsec-setup.service" ];
- wantedBy = [ "multi-user.target" ];
-
- serviceConfig = {
- User = "crowdsec";
- Group = "crowdsec";
- SupplementaryGroups = cfg.extraGroups;
-
- StateDirectory = "crowdsec";
- };
- };
- };
- };
-
- users = {
- users.crowdsec = {
- isSystemUser = true;
- home = cfg.stateDirectory;
- group = "crowdsec";
- };
- groups = {
- crowdsec = { };
- };
- };
- };
-}
diff --git a/modules/crowdsec/remediations/cs-firewall-bouncer.nix b/modules/crowdsec/remediations/cs-firewall-bouncer.nix
deleted file mode 100644
index bdc6da8..0000000
--- a/modules/crowdsec/remediations/cs-firewall-bouncer.nix
+++ /dev/null
@@ -1,87 +0,0 @@
-{
- flake-inputs,
- pkgs,
- lib,
- config,
- ...
-}:
-let
- inherit (flake-inputs.self.packages.${pkgs.stdenv.hostPlatform.system}) crowdsec-firewall-bouncer;
-
- crowdsecCfg = config.security.crowdsec;
- cfg = crowdsecCfg.remediationComponents.firewallBouncer;
- settingsFormat = pkgs.formats.yaml { };
-in
-{
- options.security.crowdsec.remediationComponents.firewallBouncer = {
- enable = lib.mkEnableOption "cs-firewall-bouncer";
-
- settings = lib.mkOption {
- inherit (settingsFormat) type;
- default = { };
-
- description = ''
- The bouncer configuration. Refer to
- for details
- on supported values.
- '';
- };
- };
-
- config = lib.mkIf cfg.enable {
- security.crowdsec.remediationComponents.firewallBouncer.settings = {
- mode = lib.mkDefault "${if config.networking.nftables.enable then "nftables" else "iptables"}";
- log_mode = "stdout";
- iptables_chains = [ "nixos-fw" ];
-
- # Don't let users easily override this; unfortunately we need to
- # set up this key through substitution at runtime.
- api_key = lib.mkForce "\${API_KEY}";
- api_url = lib.mkDefault "http://${crowdsecCfg.settings.api.server.listen_uri}";
- };
-
- systemd = {
- packages = [ crowdsec-firewall-bouncer ];
-
- services = {
- crowdsec-firewall-bouncer-setup = {
- description = "Crowdsec firewall bouncer config preparation";
- script = ''
- if [ ! -e '${crowdsecCfg.stateDirectory}/firewall_bouncer_credentials.yaml' ]; then
- ${crowdsecCfg.package}/bin/cscli -oraw bouncers add "cs-firewall-bouncer-$(${pkgs.coreutils}/bin/date +%s)" > \
- ${crowdsecCfg.stateDirectory}/firewall_bouncer_credentials.yaml
- fi
-
- # Stdout redirection is deliberately used to forcibly
- # overwrite the file if it exists
- API_KEY="$(<${crowdsecCfg.stateDirectory}/firewall_bouncer_credentials.yaml)" \
- ${lib.getExe pkgs.envsubst} \
- -i ${settingsFormat.generate "crowdsec-firewall-bouncer.yaml" cfg.settings} \
- > /var/lib/crowdsec/config/crowdsec-firewall-bouncer.yaml
- '';
-
- serviceConfig = {
- User = "crowdsec";
- Group = "crowdsec";
-
- Type = "oneshot";
- RemainAfterExit = true;
- };
- };
-
- crowdsec-firewall-bouncer = {
- enable = true;
-
- after = [ "crowdsec-firewall-bouncer-setup.service" ];
- bindsTo = [ "crowdsec-firewall-bouncer-setup.service" ];
- requiredBy = [ "crowdsec.service" ];
-
- path =
- lib.optionals (cfg.settings.mode == "ipset" || cfg.settings.mode == "iptables") [ pkgs.ipset ]
- ++ lib.optional (cfg.settings.mode == "iptables") pkgs.iptables
- ++ lib.optional (cfg.settings.mode == "nftables") pkgs.nftables;
- };
- };
- };
- };
-}
diff --git a/modules/crowdsec/remediations/default.nix b/modules/crowdsec/remediations/default.nix
deleted file mode 100644
index c3c0790..0000000
--- a/modules/crowdsec/remediations/default.nix
+++ /dev/null
@@ -1 +0,0 @@
-{ imports = [ ./cs-firewall-bouncer.nix ]; }
diff --git a/modules/default.nix b/modules/default.nix
index 1bf5314..c03a700 100644
--- a/modules/default.nix
+++ b/modules/default.nix
@@ -1,6 +1 @@
-{
- imports = [
- ./crowdsec
- ./serviceTests/stub.nix
- ];
-}
+{ imports = [ ./serviceTests/stub.nix ]; }
diff --git a/pkgs/packages/crowdsec-firewall-bouncer.nix b/pkgs/packages/crowdsec-firewall-bouncer.nix
deleted file mode 100644
index 41bba86..0000000
--- a/pkgs/packages/crowdsec-firewall-bouncer.nix
+++ /dev/null
@@ -1,51 +0,0 @@
-{
- lib,
- fetchFromGitHub,
- buildGoModule,
- envsubst,
- coreutils,
-
- writers,
- nix-update,
-}:
-let
- envsubstBin = lib.getExe envsubst;
-in
-buildGoModule (drv: {
- pname = "crowdsec-firewall-bouncer";
- version = drv.src.rev;
-
- src = fetchFromGitHub {
- owner = "crowdsecurity";
- repo = "cs-firewall-bouncer";
- rev = "0.0.34";
- sha256 = "sha256-lDO9pwPkbI+FDTdXBv03c0p8wbkRUiIDNl1ip3AZo2g=";
- };
-
- vendorHash = "sha256-SbpclloBgd9vffC0lBduGRqPOqmzQ0J91/KeDHCh0jo=";
-
- postInstall = ''
- mkdir -p $out/lib/systemd/system
-
- CFG=/var/lib/crowdsec/config BIN=$out/bin/cs-firewall-bouncer ${envsubstBin} \
- -i ./config/crowdsec-firewall-bouncer.service \
- -o $out/lib/systemd/system/crowdsec-firewall-bouncer.service
-
- substituteInPlace $out/lib/systemd/system/crowdsec-firewall-bouncer.service \
- --replace-fail /bin/sleep ${coreutils}/bin/sleep
- '';
-
- passthru.updateScript =
- writers.writeNuBin "update-crowdsec-firewall-bouncer"
- {
- makeWrapperArgs = [
- "--prefix"
- "PATH"
- ":"
- (lib.makeBinPath [ nix-update ])
- ];
- }
- ''
- nix-update --flake --format crowdsec-firewall-bouncer
- '';
-})
diff --git a/pkgs/packages/crowdsec-hub.nix b/pkgs/packages/crowdsec-hub.nix
deleted file mode 100644
index 2b193fd..0000000
--- a/pkgs/packages/crowdsec-hub.nix
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- lib,
- fetchFromGitHub,
- stdenvNoCC,
-
- writers,
- nix-update,
-}:
-# Using `mkDerivation` so nix-update can pick up the version
-stdenvNoCC.mkDerivation (drv: {
- pname = "crowdsec-hub";
- version = drv.src.rev;
-
- src = fetchFromGitHub {
- owner = "crowdsecurity";
- repo = "hub";
- rev = "7f724f92c79ce743ef9c7020cce228f98cca6afa";
- hash = "sha256-xWl3gmDicwjjrK3kto5tIJB/LLttaf+GYYgFqo8r9sw=";
- };
-
- installPhase = ''
- cp -r $src $out
- '';
-
- passthru.updateScript =
- writers.writeNuBin "update-crowdsec-hub"
- {
- makeWrapperArgs = [
- "--prefix"
- "PATH"
- ":"
- (lib.makeBinPath [ nix-update ])
- ];
- }
- ''
- nix-update --flake --format --version=branch crowdsec-hub
- '';
-})