feat: Add crowdsec module
This commit is contained in:
parent
09198a416c
commit
b90af26085
modules
237
modules/crowdsec.nix
Normal file
237
modules/crowdsec.nix
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
lib,
|
||||||
|
config,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
cfg = config.services.crowdsec;
|
||||||
|
settingsFormat = pkgs.formats.yaml { };
|
||||||
|
|
||||||
|
# TODO(tlater): Upstream properly installing the service file
|
||||||
|
crowdsec = pkgs.symlinkJoin {
|
||||||
|
name = "crowdsec-with-unit";
|
||||||
|
paths = [
|
||||||
|
pkgs.crowdsec
|
||||||
|
(pkgs.runCommandLocal "crowdsec.service" { } ''
|
||||||
|
mkdir -p $out/lib/systemd/system/
|
||||||
|
|
||||||
|
substitute ${pkgs.crowdsec}/share/crowdsec/config/crowdsec.service $out/lib/systemd/system/crowdsec.service \
|
||||||
|
--replace-fail /usr/local ${pkgs.crowdsec}
|
||||||
|
'')
|
||||||
|
];
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.crowdsec =
|
||||||
|
let
|
||||||
|
inherit (lib.types) nullOr package path;
|
||||||
|
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.
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
# clientCredentials = lib.mkOption {
|
||||||
|
# type = path;
|
||||||
|
|
||||||
|
# description = ''
|
||||||
|
# The API client credentials to configure; Required to access
|
||||||
|
# the service at all.
|
||||||
|
# '';
|
||||||
|
# };
|
||||||
|
|
||||||
|
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`.
|
||||||
|
services.crowdsec = {
|
||||||
|
stateDirectory = "/var/lib/crowdsec";
|
||||||
|
|
||||||
|
settings = {
|
||||||
|
common = {
|
||||||
|
# Default config daemonizes, but the service is set to
|
||||||
|
# `notify`; presumably the daemonization isn't really intended
|
||||||
|
daemonize = false;
|
||||||
|
# The default logs to files, which isn't the preferred way
|
||||||
|
# on NixOS
|
||||||
|
log_media = "stdout";
|
||||||
|
};
|
||||||
|
|
||||||
|
config_paths = {
|
||||||
|
config_dir = "/etc/crowdsec/";
|
||||||
|
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 = "${cfg.package}/share/crowdsec/config/patterns";
|
||||||
|
|
||||||
|
# We don't want to actually download anything; Any rules
|
||||||
|
# will be properly packaged.
|
||||||
|
hub_dir = lib.mkDefault "/var/empty/";
|
||||||
|
index_path = lib.mkDefault "/var/empty/.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";
|
||||||
|
};
|
||||||
|
|
||||||
|
api = {
|
||||||
|
cti = {
|
||||||
|
enabled = cfg.ctiApiKey != null;
|
||||||
|
key = cfg.ctiApiKey;
|
||||||
|
};
|
||||||
|
# client.credentials_path = cfg.clientCredentials;
|
||||||
|
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.etc."crowdsec/config.yaml".source =
|
||||||
|
settingsFormat.generate "crowdsec-settings.yaml" cfg.settings;
|
||||||
|
|
||||||
|
# Note that the service basics are already defined upstream
|
||||||
|
systemd.services.crowdsec.serviceConfig = {
|
||||||
|
|
||||||
|
# TODO: ExecStartPre to make `/var/lib/crowdsec/config`
|
||||||
|
|
||||||
|
User = "crowdsec";
|
||||||
|
Group = "crowdsec";
|
||||||
|
SupplementaryGroups = [ "systemd-journal" ];
|
||||||
|
|
||||||
|
StateDirectory = "crowdsec";
|
||||||
|
|
||||||
|
PrivateTmp = true;
|
||||||
|
PrivateUsers = true;
|
||||||
|
ProtectHome = true;
|
||||||
|
CapabilityBoundingSet = [ ];
|
||||||
|
LockPersonality = true;
|
||||||
|
PrivateDevices = true;
|
||||||
|
ProtectHostname = true;
|
||||||
|
ProtectKernelTunables = true;
|
||||||
|
ProtectKernelModules = true;
|
||||||
|
ProtectControlGroups = true;
|
||||||
|
|
||||||
|
NoNewPrivileges = true;
|
||||||
|
RestrictSUIDSGID = true;
|
||||||
|
|
||||||
|
ProtectProc = "invisible";
|
||||||
|
ProcSubset = "pid"; # Needed for journal access
|
||||||
|
|
||||||
|
RestrictNamespaces = true;
|
||||||
|
RestrictRealtime = true;
|
||||||
|
|
||||||
|
SystemCallFilter = [
|
||||||
|
"@system-service"
|
||||||
|
"@network-io"
|
||||||
|
];
|
||||||
|
SystemCallArchitectures = [ "native" ];
|
||||||
|
SystemCallErrorNumber = "EPERM";
|
||||||
|
|
||||||
|
ExecPaths = [ "/nix/store" ];
|
||||||
|
NoExecPaths = [ "/" ];
|
||||||
|
};
|
||||||
|
|
||||||
|
users = {
|
||||||
|
users.crowdsec = {
|
||||||
|
isSystemUser = true;
|
||||||
|
home = cfg.stateDirectory;
|
||||||
|
group = "crowdsec";
|
||||||
|
};
|
||||||
|
groups = {
|
||||||
|
crowdsec = { };
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
|
@ -1 +1,6 @@
|
||||||
{ imports = [ ./nginxExtensions.nix ]; }
|
{
|
||||||
|
imports = [
|
||||||
|
./crowdsec.nix
|
||||||
|
./nginxExtensions.nix
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue