ntfy
This commit is contained in:
@@ -6,15 +6,51 @@
|
||||
...
|
||||
}:
|
||||
let
|
||||
inherit (lib.${namespace}) mkOpt;
|
||||
inherit (lib.${namespace}) mkOpt mkBoolOpt;
|
||||
name = "crowdsec";
|
||||
cfg = config.${namespace}.services.${name};
|
||||
|
||||
ntfyServer = "https://ntfy.mjallen.dev";
|
||||
ntfyTopic = "crowdsec";
|
||||
|
||||
# CrowdSec HTTP notification plugin config — written to
|
||||
# /etc/crowdsec/notifications/ntfy.yaml at runtime. Credentials are
|
||||
# injected via EnvironmentFile so the plugin can reference them with
|
||||
# {{env "NTFY_USER"}} / {{env "NTFY_PASSWORD"}} in the URL.
|
||||
ntfyPluginConfig = pkgs.writeText "crowdsec-ntfy.yaml" ''
|
||||
type: http
|
||||
name: ntfy_plugin
|
||||
log_level: info
|
||||
format: |
|
||||
{{range . -}}
|
||||
CrowdSec blocked: {{.Scenario}}
|
||||
Source IP: {{.Source.Value}}
|
||||
Country: {{.Source.Cn}}
|
||||
Decisions: {{.Decisions | len}}
|
||||
{{range .Decisions -}}
|
||||
Action: {{.Type}} for {{.Duration}}
|
||||
{{end}}
|
||||
{{- end}}
|
||||
url: ${ntfyServer}/${ntfyTopic}
|
||||
method: POST
|
||||
headers:
|
||||
Title: "CrowdSec: {{(index . 0).Scenario}}"
|
||||
Priority: "high"
|
||||
Tags: "rotating_light,shield"
|
||||
Authorization: "Basic {{b64enc (print (env "NTFY_USER") ":" (env "NTFY_PASSWORD"))}}"
|
||||
skip_tls_verify: false
|
||||
timeout: 10s
|
||||
'';
|
||||
|
||||
crowdsecConfig = lib.${namespace}.mkModule {
|
||||
inherit config name;
|
||||
description = "crowdsec";
|
||||
options = with lib; {
|
||||
apiKey = mkOpt types.str "" "API key for crowdsec bouncer";
|
||||
ntfy = {
|
||||
enable = mkBoolOpt false "Send ntfy notifications on new CrowdSec alerts";
|
||||
envFile = mkOpt types.str "" "Path to env file containing NTFY_USER and NTFY_PASSWORD";
|
||||
};
|
||||
};
|
||||
moduleConfig = {
|
||||
services = {
|
||||
@@ -199,6 +235,57 @@ let
|
||||
user = "crowdsec";
|
||||
group = "crowdsec";
|
||||
};
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# ntfy notifications via the CrowdSec HTTP notification plugin
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Drop the plugin config YAML into /etc/crowdsec/notifications/.
|
||||
# CrowdSec scans this directory on startup and registers any plugin
|
||||
# config files it finds.
|
||||
environment.etc."crowdsec/notifications/ntfy.yaml" = lib.mkIf cfg.ntfy.enable {
|
||||
source = ntfyPluginConfig;
|
||||
mode = "0440";
|
||||
user = "crowdsec";
|
||||
group = "crowdsec";
|
||||
};
|
||||
|
||||
# CrowdSec profiles.yaml: route every alert to the ntfy plugin.
|
||||
# This replaces the default "do nothing" profile.
|
||||
environment.etc."crowdsec/profiles.yaml" = lib.mkIf cfg.ntfy.enable {
|
||||
text = ''
|
||||
name: default_ip_remediation
|
||||
filters:
|
||||
- Alert.Remediation == true && Alert.GetScope() == "Ip"
|
||||
decisions:
|
||||
- type: ban
|
||||
duration: 4h
|
||||
notifications:
|
||||
- ntfy_plugin
|
||||
on_success: break
|
||||
---
|
||||
name: default_range_remediation
|
||||
filters:
|
||||
- Alert.Remediation == true && Alert.GetScope() == "Range"
|
||||
decisions:
|
||||
- type: ban
|
||||
duration: 4h
|
||||
notifications:
|
||||
- ntfy_plugin
|
||||
on_success: break
|
||||
'';
|
||||
mode = "0440";
|
||||
user = "crowdsec";
|
||||
group = "crowdsec";
|
||||
};
|
||||
|
||||
# Inject NTFY_USER and NTFY_PASSWORD into the crowdsec service so the
|
||||
# HTTP plugin template can reference them. The plugin config uses
|
||||
# {{env "NTFY_BASIC_AUTH"}} — a pre-encoded "user:pass" base64 string
|
||||
# for the Authorization: Basic header — computed in ExecStartPre.
|
||||
systemd.services.crowdsec.serviceConfig.EnvironmentFile = lib.mkIf cfg.ntfy.enable [
|
||||
cfg.ntfy.envFile
|
||||
];
|
||||
};
|
||||
};
|
||||
in
|
||||
|
||||
Reference in New Issue
Block a user