# CrowdSec Module # Provides: Collaborative intrusion detection and prevention # # Usage: # myModules.crowdsec = { # enable = true; # enableNginxBouncer = true; # Block attackers at nginx level # }; { config, lib, ... }: let cfg = config.myModules.crowdsec; in { options.myModules.crowdsec = { enable = lib.mkEnableOption "CrowdSec security engine"; enableNginxBouncer = lib.mkOption { type = lib.types.bool; default = true; description = "Enable nginx bouncer to block malicious IPs at nginx level"; }; whitelistIPs = lib.mkOption { type = lib.types.listOf lib.types.str; default = [ ]; example = [ "1.2.3.4" "10.0.0.0/8" ]; description = "IP addresses or CIDR ranges to whitelist"; }; banDuration = lib.mkOption { type = lib.types.str; default = "4h"; description = "Default ban duration for malicious IPs"; }; }; config = lib.mkIf cfg.enable { services.crowdsec = { enable = true; autoUpdateService = true; # Enable Local API for bouncers settings.general.api.server.enable = true; # Log acquisitions localConfig.acquisitions = [ # SSH logs { source = "journalctl"; journalctl_filter = [ "_SYSTEMD_UNIT=sshd.service" ]; labels = { type = "syslog"; }; } # Nginx access logs { source = "journalctl"; journalctl_filter = [ "_SYSTEMD_UNIT=nginx.service" ]; labels = { type = "nginx"; }; } ]; # Whitelist parser for trusted IPs localConfig.parsers.s02Enrich = lib.mkIf (cfg.whitelistIPs != [ ]) [ { name = "nixos/whitelist"; description = "Whitelist trusted IPs"; whitelist = { reason = "Trusted IPs"; ip = lib.filter (ip: !(lib.hasInfix "/" ip)) cfg.whitelistIPs; cidr = lib.filter (lib.hasInfix "/") cfg.whitelistIPs; }; } ]; # Remediation profiles localConfig.profiles = [ { name = "default_ip_remediation"; filters = [ "Alert.Remediation == true && Alert.GetScope() == 'Ip'" ]; decisions = [ { type = "ban"; duration = cfg.banDuration; } ]; on_success = "break"; } ]; # Hub collections for common attack patterns hub = { collections = [ "crowdsecurity/linux" "crowdsecurity/nginx" "crowdsecurity/sshd" ]; }; }; # Nginx bouncer integration # Note: This requires the crowdsec-nginx-bouncer package # which may need to be installed separately services.nginx = lib.mkIf cfg.enableNginxBouncer { # Add crowdsec bouncer configuration # The bouncer checks with CrowdSec LAPI before allowing requests upstreams.crowdsec-squid = { servers = { "127.0.0.1:8081" = { }; }; }; # Include bouncer in all virtual hosts appendHttpConfig = '' # CrowdSec bouncer will be configured via environment # cscli bouncers add nginx-bouncer --key ''; }; # Instructions for manual setup (bouncer requires API key) system.activationScripts.crowdsec-nginx-info = lib.mkIf cfg.enableNginxBouncer '' echo "" echo "=== CrowdSec Setup ===" echo "To enable nginx bouncer, run:" echo " sudo cscli bouncers add nginx-bouncer --key \$(openssl rand -hex 32)" echo "Then configure /etc/crowdsec/bouncers/crowdsec-nginx-bouncer.conf" echo "" ''; }; }