crowdsec: inject ntfy url at runtime, drop obsolete hub prune
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
1145f1ca5a
commit
93e79509c4
1 changed files with 32 additions and 25 deletions
|
|
@ -11,14 +11,34 @@
|
||||||
#
|
#
|
||||||
# Before first deploy, create /var/secrets/ntfy-url with your topic URL:
|
# Before first deploy, create /var/secrets/ntfy-url with your topic URL:
|
||||||
# echo 'https://ntfy.sh/nordhammer-<random>' | sudo tee /var/secrets/ntfy-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, ... }:
|
{ config, lib, pkgs, ... }:
|
||||||
let
|
let
|
||||||
ntfyUrlFile = "/var/secrets/ntfy-url";
|
# The real URL is injected at service start (see ExecStartPre below) —
|
||||||
ntfyUrl =
|
# eval-time builtins.readFile can't see /var/secrets under pure flake
|
||||||
if builtins.pathExists ntfyUrlFile
|
# evaluation, which is how the `update` alias builds.
|
||||||
then lib.removeSuffix "\n" (builtins.readFile ntfyUrlFile)
|
ntfyUrlPlaceholder = "@NTFY_URL@";
|
||||||
else "https://ntfy.sh/CHANGE-ME-CREATE-VAR-SECRETS-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
|
# nixpkgs only builds the agent + cscli; the new module also expects
|
||||||
# notification plugins at $out/libexec/crowdsec/plugins/. Compile them
|
# notification plugins at $out/libexec/crowdsec/plugins/. Compile them
|
||||||
|
|
@ -128,7 +148,7 @@ in
|
||||||
name = "ntfy_http";
|
name = "ntfy_http";
|
||||||
type = "http";
|
type = "http";
|
||||||
log_level = "info";
|
log_level = "info";
|
||||||
url = ntfyUrl;
|
url = ntfyUrlPlaceholder;
|
||||||
method = "POST";
|
method = "POST";
|
||||||
headers = {
|
headers = {
|
||||||
Title = "CrowdSec alert";
|
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
|
# Firewall bouncer enforces decisions via nftables; auto-registers with LAPI
|
||||||
services.crowdsec-firewall-bouncer = {
|
services.crowdsec-firewall-bouncer = {
|
||||||
enable = true;
|
enable = true;
|
||||||
registerBouncer.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";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue