diff --git a/flake.lock b/flake.lock
index d761f4f..d86b361 100644
--- a/flake.lock
+++ b/flake.lock
@@ -190,6 +190,22 @@
         "type": "github"
       }
     },
+    "nixpkgs-crowdsec": {
+      "locked": {
+        "lastModified": 1738085579,
+        "narHash": "sha256-7mLjMrOiiIi0vI7BJwbEipYQzwA7JF/NWHP+LM4q5S8=",
+        "owner": "tlater",
+        "repo": "nixpkgs",
+        "rev": "426a7afc9a6ecfdac544bda4022acef31e36df34",
+        "type": "github"
+      },
+      "original": {
+        "owner": "tlater",
+        "ref": "tlater/fix-crowdsec",
+        "repo": "nixpkgs",
+        "type": "github"
+      }
+    },
     "nixpkgs-unstable": {
       "locked": {
         "lastModified": 1737192615,
@@ -310,6 +326,7 @@
         "disko": "disko",
         "foundryvtt": "foundryvtt",
         "nixpkgs": "nixpkgs_2",
+        "nixpkgs-crowdsec": "nixpkgs-crowdsec",
         "nixpkgs-unstable": "nixpkgs-unstable",
         "sonnenshift": "sonnenshift",
         "sops-nix": "sops-nix",
diff --git a/flake.nix b/flake.nix
index 2253566..3d04d7c 100644
--- a/flake.nix
+++ b/flake.nix
@@ -26,6 +26,8 @@
       url = "git+ssh://git@github.com/sonnenshift/battery-manager";
       inputs.nixpkgs.follows = "nixpkgs";
     };
+
+    nixpkgs-crowdsec.url = "github:tlater/nixpkgs/tlater/fix-crowdsec";
   };
 
   outputs =
@@ -98,7 +100,16 @@
       # Garbage collection root #
       ###########################
 
-      packages.${system}.default = vm.config.system.build.vm;
+      packages.${system} =
+        let
+          localPkgs = import ./pkgs { inherit pkgs; };
+        in
+        {
+          default = vm.config.system.build.vm;
+          crowdsec = pkgs.callPackage "${inputs.nixpkgs-crowdsec}/pkgs/by-name/cr/crowdsec/package.nix" { };
+          crowdsec-hub = localPkgs.crowdsec.hub;
+          crowdsec-firewall-bouncer = localPkgs.crowdsec.firewall-bouncer;
+        };
 
       ###################
       # Utility scripts #
@@ -115,6 +126,22 @@
               ${vm.config.system.build.vm.outPath}/bin/run-testvm-vm
             '').outPath;
         };
+
+        update-crowdsec-packages =
+          let
+            git = pkgs.lib.getExe pkgs.git;
+            nvfetcher = pkgs.lib.getExe pkgs.nvfetcher;
+          in
+          {
+            type = "app";
+            program =
+              (pkgs.writeShellScript "update-crowdsec-packages" ''
+                cd "$(${git} rev-parse --show-toplevel)"
+                cd ./pkgs/crowdsec
+                ${nvfetcher}
+                echo 'Remember to update the vendorHash of any go packages!'
+              '').outPath;
+          };
       };
 
       ###########################
diff --git a/modules/crowdsec/default.nix b/modules/crowdsec/default.nix
new file mode 100644
index 0000000..915ca0b
--- /dev/null
+++ b/modules/crowdsec/default.nix
@@ -0,0 +1,361 @@
+{
+  flake-inputs,
+  pkgs,
+  lib,
+  config,
+  ...
+}:
+let
+  cfg = config.security.crowdsec;
+  settingsFormat = pkgs.formats.yaml { };
+
+  crowdsec = flake-inputs.self.packages.${pkgs.system}.crowdsec;
+
+  hub = pkgs.fetchFromGitHub {
+    owner = "crowdsecurity";
+    repo = "hub";
+    rev = "7a3b4753f4577257c0cbeb8f8f90c7f17d2ae008";
+    hash = "sha256-HB4jHyhiO8gjBkLmpo6bDbwhfm5m5nAtNlKhDkZjt2I=";
+  };
+
+  cscli = pkgs.writeShellScriptBin "cscli" ''
+    export PATH="$PATH:${crowdsec}/bin/"
+
+    sudo=exec
+    if [ "$USER" != "crowdsec" ]; then
+        sudo='exec /run/wrappers/bin/sudo -u crowdsec'
+    fi
+
+    $sudo ${crowdsec}/bin/cscli "$@"
+  '';
+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 = 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
+          <https://docs.crowdsec.net/docs/next/configuration/crowdsec_configuration/>
+          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.
+        '';
+      };
+
+      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 = lib.mkDefault "${cfg.package}/share/crowdsec/config/acquis.yaml";
+
+        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.
+              #
+              # TODO: Enable when this option becomes available
+              # (1.6.4, current nixpkgs-unstable)
+              # 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.runCommandNoCCLocal "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 = [ "systemd-journal" ];
+
+            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
new file mode 100644
index 0000000..aa70552
--- /dev/null
+++ b/modules/crowdsec/remediations/cs-firewall-bouncer.nix
@@ -0,0 +1,90 @@
+{
+  flake-inputs,
+  pkgs,
+  lib,
+  config,
+  ...
+}:
+let
+  crowdsecCfg = config.security.crowdsec;
+  cfg = crowdsecCfg.remediationComponents.firewallBouncer;
+  settingsFormat = pkgs.formats.yaml { };
+  crowdsec-firewall-bouncer = flake-inputs.self.packages.${pkgs.system}.crowdsec-firewall-bouncer;
+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
+        <https://docs.crowdsec.net/u/bouncers/firewall/> 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
new file mode 100644
index 0000000..7df6ade
--- /dev/null
+++ b/modules/crowdsec/remediations/default.nix
@@ -0,0 +1,5 @@
+{
+  imports = [
+    ./cs-firewall-bouncer.nix
+  ];
+}
diff --git a/modules/default.nix b/modules/default.nix
index e1db4cc..89f1752 100644
--- a/modules/default.nix
+++ b/modules/default.nix
@@ -1 +1,6 @@
-{ imports = [ ./nginxExtensions.nix ]; }
+{
+  imports = [
+    ./crowdsec
+    ./nginxExtensions.nix
+  ];
+}
diff --git a/pkgs/crowdsec/_sources/generated.json b/pkgs/crowdsec/_sources/generated.json
new file mode 100644
index 0000000..8485779
--- /dev/null
+++ b/pkgs/crowdsec/_sources/generated.json
@@ -0,0 +1,42 @@
+{
+    "crowdsec-firewall-bouncer": {
+        "cargoLocks": null,
+        "date": null,
+        "extract": null,
+        "name": "crowdsec-firewall-bouncer",
+        "passthru": null,
+        "pinned": false,
+        "src": {
+            "deepClone": false,
+            "fetchSubmodules": false,
+            "leaveDotGit": false,
+            "name": null,
+            "owner": "crowdsecurity",
+            "repo": "cs-firewall-bouncer",
+            "rev": "v0.0.31",
+            "sha256": "sha256-59MWll8v00CF4WA53gjHZSTFc8hpYaHENg9O7LgTCrA=",
+            "type": "github"
+        },
+        "version": "v0.0.31"
+    },
+    "crowdsec-hub": {
+        "cargoLocks": null,
+        "date": "2025-01-30",
+        "extract": null,
+        "name": "crowdsec-hub",
+        "passthru": null,
+        "pinned": false,
+        "src": {
+            "deepClone": false,
+            "fetchSubmodules": false,
+            "leaveDotGit": false,
+            "name": null,
+            "owner": "crowdsecurity",
+            "repo": "hub",
+            "rev": "8f102f5ac79af59d3024ca2771b65ec87411ac02",
+            "sha256": "sha256-8K1HkBg0++Au1dr2KMrl9b2ruqXdo+vqWngOCwL11Mo=",
+            "type": "github"
+        },
+        "version": "8f102f5ac79af59d3024ca2771b65ec87411ac02"
+    }
+}
\ No newline at end of file
diff --git a/pkgs/crowdsec/_sources/generated.nix b/pkgs/crowdsec/_sources/generated.nix
new file mode 100644
index 0000000..6f845ec
--- /dev/null
+++ b/pkgs/crowdsec/_sources/generated.nix
@@ -0,0 +1,27 @@
+# This file was generated by nvfetcher, please do not modify it manually.
+{ fetchgit, fetchurl, fetchFromGitHub, dockerTools }:
+{
+  crowdsec-firewall-bouncer = {
+    pname = "crowdsec-firewall-bouncer";
+    version = "v0.0.31";
+    src = fetchFromGitHub {
+      owner = "crowdsecurity";
+      repo = "cs-firewall-bouncer";
+      rev = "v0.0.31";
+      fetchSubmodules = false;
+      sha256 = "sha256-59MWll8v00CF4WA53gjHZSTFc8hpYaHENg9O7LgTCrA=";
+    };
+  };
+  crowdsec-hub = {
+    pname = "crowdsec-hub";
+    version = "8f102f5ac79af59d3024ca2771b65ec87411ac02";
+    src = fetchFromGitHub {
+      owner = "crowdsecurity";
+      repo = "hub";
+      rev = "8f102f5ac79af59d3024ca2771b65ec87411ac02";
+      fetchSubmodules = false;
+      sha256 = "sha256-8K1HkBg0++Au1dr2KMrl9b2ruqXdo+vqWngOCwL11Mo=";
+    };
+    date = "2025-01-30";
+  };
+}
diff --git a/pkgs/crowdsec/default.nix b/pkgs/crowdsec/default.nix
new file mode 100644
index 0000000..66faac3
--- /dev/null
+++ b/pkgs/crowdsec/default.nix
@@ -0,0 +1,9 @@
+{ pkgs }:
+let
+  sources = pkgs.callPackage ./_sources/generated.nix { };
+  callPackage = pkgs.lib.callPackageWith (pkgs // { inherit sources; });
+in
+{
+  hub = callPackage ./hub.nix { };
+  firewall-bouncer = callPackage ./firewall-bouncer.nix { };
+}
diff --git a/pkgs/crowdsec/firewall-bouncer.nix b/pkgs/crowdsec/firewall-bouncer.nix
new file mode 100644
index 0000000..86370c4
--- /dev/null
+++ b/pkgs/crowdsec/firewall-bouncer.nix
@@ -0,0 +1,26 @@
+{
+  lib,
+  sources,
+  buildGoModule,
+  envsubst,
+  coreutils,
+}:
+let
+  envsubstBin = lib.getExe envsubst;
+in
+buildGoModule {
+  inherit (sources.crowdsec-firewall-bouncer) pname version src;
+
+  vendorHash = "sha256-7Jxvg8UEjUxnIz1llvXyI2AefJ31OVdNzhWD/C8wU/Y=";
+
+  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
+  '';
+}
diff --git a/pkgs/crowdsec/hub.nix b/pkgs/crowdsec/hub.nix
new file mode 100644
index 0000000..d057ca8
--- /dev/null
+++ b/pkgs/crowdsec/hub.nix
@@ -0,0 +1,4 @@
+{
+  sources,
+}:
+sources.crowdsec-hub.src
diff --git a/pkgs/crowdsec/nvfetcher.toml b/pkgs/crowdsec/nvfetcher.toml
new file mode 100644
index 0000000..2287dba
--- /dev/null
+++ b/pkgs/crowdsec/nvfetcher.toml
@@ -0,0 +1,7 @@
+[crowdsec-hub]
+src.git = "https://github.com/crowdsecurity/hub.git"
+fetch.github = "crowdsecurity/hub"
+
+[crowdsec-firewall-bouncer]
+src.github = "crowdsecurity/cs-firewall-bouncer"
+fetch.github = "crowdsecurity/cs-firewall-bouncer"
diff --git a/pkgs/default.nix b/pkgs/default.nix
index 036afd4..0e5de7a 100644
--- a/pkgs/default.nix
+++ b/pkgs/default.nix
@@ -1,7 +1,5 @@
 { pkgs }:
-let
-  inherit (pkgs) callPackage;
-in
 {
-  starbound = callPackage ./starbound { };
+  crowdsec = import ./crowdsec { inherit pkgs; };
+  starbound = pkgs.callPackage ./starbound { };
 }