Compare commits
2 Commits
be65ccd70c
...
26b810509f
| Author | SHA1 | Date | |
|---|---|---|---|
| 26b810509f | |||
| ecca92f3ed |
66
README.md
Normal file
66
README.md
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
# Traefik-Stack (pi5-1)
|
||||||
|
|
||||||
|
Compose-Stack fuer den Reverse Proxy und die davor haengende CrowdSec-Abwehr.
|
||||||
|
|
||||||
|
| Service | Image | Aufgabe |
|
||||||
|
|---|---|---|
|
||||||
|
| `traefik` | `traefik:v3.7` | Reverse Proxy, TLS-Terminierung, ACME |
|
||||||
|
| `crowdsec` | `crowdsecurity/crowdsec:v1.7.8` | Erkennung aus Traefik-Access-Log + Synology-Syslog |
|
||||||
|
| `crowdsec-mikrotik-bouncer` | `ghcr.io/funkolab/cs-mikrotik-bouncer` | spiegelt Decisions als Drop-Regel auf die AX3 (Edge) |
|
||||||
|
|
||||||
|
Zusaetzlich haengt der **Traefik-Bouncer-Plugin** (`crowdsec@file`-Middleware)
|
||||||
|
direkt im Request-Pfad; die MikroTik-Seite blockt zusaetzlich auf Firewall-Ebene,
|
||||||
|
also auch VPN und SSH.
|
||||||
|
|
||||||
|
## Zwei Repos
|
||||||
|
|
||||||
|
Die **statische und dynamische Traefik-Konfiguration liegt NICHT hier**, sondern
|
||||||
|
unter `/srv/TRAEFIK/etc/traefik` (root-owned, in den Container als `/etc/traefik`
|
||||||
|
gemountet) und wird von einem eigenen Repo versioniert:
|
||||||
|
|
||||||
|
> **[`~/Projects/TraefikConfig`](http://192.168.0.234:8765/lutz/TraefikConfig)**
|
||||||
|
> – `traefik.yml`, `traefik.d/*`, TLS-Inventar, Sync-/Deploy-Skripte, Disaster Recovery
|
||||||
|
|
||||||
|
Hier im Repo liegt alles, was den *Stack* beschreibt:
|
||||||
|
|
||||||
|
```
|
||||||
|
docker-compose.yml Services, Ports, Volumes
|
||||||
|
crowdsec/acquis.yaml Acquisition: Traefik-Access-Log
|
||||||
|
crowdsec/acquis-synology.yaml Acquisition: Syslog-Listener (fids/fids2)
|
||||||
|
crowdsec/parsers/famfihome-synology-connection.yaml lokaler Parser: DSM-7-Anmeldefehler
|
||||||
|
crowdsec/profiles.yaml eskalierende Ban-Dauer (count+1)*12h, max 168h
|
||||||
|
crowdsec/famfi-ca-bundle.pem OpenBAO-CA (fuer RouterOS api-ssl)
|
||||||
|
scripts/sync-synology-certs.sh holt die Synology-LE-Certs nach Traefik
|
||||||
|
```
|
||||||
|
|
||||||
|
Alles unter `crowdsec/` wird per Bind-Mount ins Image gelegt, damit es ein
|
||||||
|
Zuruecksetzen der Named Volumes ueberlebt – die Dateien lagen frueher nur im
|
||||||
|
`crowdsec-config`-Volume und waren damit nicht gesichert.
|
||||||
|
|
||||||
|
## Bedienung
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker compose up -d # Stack starten
|
||||||
|
docker compose up -d crowdsec # nur CrowdSec neu erzeugen (nach Config-Aenderung)
|
||||||
|
|
||||||
|
docker exec crowdsec cscli metrics show acquisition # kommen Logs an?
|
||||||
|
docker exec crowdsec cscli decisions list # aktuelle Bans
|
||||||
|
docker exec crowdsec cscli bouncers list # ziehen die Bouncer?
|
||||||
|
```
|
||||||
|
|
||||||
|
Datenquellen pruefen: Traefik schreibt sein Access-Log ins geteilte Volume
|
||||||
|
`traefik-logs`, CrowdSec liest es read-only. Die Synologies senden per
|
||||||
|
DSM *Log Center → Log Sending* an `192.168.0.142:5514/udp`.
|
||||||
|
|
||||||
|
## Secrets
|
||||||
|
|
||||||
|
`.mikrotik.env` (RouterOS-Passwort + Bouncer-API-Key) ist git-ignoriert und
|
||||||
|
root-only. Der LAPI-Key der Traefik-Middleware liegt in
|
||||||
|
`/srv/TRAEFIK/etc/traefik/traefik.d/crowdsec.yml` und ist ebenfalls bewusst
|
||||||
|
nicht versioniert – siehe TraefikConfig-README.
|
||||||
|
|
||||||
|
## Verwandt
|
||||||
|
|
||||||
|
- `~/Projects/TraefikConfig` – Traefik-Konfiguration (`/srv`), Restore-Prozedur
|
||||||
|
- `~/Projects/OpenBAO` – PKI und Credential-Helper
|
||||||
|
- `~/Projects/ClaudeAdmin` – 4-stuendlicher Healthcheck ueber den Stack
|
||||||
13
crowdsec/acquis-synology.yaml
Normal file
13
crowdsec/acquis-synology.yaml
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
# CrowdSec acquisition: Syslog-Listener fuer die Synology-NAS (fids/fids2)
|
||||||
|
# Gemountet nach /etc/crowdsec/acquis.d/synology.yaml (siehe docker-compose.yml)
|
||||||
|
#
|
||||||
|
# Die Synologies senden per DSM "Log Center -> Log Sending" an
|
||||||
|
# 192.168.0.142:5514/udp; Docker mappt das auf Port 514 im Container.
|
||||||
|
# Das Label "syslog" aktiviert s00-raw/crowdsecurity/syslog-logs; darauf
|
||||||
|
# setzen crowdsecurity/synology-dsm (+ der lokale Parser
|
||||||
|
# parsers/famfihome-synology-connection.yaml) auf.
|
||||||
|
source: syslog
|
||||||
|
listen_addr: 0.0.0.0
|
||||||
|
listen_port: 514
|
||||||
|
labels:
|
||||||
|
type: syslog
|
||||||
24
crowdsec/parsers/famfihome-synology-connection.yaml
Normal file
24
crowdsec/parsers/famfihome-synology-connection.yaml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
# Lokaler CrowdSec-Parser (kein Hub-Item).
|
||||||
|
# Gemountet nach /etc/crowdsec/parsers/s01-parse/famfihome-synology-connection.yaml
|
||||||
|
# (siehe docker-compose.yml). Ergaenzt crowdsecurity/synology-dsm-logs um das
|
||||||
|
# "Connection"-Programm des DSM-7-Log-Centers; speist crowdsecurity/synology-dsm-bf.
|
||||||
|
name: famfihome/synology-connection-logs
|
||||||
|
description: "Synology Log Center 'Connection' events (DSM 7 sign-in failures)"
|
||||||
|
filter: "evt.Parsed.program == 'Connection'"
|
||||||
|
onsuccess: next_stage
|
||||||
|
pattern_syntax:
|
||||||
|
IPv4_WA: '(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)'
|
||||||
|
IP_WA: '(?:%{IPV6}|%{IPv4_WA})'
|
||||||
|
nodes:
|
||||||
|
- grok:
|
||||||
|
pattern: 'User \[%{DATA:user}\] from \[%{IP_WA:src_ip}\] failed to sign in to \[%{DATA:service}\] via \[%{DATA:method}\]'
|
||||||
|
apply_on: message
|
||||||
|
statics:
|
||||||
|
- meta: log_type
|
||||||
|
value: synology-dsm_failed_auth
|
||||||
|
- meta: service
|
||||||
|
value: synology-dsm
|
||||||
|
- meta: source_ip
|
||||||
|
expression: "evt.Parsed.src_ip"
|
||||||
|
- meta: user
|
||||||
|
expression: "evt.Parsed.user"
|
||||||
30
crowdsec/profiles.yaml
Normal file
30
crowdsec/profiles.yaml
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
name: default_ip_remediation
|
||||||
|
#debug: true
|
||||||
|
filters:
|
||||||
|
- Alert.Remediation == true && Alert.GetScope() == "Ip"
|
||||||
|
decisions:
|
||||||
|
- type: ban
|
||||||
|
duration: 12h
|
||||||
|
# Escalating ban: 1st 12h; repeat offenders (while still listed) 24h, 36h ...; capped at 168h (7d)
|
||||||
|
duration_expr: Sprintf('%dh', min((GetDecisionsCount(Alert.GetValue()) + 1) * 12, 168))
|
||||||
|
# notifications:
|
||||||
|
# - slack_default # Set the webhook in /etc/crowdsec/notifications/slack.yaml before enabling this.
|
||||||
|
# - splunk_default # Set the splunk url and token in /etc/crowdsec/notifications/splunk.yaml before enabling this.
|
||||||
|
# - http_default # Set the required http parameters in /etc/crowdsec/notifications/http.yaml before enabling this.
|
||||||
|
# - email_default # Set the required email parameters in /etc/crowdsec/notifications/email.yaml before enabling this.
|
||||||
|
on_success: break
|
||||||
|
---
|
||||||
|
name: default_range_remediation
|
||||||
|
#debug: true
|
||||||
|
filters:
|
||||||
|
- Alert.Remediation == true && Alert.GetScope() == "Range"
|
||||||
|
decisions:
|
||||||
|
- type: ban
|
||||||
|
duration: 12h
|
||||||
|
duration_expr: Sprintf('%dh', min((GetDecisionsCount(Alert.GetValue()) + 1) * 12, 168))
|
||||||
|
# notifications:
|
||||||
|
# - slack_default # Set the webhook in /etc/crowdsec/notifications/slack.yaml before enabling this.
|
||||||
|
# - splunk_default # Set the splunk url and token in /etc/crowdsec/notifications/splunk.yaml before enabling this.
|
||||||
|
# - http_default # Set the required http parameters in /etc/crowdsec/notifications/http.yaml before enabling this.
|
||||||
|
# - email_default # Set the required email parameters in /etc/crowdsec/notifications/email.yaml before enabling this.
|
||||||
|
on_success: break
|
||||||
@@ -48,8 +48,16 @@ services:
|
|||||||
- crowdsec-db:/var/lib/crowdsec/data
|
- crowdsec-db:/var/lib/crowdsec/data
|
||||||
- traefik-logs:/var/log/traefik:ro # liest Traefiks Access-Log
|
- traefik-logs:/var/log/traefik:ro # liest Traefiks Access-Log
|
||||||
- ./crowdsec/acquis.yaml:/etc/crowdsec/acquis.d/traefik.yaml:ro,Z
|
- ./crowdsec/acquis.yaml:/etc/crowdsec/acquis.d/traefik.yaml:ro,Z
|
||||||
|
# Syslog-Quelle Synology (fids/fids2) + lokaler Parser dazu. Beides liegt
|
||||||
|
# im Repo (nicht nur im crowdsec-config-Volume), damit es ein Volume-Reset
|
||||||
|
# ueberlebt.
|
||||||
|
- ./crowdsec/acquis-synology.yaml:/etc/crowdsec/acquis.d/synology.yaml:ro,Z
|
||||||
|
- ./crowdsec/parsers/famfihome-synology-connection.yaml:/etc/crowdsec/parsers/s01-parse/famfihome-synology-connection.yaml:ro,Z
|
||||||
|
# Eskalierende Ban-Dauer ((count+1)*12h, max 168h) - haendisch gepflegt
|
||||||
|
- ./crowdsec/profiles.yaml:/etc/crowdsec/profiles.yaml:ro,Z
|
||||||
ports:
|
ports:
|
||||||
- "192.168.0.142:6060:6060" # Prometheus-Metriken (CrowdSec) fuer 192.168.0.23
|
- "192.168.0.142:6060:6060" # Prometheus-Metriken (CrowdSec) fuer 192.168.0.23
|
||||||
|
- "192.168.0.142:5514:514/udp" # Syslog von den Synologies (DSM Log Center)
|
||||||
|
|
||||||
# MikroTik-Bouncer: spiegelt CrowdSec-Decisions in eine RouterOS-Firewall-
|
# MikroTik-Bouncer: spiegelt CrowdSec-Decisions in eine RouterOS-Firewall-
|
||||||
# Address-List ("crowdsec") auf der AX3 -> Edge-Drop (alle Ports, auch VPN/SSH).
|
# Address-List ("crowdsec") auf der AX3 -> Edge-Drop (alle Ports, auch VPN/SSH).
|
||||||
|
|||||||
Reference in New Issue
Block a user