Compare commits
2 commits
ff83fb3b9e
...
40f6318455
Author | SHA1 | Date | |
---|---|---|---|
40f6318455 | |||
d8337a79bc |
13 changed files with 293 additions and 14 deletions
|
@ -1,7 +1,8 @@
|
||||||
{ pkgs, ... }:
|
{ pkgs, ... }:
|
||||||
{
|
{
|
||||||
services.crowdsec = {
|
security.crowdsec = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
remediationComponents.firewallBouncer.enable = true;
|
||||||
|
|
||||||
parserWhitelist = [
|
parserWhitelist = [
|
||||||
"1.64.239.213"
|
"1.64.239.213"
|
||||||
|
@ -17,7 +18,7 @@
|
||||||
---
|
---
|
||||||
source: journalctl
|
source: journalctl
|
||||||
journalctl_filter:
|
journalctl_filter:
|
||||||
- "SYSLOG_IDENTIFIER=sshd-service"
|
- "SYSLOG_IDENTIFIER=sshd-session"
|
||||||
labels:
|
labels:
|
||||||
type: syslog
|
type: syslog
|
||||||
---
|
---
|
||||||
|
|
30
flake.nix
30
flake.nix
|
@ -100,10 +100,16 @@
|
||||||
# Garbage collection root #
|
# Garbage collection root #
|
||||||
###########################
|
###########################
|
||||||
|
|
||||||
packages.${system} = {
|
packages.${system} =
|
||||||
default = vm.config.system.build.vm;
|
let
|
||||||
crowdsec = pkgs.callPackage "${inputs.nixpkgs-crowdsec}/pkgs/by-name/cr/crowdsec/package.nix" { };
|
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 #
|
# Utility scripts #
|
||||||
|
@ -120,6 +126,22 @@
|
||||||
${vm.config.system.build.vm.outPath}/bin/run-testvm-vm
|
${vm.config.system.build.vm.outPath}/bin/run-testvm-vm
|
||||||
'').outPath;
|
'').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;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
###########################
|
###########################
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
let
|
let
|
||||||
cfg = config.services.crowdsec;
|
cfg = config.security.crowdsec;
|
||||||
settingsFormat = pkgs.formats.yaml { };
|
settingsFormat = pkgs.formats.yaml { };
|
||||||
|
|
||||||
crowdsec = flake-inputs.self.packages.${pkgs.system}.crowdsec;
|
crowdsec = flake-inputs.self.packages.${pkgs.system}.crowdsec;
|
||||||
|
@ -31,7 +31,9 @@ let
|
||||||
'';
|
'';
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
options.services.crowdsec =
|
imports = [ ./remediations ];
|
||||||
|
|
||||||
|
options.security.crowdsec =
|
||||||
let
|
let
|
||||||
inherit (lib.types)
|
inherit (lib.types)
|
||||||
nullOr
|
nullOr
|
||||||
|
@ -81,6 +83,50 @@ in
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
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 {
|
centralApiCredentials = lib.mkOption {
|
||||||
type = nullOr path;
|
type = nullOr path;
|
||||||
default = null;
|
default = null;
|
||||||
|
@ -115,7 +161,7 @@ in
|
||||||
# Set up default settings; anything that *shouldn't* be changed is
|
# Set up default settings; anything that *shouldn't* be changed is
|
||||||
# set to the default priority so that users need to use
|
# set to the default priority so that users need to use
|
||||||
# `lib.mkForce`.
|
# `lib.mkForce`.
|
||||||
services.crowdsec = {
|
security.crowdsec = {
|
||||||
stateDirectory = "/var/lib/crowdsec";
|
stateDirectory = "/var/lib/crowdsec";
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
|
@ -278,6 +324,8 @@ in
|
||||||
|
|
||||||
# Note that the service basics are already defined upstream
|
# Note that the service basics are already defined upstream
|
||||||
crowdsec = {
|
crowdsec = {
|
||||||
|
enable = true;
|
||||||
|
|
||||||
after = [ "crowdsec-setup.service" ];
|
after = [ "crowdsec-setup.service" ];
|
||||||
bindsTo = [ "crowdsec-setup.service" ];
|
bindsTo = [ "crowdsec-setup.service" ];
|
||||||
|
|
90
modules/crowdsec/remediations/cs-firewall-bouncer.nix
Normal file
90
modules/crowdsec/remediations/cs-firewall-bouncer.nix
Normal file
|
@ -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" ];
|
||||||
|
partOf = [ "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;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
5
modules/crowdsec/remediations/default.nix
Normal file
5
modules/crowdsec/remediations/default.nix
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
imports = [
|
||||||
|
./cs-firewall-bouncer.nix
|
||||||
|
];
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./crowdsec.nix
|
./crowdsec
|
||||||
./nginxExtensions.nix
|
./nginxExtensions.nix
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
42
pkgs/crowdsec/_sources/generated.json
Normal file
42
pkgs/crowdsec/_sources/generated.json
Normal file
|
@ -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"
|
||||||
|
}
|
||||||
|
}
|
27
pkgs/crowdsec/_sources/generated.nix
Normal file
27
pkgs/crowdsec/_sources/generated.nix
Normal file
|
@ -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";
|
||||||
|
};
|
||||||
|
}
|
9
pkgs/crowdsec/default.nix
Normal file
9
pkgs/crowdsec/default.nix
Normal file
|
@ -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 { };
|
||||||
|
}
|
26
pkgs/crowdsec/firewall-bouncer.nix
Normal file
26
pkgs/crowdsec/firewall-bouncer.nix
Normal file
|
@ -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
|
||||||
|
'';
|
||||||
|
}
|
4
pkgs/crowdsec/hub.nix
Normal file
4
pkgs/crowdsec/hub.nix
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
sources,
|
||||||
|
}:
|
||||||
|
sources.crowdsec-hub.src
|
7
pkgs/crowdsec/nvfetcher.toml
Normal file
7
pkgs/crowdsec/nvfetcher.toml
Normal file
|
@ -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"
|
|
@ -1,7 +1,5 @@
|
||||||
{ pkgs }:
|
{ pkgs }:
|
||||||
let
|
|
||||||
inherit (pkgs) callPackage;
|
|
||||||
in
|
|
||||||
{
|
{
|
||||||
starbound = callPackage ./starbound { };
|
crowdsec = import ./crowdsec { inherit pkgs; };
|
||||||
|
starbound = pkgs.callPackage ./starbound { };
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue