Initial version: npm-scanner image, filters, entrypoint, watcher, testbed
- Image based on crazymax/fail2ban:1.1.1 with inotify-tools - Filters npm-scanner and npm-wplogin, tested with fail2ban-regex in the build - jail.local generated from .env, optional npm-wplogin and recidive - Watcher reloads the jails when NPM creates a new proxy host log - check command, docs, testbed for LXC Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
d7dcd9d6b1
29 files changed
+1163
No files matched your search
@@ -0,0 +1,96 @@
|
||||
# Konfiguration
|
||||
|
||||
Alle Einstellungen stehen in der `.env` neben der `docker-compose.yaml`. Nach einer Änderung:
|
||||
|
||||
```bash
|
||||
docker compose run --rm npm-scanner check
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Die `jail.local` wird bei **jedem Start** neu aus der `.env` erzeugt.
|
||||
|
||||
## Variablen
|
||||
|
||||
### Allgemein
|
||||
|
||||
| Variable | Standard | Bedeutung |
|
||||
|---|---|---|
|
||||
| `NPM_SCANNER_VERSION` | `latest` | Image-Tag |
|
||||
| `TZ` | `Europe/Vienna` | Zeitzone für Log-Zeitstempel |
|
||||
| `F2B_LOG_LEVEL` | `INFO` | `CRITICAL`, `ERROR`, `WARNING`, `NOTICE`, `INFO`, `DEBUG` |
|
||||
| `F2B_DB_PURGE_AGE` | `30d` | So lange bleiben alte Sperren in der DB – Grundlage für die steigende Sperrdauer und `recidive` |
|
||||
| `NPM_LOG_DIR` | – (Pflicht) | Log-Ordner des NPM auf dem Host |
|
||||
| `NPM_LOG_DIR2` | = `NPM_LOG_DIR` | Zweiter Log-Ordner (jlesage: `logs/`). Ist es derselbe Ordner wie `NPM_LOG_DIR`, wird er nur einmal gelesen. |
|
||||
| `WHITELIST` | leer | IPs/Netze, die nie gesperrt werden, mit Leerzeichen getrennt. `127.0.0.1/8` und `::1` sind immer dabei. |
|
||||
| `F2B_CHAIN` | `DOCKER-USER` | iptables-Kette für die Sperren |
|
||||
| `ENABLE_NEWLOG_WATCH` | `true` | Neue Proxy-Hosts automatisch überwachen |
|
||||
| `NEWLOG_SETTLE_SECONDS` | `5` | Wartezeit nach dem Erscheinen einer neuen Logdatei |
|
||||
| `IPTABLES_MODE` | `auto` | Vom Basis-Image: `auto`, `legacy` (erzwingt iptables-legacy) |
|
||||
|
||||
Zeitangaben: Zahl mit Einheit `s`, `m`, `h`, `d`, `w` – zum Beispiel `10m`, `24h`, `4w`.
|
||||
|
||||
### npm-scanner (immer aktiv)
|
||||
|
||||
| Variable | Standard | Bedeutung |
|
||||
|---|---|---|
|
||||
| `SCANNER_MAXRETRY` | `3` | Treffer bis zur Sperre |
|
||||
| `SCANNER_FINDTIME` | `1h` | Zeitfenster für die Treffer |
|
||||
| `SCANNER_BANTIME` | `24h` | Erste Sperrdauer |
|
||||
| `SCANNER_MAXTIME` | `4w` | Höchste Sperrdauer bei Wiederholung |
|
||||
|
||||
Gelesen werden `proxy-host-*_access.log`, `default-host_access.log`, `fallback_access.log` und
|
||||
`fallback_http_access.log` in beiden Log-Ordnern.
|
||||
|
||||
### npm-wplogin (optional)
|
||||
|
||||
Zählt `POST` auf `wp-login.php` und `xmlrpc.php` auf allen Hosts hinter dem NPM.
|
||||
|
||||
| Variable | Standard |
|
||||
|---|---|
|
||||
| `ENABLE_WPLOGIN` | `false` |
|
||||
| `WPLOGIN_MAXRETRY` | `5` |
|
||||
| `WPLOGIN_FINDTIME` | `10m` |
|
||||
| `WPLOGIN_BANTIME` | `24h` |
|
||||
| `WPLOGIN_MAXTIME` | `4w` |
|
||||
|
||||
### recidive (optional)
|
||||
|
||||
Sperrt Wiederholungstäter über alle Jails in `INPUT` **und** `F2B_CHAIN`.
|
||||
|
||||
| Variable | Standard |
|
||||
|---|---|
|
||||
| `ENABLE_RECIDIVE` | `false` |
|
||||
| `RECIDIVE_MAXRETRY` | `3` |
|
||||
| `RECIDIVE_FINDTIME` | `1w` |
|
||||
| `RECIDIVE_BANTIME` | `4w` |
|
||||
|
||||
Mit `recidive` schreibt fail2ban sein Log nach `./data/log/fail2ban.log` (recidive liest es).
|
||||
`docker logs` zeigt es trotzdem weiter an.
|
||||
|
||||
## Eigene Jails, Filter und Actions
|
||||
|
||||
Der Ordner `./data` wird beim Start eingebunden:
|
||||
|
||||
| Ordner | Wirkung |
|
||||
|---|---|
|
||||
| `./data/jail.d/*.local` | Wird **nach** der erzeugten `jail.local` gelesen – eigene Jails oder Überschreibungen |
|
||||
| `./data/filter.d/*.conf` | Eigene Filter. Gleichnamige Filter des Images werden ersetzt. |
|
||||
| `./data/action.d/*.conf` | Eigene Actions, zum Beispiel für ntfy |
|
||||
| `./data/db/` | fail2ban-Datenbank – nicht von Hand ändern |
|
||||
|
||||
Beispiel: Sperrdauer für npm-scanner auf 48 h, ohne die `.env` zu ändern:
|
||||
|
||||
```bash
|
||||
nano ./data/jail.d/50-eigene.local
|
||||
```
|
||||
|
||||
```ini
|
||||
[npm-scanner]
|
||||
bantime = 48h
|
||||
```
|
||||
|
||||
```bash
|
||||
docker compose restart npm-scanner
|
||||
```
|
||||
|
||||
Die NPM-Logs liegen im Container unter `/logs/npm1` und `/logs/npm2`.
|
||||
@@ -0,0 +1,107 @@
|
||||
# Betrieb
|
||||
|
||||
Alle Befehle im Projektordner (zum Beispiel `/home/docker-projekte/npm-scanner`) als root.
|
||||
|
||||
## Status und Logs
|
||||
|
||||
```bash
|
||||
docker compose ps
|
||||
docker logs --tail 50 npm-scanner
|
||||
docker logs -f npm-scanner
|
||||
docker exec npm-scanner fail2ban-client status
|
||||
docker exec npm-scanner fail2ban-client status npm-scanner
|
||||
```
|
||||
|
||||
Überwachte Dateien:
|
||||
|
||||
```bash
|
||||
docker exec npm-scanner fail2ban-client get npm-scanner logpath
|
||||
```
|
||||
|
||||
Meldungen des Watchers (neue Proxy-Hosts):
|
||||
|
||||
```bash
|
||||
docker logs npm-scanner 2>&1 | grep npm-newlog
|
||||
```
|
||||
|
||||
## Sperren
|
||||
|
||||
```bash
|
||||
docker exec npm-scanner fail2ban-client get npm-scanner banip --with-time
|
||||
docker exec npm-scanner fail2ban-client set npm-scanner unbanip 198.51.100.7
|
||||
docker exec npm-scanner fail2ban-client set npm-scanner banip 198.51.100.7
|
||||
docker exec npm-scanner fail2ban-client unban 198.51.100.7 # aus allen Jails
|
||||
```
|
||||
|
||||
Regeln auf dem Host:
|
||||
|
||||
```bash
|
||||
iptables -S DOCKER-USER
|
||||
iptables -S f2b-npm-scan
|
||||
```
|
||||
|
||||
## Filter gegen echte Logs testen
|
||||
|
||||
Ändert nichts, zeigt nur die Treffer:
|
||||
|
||||
```bash
|
||||
docker exec npm-scanner sh -c 'fail2ban-regex "$(ls -S /logs/npm1/proxy-host-*_access.log | head -1)" /etc/fail2ban/filter.d/npm-scanner.conf' | grep -E '^Lines:'
|
||||
docker exec npm-scanner sh -c 'fail2ban-regex --print-all-matched "$(ls -S /logs/npm1/proxy-host-*_access.log | head -1)" /etc/fail2ban/filter.d/npm-scanner.conf' | grep -E '^\| \[' | head -20
|
||||
```
|
||||
|
||||
## Update
|
||||
|
||||
```bash
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
docker logs --tail 30 npm-scanner
|
||||
```
|
||||
|
||||
Die Sperren bleiben erhalten (fail2ban-DB in `./data/db`).
|
||||
|
||||
## Backup
|
||||
|
||||
```bash
|
||||
mkdir -p /backups/config_backups/$(hostname)
|
||||
docker compose stop npm-scanner
|
||||
tar -cpzf /backups/config_backups/$(hostname)/$(date +%F)_npm-scanner.tar.gz -C .. "$(basename "$PWD")"
|
||||
docker compose start npm-scanner
|
||||
```
|
||||
|
||||
## Fehlerbehebung
|
||||
|
||||
| Meldung | Ursache | Lösung |
|
||||
|---|---|---|
|
||||
| `NPM_LOG_DIR missing in .env` | Variable fehlt | `.env` prüfen |
|
||||
| `/logs/npm1 is missing` | Pfad in `NPM_LOG_DIR` existiert nicht | `ls <pfad>` auf dem Host |
|
||||
| `no proxy-host-*_access.log found yet` | Falscher Ordner oder NPM hat noch keine Hosts | Schritt 1 der Installation wiederholen |
|
||||
| `Have not found any log file for npm-scanner jail` | Keine einzige Logdatei gefunden | wie oben |
|
||||
| `iptables chain DOCKER-USER does not exist` | Docker auf dem Host läuft nicht oder ohne iptables | `systemctl status docker`, `iptables -S DOCKER-USER` |
|
||||
| `iptables-nft is not supported by the host, falling back to iptables-legacy` | Host nutzt iptables-legacy | nur Hinweis; prüfen, dass die Regeln mit `iptables -S` auf dem Host sichtbar sind |
|
||||
| Regeln im Container, nicht auf dem Host | `network_mode: host` fehlt | `docker-compose.yaml` prüfen |
|
||||
| Jede Zeile zählt doppelt | Derselbe Ordner zweimal über verschiedene Pfade eingebunden | `NPM_LOG_DIR2` leer lassen |
|
||||
| Eigene IP gesperrt | Fehlt in `WHITELIST` | entsperren (siehe oben), `WHITELIST` ergänzen, `docker compose up -d` |
|
||||
| Container startet nicht | Fehler in der Konfiguration | `docker compose run --rm npm-scanner check` |
|
||||
|
||||
Notfall – alle Sperren sofort aufheben:
|
||||
|
||||
```bash
|
||||
docker compose stop npm-scanner
|
||||
```
|
||||
|
||||
fail2ban entfernt beim Stoppen seine Regeln. Bleiben sie trotzdem hängen:
|
||||
|
||||
```bash
|
||||
iptables -D DOCKER-USER -j f2b-npm-scan
|
||||
iptables -F f2b-npm-scan
|
||||
iptables -X f2b-npm-scan
|
||||
```
|
||||
|
||||
## Rückbau
|
||||
|
||||
```bash
|
||||
docker compose down
|
||||
iptables -S | grep f2b- || echo "keine f2b-Regeln mehr"
|
||||
```
|
||||
|
||||
Danach den Projektordner löschen, wenn die Sperr-Historie nicht mehr gebraucht wird.
|
||||
Reference in new issue
Block a user