{ roles.default.perInstance = { settings, ... }: { nixosModule = { config, ... }: let dir = config.clan.core.settings.directory; instance = "zerotier"; networkId = builtins.readFile "${dir}/vars/shared/zerotier-network-${instance}/network-id/value"; full = "fd" + networkId + "9993"; hextet = i: builtins.substring (i * 4) 4 full; subnetZtier = "${hextet 0}:${hextet 1}:${hextet 2}:${hextet 3}:${hextet 4}:${builtins.substring 20 2 full}00::/88"; 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 = [ subnetZtier ]; }; } ]; }; }; services.crowdsec-firewall-bouncer = { enable = true; registerBouncer.enable = true; settings.mode = "nftables"; }; }; }; }