# CrowdSec security engine + nftables bouncer: parses sshd auth attempts from # the journal and bans offending source IPs at the firewall. Log-based (no # inline DPI) so it costs the N300 next to nothing. { settings }: { ... }: let cfg = settings; in { services.crowdsec = { enable = true; autoUpdateService = true; hub.collections = [ "crowdsecurity/linux" "crowdsecurity/sshd" ]; localConfig = { acquisitions = [ { source = "journalctl"; journalctl_filter = [ "_SYSTEMD_UNIT=sshd.service" ]; labels.type = "syslog"; } ]; # Never ban the ZeroTier mesh — it is the only admin path to these # boxes (no public SSH), so a false positive would lock us out. # Parser-stage whitelist: mesh events are dropped before any scenario. parsers.s02Enrich = [ { name = "cnx/mesh-whitelist"; description = "Whitelist the ZeroTier management mesh"; whitelist = { reason = "ZeroTier mesh is the admin path"; cidr = [ cfg.mesh.subnet ]; }; } ]; }; }; services.crowdsec-firewall-bouncer = { enable = true; registerBouncer.enable = true; settings.mode = "nftables"; }; }