crowdsec: inject ntfy url at runtime, drop obsolete hub prune

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
rope 2026-06-11 10:00:02 +01:00
parent 1145f1ca5a
commit 93e79509c4

View file

@ -11,14 +11,34 @@
#
# Before first deploy, create /var/secrets/ntfy-url with your topic URL:
# echo 'https://ntfy.sh/nordhammer-<random>' | sudo tee /var/secrets/ntfy-url
# sudo chmod 640 /var/secrets/ntfy-url
# sudo chmod 600 /var/secrets/ntfy-url
{ config, lib, pkgs, ... }:
let
ntfyUrlFile = "/var/secrets/ntfy-url";
ntfyUrl =
if builtins.pathExists ntfyUrlFile
then lib.removeSuffix "\n" (builtins.readFile ntfyUrlFile)
else "https://ntfy.sh/CHANGE-ME-CREATE-VAR-SECRETS-NTFY-URL";
# The real URL is injected at service start (see ExecStartPre below) —
# eval-time builtins.readFile can't see /var/secrets under pure flake
# evaluation, which is how the `update` alias builds.
ntfyUrlPlaceholder = "@NTFY_URL@";
# The module renders settings.notifications into /etc/crowdsec/notifications/
# as a symlink into /etc/static (the store). Re-render it from the static
# source with the secret substituted on every service start; nixos-rebuild
# restores the symlink on activation, so this never goes stale.
injectNtfyUrl = pkgs.writeShellScript "crowdsec-inject-ntfy-url" ''
set -euo pipefail
src=/etc/static/crowdsec/notifications/0-nixos-generated.yaml
dst=/etc/crowdsec/notifications/0-nixos-generated.yaml
secret=/var/secrets/ntfy-url
if [ ! -f "$secret" ]; then
echo "WARNING: $secret not found; ntfy notifications will not work" >&2
exit 0
fi
url=$(${pkgs.coreutils}/bin/tr -d '\n' < "$secret")
tmp=$(${pkgs.coreutils}/bin/mktemp "$dst.XXXXXX")
${pkgs.gnused}/bin/sed "s|${ntfyUrlPlaceholder}|$url|g" "$src" > "$tmp"
${pkgs.coreutils}/bin/chmod 600 "$tmp"
${pkgs.coreutils}/bin/chown crowdsec:crowdsec "$tmp"
${pkgs.coreutils}/bin/mv "$tmp" "$dst"
'';
# nixpkgs only builds the agent + cscli; the new module also expects
# notification plugins at $out/libexec/crowdsec/plugins/. Compile them
@ -128,7 +148,7 @@ in
name = "ntfy_http";
type = "http";
log_level = "info";
url = ntfyUrl;
url = ntfyUrlPlaceholder;
method = "POST";
headers = {
Title = "CrowdSec alert";
@ -163,28 +183,15 @@ in
};
};
# Inject the ntfy topic URL into the rendered notification config before
# every start. "+" runs the script with full privileges (it reads the
# root-owned secret and replaces a root-owned /etc symlink).
systemd.services.crowdsec.serviceConfig.ExecStartPre = [ "+${injectNtfyUrl}" ];
# Firewall bouncer enforces decisions via nftables; auto-registers with LAPI
services.crowdsec-firewall-bouncer = {
enable = true;
registerBouncer.enable = true;
};
# The hub keeps tracking upstream master, but nixpkgs stable's crowdsec
# binary is a few versions behind and doesn't know newer expr functions
# (e.g. LookupFile, used by crowdsecurity/http-technology-probing). The
# agent then refuses to load the entire bucket and crashes on startup.
# Strip incompatible scenarios after crowdsec-setup repopulates the hub
# but before crowdsec.service tries to load them.
systemd.services.crowdsec-prune-incompatible-hub-items = {
description = "Remove hub scenarios incompatible with the bundled crowdsec";
after = [ "crowdsec-setup.service" ];
before = [ "crowdsec.service" ];
requiredBy = [ "crowdsec.service" ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
ExecStart = "${pkgs.coreutils}/bin/rm -f /etc/crowdsec/scenarios/http-technology-probing.yaml";
};
};
};
}