9b18b11f32
Add token- and IP-protected ingest.php, boka status checks in monitor.php, and document the two-repo push workflow. Todo 04 marked complete. Co-authored-by: Cursor <cursoragent@cursor.com>
164 lines
7.2 KiB
Markdown
164 lines
7.2 KiB
Markdown
# Monitoring — externer PHP-Webspace (0012.de)
|
||
|
||
Der vServer **`boka`** (`89.163.231.180`) wird von **`0012.de`** (wint.global Classic 1.0, Plesk-Cron) aus überwacht. Der Webspace sieht den Server von außen — interne Metriken (Disk, Docker) brauchen ein Push-Skript auf boka oder eine Status-API.
|
||
|
||
**Webspace:** unabhängig von boka gehostet — fällt der VPS aus, kann 0012.de noch alarmieren.
|
||
|
||
Siehe auch: [`todo/03-monitoring-pull-phase1.md`](todo/03-monitoring-pull-phase1.md), [`todo/04-monitoring-push-boka.md`](todo/04-monitoring-push-boka.md), [`HOSTING.md`](HOSTING.md)
|
||
|
||
---
|
||
|
||
## Architektur (empfohlen)
|
||
|
||
### Ebene 1 — Pull (PHP-Cron auf Webspace, alle 5–15 Min)
|
||
|
||
- HTTPS-Checks auf öffentliche URLs
|
||
- SSL-Zertifikat-Ablauf
|
||
- Optional: TCP-Checks (Gitea SSH, RustDesk)
|
||
- Bei Fehler: E-Mail / Telegram (nach 2. Versuch, 2 Min Abstand → weniger Fehlalarme)
|
||
|
||
### Ebene 2 — Push (Cron auf boka, alle 5 Min) — **implementiert** (2026-06-12)
|
||
|
||
- Skript `~/server/scripts/push-status.sh` postet JSON an `ingest.php` (Token + IP-Whitelist)
|
||
- Payload: `load`, `disk_percent`, `mem_available_mb`, `containers_running`, `containers_unhealthy`
|
||
- `ingest.php` speichert nach `private/data/boka-status.json`
|
||
- `monitor.php` prüft: kein Push seit 15 Min → „boka silent“; optional Disk > 85 %, unhealthy > 0, Backup > 25h
|
||
- Sicherheit: `BOKA_IP=89.163.231.180` — nur Requests von dieser IP werden akzeptiert (zusätzlich zum Token)
|
||
|
||
**Zwei Repos:** PHP in diesem Repo (Pull + Ingest); Push-Skript + Cron im boka-Repo (`~/server`). Deploy-Ablauf: [`todo/04-monitoring-push-boka.md`](todo/04-monitoring-push-boka.md); boka-seitig `docs/MONITORING-WORKFLOW.md`.
|
||
|
||
---
|
||
|
||
## Prio **high** — zuerst umsetzen
|
||
|
||
| Was | Wie (extern) | Warum |
|
||
|-----|----------------|-------|
|
||
| HTTPS-Erreichbarkeit kritischer Domains | `curl` / `file_get_contents`, Timeout ~10s, Status 200/301 | Einzelne Apps können down sein, ohne dass es auffällt (z. B. bringtake) |
|
||
| Traefik / Edge | `https://schwenk.online` + eine App-Domain + `https://gitea.schwenk.online` | Fällt Traefik oder Let's Encrypt aus, sind viele Sites betroffen |
|
||
| Gitea | HTTPS, optional Login-Seite erreichbar | Zentrale Git-/CI-Basis |
|
||
| Immich | `https://pics.schwenk.online` | Fotos, großer Datenbestand |
|
||
| SSL-Zertifikat-Ablauf | TLS-Handshake prüfen, Warnung bei < 14 Tagen | Ablauf oder verlorenes `acme.json` = Ausfall vieler Dienste |
|
||
| Backup-Heartbeat | Server pingt nach erfolgreichem Backup den Webspace; Cron alarmiert bei **keinem Ping seit 25h** | Sobald Backups existieren: kritisch |
|
||
| Alarm bei Ausfall | E-Mail oder Telegram vom PHP-Cron | Externer Beobachter ohne Zugang zu boka |
|
||
|
||
### Mindest-URL-Liste (Start)
|
||
|
||
- `https://schwenk.online`
|
||
- `https://gitea.schwenk.online`
|
||
- `https://pics.schwenk.online`
|
||
- `https://medis.schwenk.online`
|
||
- `https://portainer.schwenk.online`
|
||
- Eine `bsc-gp.de`-Subdomain (z. B. `https://score.bsc-gp.de`)
|
||
- `https://vfb.red`
|
||
|
||
---
|
||
|
||
## Prio **medium** — bald sinnvoll
|
||
|
||
| Was | Wie (extern) | Warum |
|
||
|-----|----------------|-------|
|
||
| Weitere App-Domains | HTTP-Check pro Stack | Viele kleine Sites; einzelne Container können sterben |
|
||
| API-Health | z. B. `https://api.bringtake.schwenk.online/health` | Frontend kann 200 liefern, Backend tot |
|
||
| Antwortzeit | Dauer messen, Warnung bei > 5s | Frühwarnung bei Last (Immich ML, viele Container) |
|
||
| Inhalt prüfen | Marker-String im HTML (`<title>`, fester Text) | Erkennt „200 aber leere/falsche Seite“ |
|
||
| HTTP→HTTPS-Redirect | `http://domain` → 301/308 | Kaputter Redirect = Browser-Warnungen |
|
||
| DNS-Auflösung | `gethostbyname` / DNS-API | Domain zeigt plötzlich woanders hin |
|
||
| Gitea SSH | TCP-Check Port **2222** (`fsockopen`) | Git per SSH unabhängig von der Web-UI |
|
||
| RustDesk | TCP **21115–21117** (falls genutzt) | Kein HTTP möglich |
|
||
| SSL pro Subdomain | Einzelcheck je Host | Nicht jeder Host nutzt dasselbe Zertifikat |
|
||
| Push-Status vom Server | `POST` an Webspace mit Token + JSON | Disk/RAM/Container sonst von außen unsichtbar |
|
||
|
||
### Weitere URLs (medium, nach und nach)
|
||
|
||
- `https://affen.schwenk.online`
|
||
- `https://bringtake.schwenk.online`
|
||
- `https://api.bringtake.schwenk.online`
|
||
- `https://link.schwenk.online`
|
||
- `https://traefik.schwenk.online` (nur wenn Dashboard öffentlich bleiben soll)
|
||
- Weitere `*.schwenk.online` und `*.bsc-gp.de` laut Inventory
|
||
|
||
---
|
||
|
||
## Prio **low** — nice to have
|
||
|
||
| Was | Wie (extern) | Warum |
|
||
|-----|----------------|-------|
|
||
| Alle ~25 Domains einzeln | Lange Checkliste | Hoher Pflegeaufwand; Stichproben reichen oft |
|
||
| Security Headers | HSTS, `X-Frame-Options` | Sicherheit, kein Verfügbarkeitsproblem |
|
||
| TLS-Version / Cipher | Nur TLS 1.2+ | Selten akut |
|
||
| Port-Scan light | 22, 80, 443, 2222 erwartet; **5432 nicht** offen | Postgres soll nicht öffentlich sein |
|
||
| Blacklist / Malware-Scan | Externe API | Für Homelab meist overkill |
|
||
| WHOIS / Domain-Ablauf | Registrar-API | Oft ohnehin Mail vom Registrar |
|
||
| Öffentliche Feeds | RSS/iCal-Outputs | Nur wenn businesskritisch |
|
||
| Synthetic Login | Formular-POST mit Test-User | Aufwendig, bricht bei UI-Änderungen |
|
||
| Response-Größe | Plötzlich sehr kleine Antwort | Selten nötig |
|
||
| Uptime-Dashboard / SLA | DB auf Webspace | Nach echten Checks |
|
||
|
||
---
|
||
|
||
## Von außen schlecht prüfbar (ohne Hilfsskript auf boka)
|
||
|
||
| Intern | Lösung |
|
||
|--------|--------|
|
||
| Disk voll, RAM, Load | Push-Endpoint (Ebene 2) |
|
||
| `docker ps`, exited containers | Status-JSON von boka pushen |
|
||
| Log-Fehler, OOM | Push oder zentraler Log-Dienst |
|
||
| Dangling volumes, Backup-Größe | Nur auf dem Host |
|
||
| fail2ban / SSH-Bruteforce | Auth-Log per Push oder separater Dienst |
|
||
|
||
**Pragmatisch:** `monitor-push.sh` auf boka (Cron alle 5 Min) → POST an Webspace:
|
||
|
||
```json
|
||
{
|
||
"token": "...",
|
||
"load": [1.2, 0.8, 0.5],
|
||
"disk_percent": 55,
|
||
"mem_available_mb": 4700,
|
||
"containers_running": 38,
|
||
"containers_unhealthy": 0,
|
||
"backup_last_success": "2026-06-10T03:00:00+02:00"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## Umsetzung in Phasen
|
||
|
||
### Phase 1 (high, ~1h)
|
||
|
||
- 8–12 HTTPS-URLs aus der Mindestliste
|
||
- SSL-Ablauf < 14 Tage → Warnung
|
||
- E-Mail bei Fehler, Retry nach 2 Minuten
|
||
|
||
### Phase 2 (medium)
|
||
|
||
- API-Health für Stacks mit Backend (bringtake, medis, affen, …)
|
||
- Latenz-Schwelle
|
||
- Backup-Heartbeat (sobald Backups existieren) — Ingest-Feld `backup_last_success` vorbereitet
|
||
- ~~Push-Status von boka~~ → erledigt (Todo 04)
|
||
|
||
### Phase 3 (low)
|
||
|
||
- Restliche Domains, Header-Checks, Dashboard
|
||
|
||
---
|
||
|
||
## Dateien
|
||
|
||
| Ort | Datei | Zweck |
|
||
|-----|-------|--------|
|
||
| Webspace | `monitor.php` | Cron: Pull-Checks + boka-Stale/Schwellen |
|
||
| Webspace | `ingest.php` | Empfang Push von boka (Token + IP) |
|
||
| Webspace | `private/data/boka-status.json` | Letzter Push-Stand |
|
||
| boka | `~/server/scripts/push-status.sh` | Sammelt Metriken, POST an Webspace |
|
||
| boka | `~/server/config/push.env` | `INGEST_URL`, `PUSH_TOKEN` |
|
||
| boka | Crontab | `*/5 * * * *` push-status |
|
||
|
||
---
|
||
|
||
## Hinweise
|
||
|
||
- **Portainer** und **Traefik-Dashboard** öffentlich monitoren = öffentlich bestätigen, dass sie erreichbar sind. Basic Auth beibehalten; Monitoring prüft nur Erreichbarkeit (und ggf. 401 als „ok“).
|
||
- **Exit 401/403** kann bei geschützten Diensten **erwünscht** sein — Checks pro Host konfigurieren.
|
||
- Externer Monitor ersetzt kein **fail2ban** oder **UFW-Audit** auf boka (separates boka-Repo).
|