Add project files: source code, Docker setup, docs and config templates
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,620 @@
|
||||
# NetMon – Netzwerk Monitor
|
||||
|
||||
Vollständiges Netzwerk-Monitoring-System mit Live-Paketmitschnitt, Ausfallserkennung, Geräteverfolgung und FritzBox-Integration. Läuft 24/7 als Docker-Container und speichert alle Daten in einer SQLite-Datenbank. Auswertung über ein Web-Dashboard.
|
||||
|
||||
---
|
||||
|
||||
## Inhaltsverzeichnis
|
||||
|
||||
1. [Schnellstart](#1-schnellstart)
|
||||
2. [Architektur](#2-architektur)
|
||||
3. [Konfiguration (.env)](#3-konfiguration-env)
|
||||
4. [Funktionen](#4-funktionen)
|
||||
5. [Web-Dashboard](#5-web-dashboard)
|
||||
6. [REST-API](#6-rest-api)
|
||||
7. [Datenbank-Schema](#7-datenbank-schema)
|
||||
8. [Deployment](#8-deployment)
|
||||
9. [Troubleshooting](#9-troubleshooting)
|
||||
|
||||
---
|
||||
|
||||
## 1. Schnellstart
|
||||
|
||||
```bash
|
||||
cd /root/netmon
|
||||
|
||||
# 1. Konfiguration anlegen
|
||||
cp .env.example .env
|
||||
nano .env # mindestens FRITZ_PASSWORD setzen
|
||||
|
||||
# 2. Starten
|
||||
docker compose up -d --build
|
||||
|
||||
# 3. Dashboard öffnen
|
||||
# http://<server-ip>:5000
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Architektur
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ main.py (Einstiegspunkt) │
|
||||
│ .env laden → DB initialisieren → Threads starten │
|
||||
│ → Flask-Webserver starten │
|
||||
└────────────────────────┬────────────────────────────────┘
|
||||
│
|
||||
┌───────────────┼───────────────┐
|
||||
│ │ │
|
||||
┌────▼─────┐ ┌────▼────┐ ┌────▼────┐
|
||||
│ monitor │ │ api │ │database │
|
||||
│ 7 Threads│ │ Flask │ │ SQLite │
|
||||
└────┬─────┘ └────┬────┘ └─────────┘
|
||||
│ │
|
||||
│ ┌──────────┴──────────┐
|
||||
│ │ REST-API-Endpunkte │
|
||||
│ │ Statische Dateien │
|
||||
│ └─────────────────────┘
|
||||
│
|
||||
┌────┴──────────────────────────────────┐
|
||||
│ Thread 1 │ Traffic-Loop (60s) │
|
||||
│ Thread 2 │ Outage-Loop (5s) │
|
||||
│ Thread 3 │ Device-Loop (300s) │
|
||||
│ Thread 4 │ Port-Loop (3600s) │
|
||||
│ Thread 5 │ FritzBox-Loop (60s) │
|
||||
│ Thread 6 │ Cleanup-Loop (24h) │
|
||||
│ Thread 7 │ Capture-Loop (dauerhaft)│
|
||||
└───────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### Komponenten
|
||||
|
||||
| Datei | Aufgabe |
|
||||
|---|---|
|
||||
| `src/main.py` | Einstiegspunkt, startet alles |
|
||||
| `src/monitor.py` | Alle 7 Monitoring-Threads |
|
||||
| `src/database.py` | SQLite-Zugriff, alle DB-Funktionen |
|
||||
| `src/fritz.py` | FritzBox TR-064 Client |
|
||||
| `src/scanner.py` | ARP-Scan, nmap Port-Scan, Vendor-Lookup |
|
||||
| `src/api.py` | Flask REST-API + statische Dateien |
|
||||
| `src/web/` | HTML/CSS/JS Frontend |
|
||||
|
||||
### Technologie-Stack
|
||||
|
||||
| Bereich | Technologie |
|
||||
|---|---|
|
||||
| Backend | Python 3.11, Flask 3.0 |
|
||||
| Datenbank | SQLite (WAL-Mode, thread-safe) |
|
||||
| Paketmitschnitt | scapy |
|
||||
| Port-Scan | python-nmap |
|
||||
| Traffic-Messung | psutil |
|
||||
| Router-Integration | fritzconnection (TR-064) |
|
||||
| Frontend | Bootstrap 5.3 (Dark Theme), Chart.js 4 |
|
||||
| Container | Docker, host-network, privileged |
|
||||
|
||||
---
|
||||
|
||||
## 3. Konfiguration (.env)
|
||||
|
||||
Alle Einstellungen erfolgen ausschließlich über die `.env`-Datei im Projektordner.
|
||||
|
||||
### FritzBox
|
||||
|
||||
```env
|
||||
FRITZ_HOST=192.168.178.1 # IP der FritzBox (Standard AVM: 192.168.178.1)
|
||||
FRITZ_USER= # Benutzername (leer = kein Auth)
|
||||
FRITZ_PASSWORD=dein_passwort # Passwort – PFLICHTFELD für FritzBox-Integration
|
||||
```
|
||||
|
||||
> Ohne `FRITZ_PASSWORD` läuft das System weiter, FritzBox-Daten fehlen aber im Dashboard.
|
||||
|
||||
### Netzwerk
|
||||
|
||||
```env
|
||||
MONITOR_INTERFACE=auto # "auto" = primäres Interface, oder z.B. "eth0", "ens18"
|
||||
NETWORK_RANGE=auto # "auto" = wird aus Interface berechnet, oder "192.168.1.0/24"
|
||||
```
|
||||
|
||||
### Monitoring-Intervalle (Sekunden)
|
||||
|
||||
```env
|
||||
TRAFFIC_INTERVAL=60 # Bandbreiten-Messung alle 60s
|
||||
OUTAGE_CHECK_INTERVAL=5 # Ping-Prüfung alle 5s
|
||||
DEVICE_SCAN_INTERVAL=300 # Geräte-Scan alle 5 Minuten
|
||||
PORT_SCAN_INTERVAL=3600 # Port-Scan alle 60 Minuten
|
||||
FRITZ_POLL_INTERVAL=60 # FritzBox-Abfrage alle 60s
|
||||
OUTAGE_THRESHOLD=2 # Aufeinanderfolgende Fehlschläge bis Ausfall erkannt wird
|
||||
```
|
||||
|
||||
### Ausfalls-Erkennung
|
||||
|
||||
```env
|
||||
PING_TARGETS=8.8.8.8,1.1.1.1,9.9.9.9 # Kommaseparierte Ping-Ziele
|
||||
# Gateway wird automatisch hinzugefügt
|
||||
```
|
||||
|
||||
> Der Default-Gateway wird immer automatisch erkannt und als erstes Ziel hinzugefügt.
|
||||
|
||||
### Paketmitschnitt
|
||||
|
||||
```env
|
||||
CAPTURE_ENABLED=true # Mitschnitt ein/aus
|
||||
|
||||
# Protokoll-Filter (true = herausfiltern, false = mitschneiden)
|
||||
CAPTURE_FILTER_ICMP=true # Ping/ICMP ausblenden
|
||||
CAPTURE_FILTER_ARP=true # ARP ausblenden
|
||||
CAPTURE_FILTER_ZABBIX=true # Zabbix (Port 10050/10051) ausblenden
|
||||
CAPTURE_FILTER_RUSTDESK=true # RustDesk (Port 21115-21119) ausblenden
|
||||
|
||||
# Eigener BPF-Filter (wird mit AND angehängt)
|
||||
CAPTURE_FILTER_EXTRA= # z.B.: not port 5353 and not port 1900
|
||||
|
||||
CAPTURE_MAX_ROWS=50000 # Max. Einträge in DB (Rolling Window)
|
||||
```
|
||||
|
||||
**BPF-Filter Beispiele für `CAPTURE_FILTER_EXTRA`:**
|
||||
|
||||
```bash
|
||||
# mDNS und SSDP rausfiltern
|
||||
CAPTURE_FILTER_EXTRA=not port 5353 and not port 1900
|
||||
|
||||
# Nur lokalen Traffic anzeigen
|
||||
CAPTURE_FILTER_EXTRA=dst net 192.168.1.0/24
|
||||
|
||||
# Bestimmten Host ausblenden
|
||||
CAPTURE_FILTER_EXTRA=not host 192.168.1.50
|
||||
```
|
||||
|
||||
### Datenbank & Web
|
||||
|
||||
```env
|
||||
DB_PATH=/data/netmon.db # Pfad zur SQLite-Datenbank im Container
|
||||
WEB_HOST=0.0.0.0 # Bind-Adresse (0.0.0.0 = alle Interfaces)
|
||||
WEB_PORT=5000 # HTTP-Port
|
||||
LOG_LEVEL=INFO # DEBUG / INFO / WARNING / ERROR
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. Funktionen
|
||||
|
||||
### Traffic-Messung
|
||||
|
||||
Misst alle 60 Sekunden die Bandbreite auf dem überwachten Interface via `psutil`. Gespeichert werden:
|
||||
- Bytes/s (Upload + Download)
|
||||
- Paketanzahl
|
||||
- Delta-Bytes seit letzter Messung
|
||||
|
||||
Daten werden 35 Tage aufbewahrt und täglich automatisch bereinigt.
|
||||
|
||||
### Ausfalls-Erkennung
|
||||
|
||||
Alle 5 Sekunden werden alle Ping-Ziele **gleichzeitig** (parallel) angepingt:
|
||||
|
||||
- Timeout: 1 Sekunde pro Ping
|
||||
- Erst wenn **alle** Ziele nicht antworten, wird ein Ausfall registriert
|
||||
- Nach `OUTAGE_THRESHOLD` aufeinanderfolgenden Fehlschlägen → Ausfall-Eintrag in DB
|
||||
- Jeder einzelne Ping-Versuch wird geloggt (auch kurze Blips unter der Ausfall-Schwelle sichtbar)
|
||||
- Der Default-Gateway wird automatisch zu den Zielen hinzugefügt
|
||||
|
||||
**Warum 2-fache Schwelle?** Verhindert Fehlalarme durch einzelne Paketverluste im Netz.
|
||||
|
||||
### Geräte-Erkennung
|
||||
|
||||
Alle 5 Minuten:
|
||||
1. **ARP-Scan** des gesamten Netzwerks via scapy → erkennt alle aktiven Geräte
|
||||
2. **Fallback auf nmap** wenn scapy nicht verfügbar/keine Rechte
|
||||
3. **FritzBox-Abgleich** → Gerätenamen und Verbindungstyp (LAN/WLAN/Gast)
|
||||
4. **Reverse-DNS** → Hostname-Auflösung
|
||||
5. **MAC-Vendor-Lookup** → Hersteller aus MAC-Präfix (Apple, Samsung, Raspberry Pi, etc.)
|
||||
|
||||
Geräte die nicht mehr gesehen werden, bekommen `is_active=0`.
|
||||
|
||||
### Port-Scan
|
||||
|
||||
Jede Stunde wird für alle aktiven Geräte ein **nmap-Quick-Scan** durchgeführt:
|
||||
|
||||
Gescannte Ports: `21-23, 25, 53, 80, 110, 111, 135, 139, 143, 443, 445, 548, 993, 995, 1080, 1194, 1433, 1883, 2049, 3306, 3389, 4000, 5000, 5432, 5900, 6379, 8080, 8443, 8883, 9100, 27017`
|
||||
|
||||
Ergebnisse werden pro Gerät gespeichert und im Dashboard angezeigt.
|
||||
|
||||
### FritzBox-Integration
|
||||
|
||||
Alle 60 Sekunden werden via TR-064 API abgefragt:
|
||||
- Verbindungsstatus (online/offline)
|
||||
- Verbindungszeit (Uptime seit letztem Reconnect)
|
||||
- Maximale Up-/Downloadrate (vom Provider)
|
||||
- Gesamte übertragene Datenmenge
|
||||
- Aktuelle externe IP-Adresse
|
||||
- Liste aller bekannten Geräte (Name, IP, MAC, Interface-Typ)
|
||||
|
||||
Bei Verbindungsverlust zur FritzBox wird automatisch alle 10 Minuten ein Reconnect versucht.
|
||||
|
||||
### Live-Paketmitschnitt
|
||||
|
||||
Dauerhafter Mitschnitt via scapy auf dem konfigurierten Interface. Gespeichert wird nur **Metadaten** (kein Payload):
|
||||
|
||||
| Feld | Inhalt |
|
||||
|---|---|
|
||||
| Zeitstempel | Millisekunden-Präzision |
|
||||
| Quelle | IP:Port |
|
||||
| Ziel | IP:Port |
|
||||
| Protokoll | TCP/UDP/DNS/HTTP/HTTPS/SSH/SMB/... |
|
||||
| Länge | Bytes |
|
||||
| Flags | TCP-Flags (SYN/ACK/FIN/RST/PSH) |
|
||||
| Info | Lesbare Zusammenfassung |
|
||||
|
||||
Erkannte Protokolle: `TCP, UDP, HTTP, HTTPS, SSH, FTP, SMTP, DNS, DHCP, NTP, mDNS, SSDP, SMB, RDP, VNC, MySQL, PostgreSQL, Redis, MongoDB, MQTT, AFP`
|
||||
|
||||
Rolling Window: Älteste Einträge werden gelöscht wenn `CAPTURE_MAX_ROWS` erreicht.
|
||||
|
||||
---
|
||||
|
||||
## 5. Web-Dashboard
|
||||
|
||||
Erreichbar unter `http://<server-ip>:5000`
|
||||
|
||||
### Tab: Dashboard
|
||||
|
||||
- **Status-Badge** (Navbar): Internet Online/Offline + aktuelle Geschwindigkeit
|
||||
- **Stat-Karten**: Internet-Status · Aktive Geräte · Ausfälle heute · Ausfallzeit heute
|
||||
- **Traffic-Chart**: Zeitreihe Upload/Download in kbps (Zeitbereiche: 1h / 6h / 24h / 7d / 30d)
|
||||
- **Letzte Ausfälle**: Tabelle der 10 letzten Ausfälle mit Dauer
|
||||
|
||||
### Tab: Geräte
|
||||
|
||||
- Vollständige Geräteliste mit Status, IP, MAC, Hersteller, Verbindungstyp
|
||||
- Suchfeld (filtert nach Name, IP, MAC, Hersteller)
|
||||
- Toggle für inaktive Geräte
|
||||
- **Port-Modal**: Klick auf Port-Anzahl → alle offenen Ports mit Service-Name
|
||||
|
||||
### Tab: Ausfälle
|
||||
|
||||
- **Ping-Statistik** pro Ziel: Checks · Erfolgsrate · Ausfallrate · Latenz (Ø/Min/Max)
|
||||
- Zeitbereich wählbar (1h / 6h / 24h / 7d)
|
||||
- **Ausfall-Protokoll**: Komplette History mit Start, Ende, Dauer, Status
|
||||
|
||||
### Tab: FritzBox
|
||||
|
||||
- Verbindungsstatus · Externe IP · Max. Download/Upload · Verbindungszeit
|
||||
- Gesamter Datenverbrauch (seit letztem Router-Reset)
|
||||
- **Verbindungsverlauf** (letzte 24h) als Chart
|
||||
|
||||
### Tab: Mitschnitt
|
||||
|
||||
- **Live-Paketliste** (aktualisiert alle 2 Sekunden)
|
||||
- Protokoll-Farben (wie Wireshark):
|
||||
- Blau = TCP · Grün = HTTP/HTTPS/SSH · Lila = UDP · Orange = DNS/DHCP · Rot = SMB/RDP
|
||||
- Filterfeld: Echtzeit-Filter nach IP, Port, Protokoll
|
||||
- Anzeige-Limit wählbar (100 / 200 / 500 / 1000 Pakete)
|
||||
- Live/Pause-Toggle
|
||||
- Auto-Scroll (optional)
|
||||
|
||||
---
|
||||
|
||||
## 6. REST-API
|
||||
|
||||
Basis-URL: `http://<server-ip>:5000/api`
|
||||
|
||||
### GET /api/status
|
||||
|
||||
Aktueller Gesamtstatus.
|
||||
|
||||
```json
|
||||
{
|
||||
"internet_up": true,
|
||||
"bps_up": 125000,
|
||||
"bps_down": 890000,
|
||||
"active_devices": 12,
|
||||
"total_devices": 18,
|
||||
"outages_today": 2,
|
||||
"total_outage_seconds_today": 37,
|
||||
"current_outage_since": null,
|
||||
"fritz": {
|
||||
"available": true,
|
||||
"is_connected": 1,
|
||||
"external_ip": "93.x.x.x",
|
||||
"uptime_s": 86400,
|
||||
"max_up_bps": 10000000,
|
||||
"max_down_bps": 50000000
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### GET /api/traffic?range=1h
|
||||
|
||||
Traffic-Zeitreihe. `range`: `1h` | `6h` | `24h` | `7d` | `30d`
|
||||
|
||||
```json
|
||||
{
|
||||
"labels": ["12:00", "12:01", "12:02"],
|
||||
"upload": [12.5, 8.3, 45.1],
|
||||
"download": [89.2, 102.4, 78.9]
|
||||
}
|
||||
```
|
||||
|
||||
### GET /api/outages?limit=100&since=1700000000
|
||||
|
||||
Ausfall-History.
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 42,
|
||||
"start_ts": 1700012345,
|
||||
"end_ts": 1700012382,
|
||||
"duration_s": 37,
|
||||
"duration_human": "37s",
|
||||
"start_human": "15.11.2024 09:12:25",
|
||||
"end_human": "15.11.2024 09:13:02"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### GET /api/devices
|
||||
|
||||
Alle Geräte.
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"id": 1,
|
||||
"mac": "aa:bb:cc:dd:ee:ff",
|
||||
"ip": "192.168.1.42",
|
||||
"name": "Mein Laptop",
|
||||
"hostname": "laptop.local",
|
||||
"fritz_name": "Mein Laptop",
|
||||
"vendor": "Apple",
|
||||
"iface_type": "802.11 ax",
|
||||
"is_active": true,
|
||||
"first_seen": 1700000000,
|
||||
"last_seen": 1700012345,
|
||||
"last_seen_human": "15.11.2024 09:12:25",
|
||||
"port_count": 3
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### GET /api/devices/\<id\>/ports
|
||||
|
||||
Offene Ports eines Geräts.
|
||||
|
||||
```json
|
||||
[
|
||||
{"port": 22, "protocol": "tcp", "service": "ssh", "state": "open"},
|
||||
{"port": 80, "protocol": "tcp", "service": "http", "state": "open"},
|
||||
{"port": 443, "protocol": "tcp", "service": "https", "state": "open"}
|
||||
]
|
||||
```
|
||||
|
||||
### GET /api/packets?since=\<unix_ts\>&limit=200&filter=\<text\>
|
||||
|
||||
Live-Paketmitschnitt. `since` = UNIX-Timestamp (float), nur neuere Pakete werden zurückgegeben.
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"ts": 1700012345.123,
|
||||
"iface": "ens18",
|
||||
"src_ip": "192.168.1.42",
|
||||
"dst_ip": "1.1.1.1",
|
||||
"src_port": 54321,
|
||||
"dst_port": 443,
|
||||
"protocol": "HTTPS",
|
||||
"length": 128,
|
||||
"flags": "SYN",
|
||||
"info": "54321→443 [SYN] Seq=0"
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
### GET /api/ping_log?minutes=60
|
||||
|
||||
Ping-Log der letzten N Minuten + Statistik pro Ziel.
|
||||
|
||||
```json
|
||||
{
|
||||
"log": [
|
||||
{"ts": 1700012345, "target": "8.8.8.8", "success": 1, "latency_ms": 12.4}
|
||||
],
|
||||
"stats": [
|
||||
{
|
||||
"target": "8.8.8.8",
|
||||
"total": 720,
|
||||
"ok": 718,
|
||||
"avg_ms": 14.2,
|
||||
"min_ms": 9.1,
|
||||
"max_ms": 89.3
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### GET /api/fritz?hours=24
|
||||
|
||||
FritzBox-Status und Verbindungsverlauf.
|
||||
|
||||
```json
|
||||
{
|
||||
"latest": {
|
||||
"ts": 1700012345,
|
||||
"is_connected": 1,
|
||||
"uptime_s": 86400,
|
||||
"max_up_bps": 10000000,
|
||||
"max_down_bps": 50000000,
|
||||
"total_bytes_sent": 15000000000,
|
||||
"total_bytes_recv": 120000000000,
|
||||
"external_ip": "93.x.x.x"
|
||||
},
|
||||
"history": [
|
||||
{"bucket": 1700010000, "connected": 1.0}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. Datenbank-Schema
|
||||
|
||||
SQLite-Datenbank unter `./data/netmon.db` (im Container: `/data/netmon.db`).
|
||||
|
||||
```sql
|
||||
-- Bandbreiten-Messungen (alle 60s)
|
||||
traffic (id, ts, iface, bytes_sent, bytes_recv, pkts_sent, pkts_recv, bps_sent, bps_recv)
|
||||
|
||||
-- Internetausfälle
|
||||
outages (id, start_ts, end_ts, duration_s)
|
||||
|
||||
-- Jeder einzelne Ping-Versuch
|
||||
ping_log (id, ts, target, success, latency_ms)
|
||||
|
||||
-- Paketmitschnitt-Metadaten (Rolling Window)
|
||||
packets (id, ts, iface, src_ip, dst_ip, src_port, dst_port, protocol, length, flags, info)
|
||||
|
||||
-- Erkannte Geräte
|
||||
devices (id, mac, ip, hostname, vendor, fritz_name, iface_type, first_seen, last_seen, is_active)
|
||||
|
||||
-- Offene Ports pro Gerät
|
||||
ports (id, device_id→devices, port, protocol, service, state, ts)
|
||||
|
||||
-- FritzBox-Verbindungsdaten (alle 60s)
|
||||
fritz_stats (id, ts, is_connected, uptime_s, max_up_bps, max_down_bps, total_bytes_sent, total_bytes_recv, external_ip)
|
||||
```
|
||||
|
||||
Alle Zeitstempel sind UNIX-Timestamps (Integer). Die `packets`-Tabelle verwendet `REAL` für Millisekunden-Präzision.
|
||||
|
||||
**Datenhaltung:**
|
||||
- Traffic, Ping-Log, FritzBox-Stats: automatisch nach **35 Tagen** gelöscht
|
||||
- Pakete: Rolling Window, maximal `CAPTURE_MAX_ROWS` Einträge
|
||||
|
||||
---
|
||||
|
||||
## 8. Deployment
|
||||
|
||||
### Voraussetzungen
|
||||
|
||||
- Docker + Docker Compose
|
||||
- Linux-Host (für raw sockets / packet capture)
|
||||
- Root-Rechte (für ARP-Scan, nmap, scapy)
|
||||
|
||||
### Docker Compose (empfohlen)
|
||||
|
||||
```yaml
|
||||
# docker-compose.yml
|
||||
services:
|
||||
netmon:
|
||||
build: .
|
||||
container_name: netmon
|
||||
restart: unless-stopped
|
||||
network_mode: host # Pflicht für echte Interface-Daten
|
||||
privileged: true # Pflicht für scapy/nmap raw sockets
|
||||
env_file: .env
|
||||
volumes:
|
||||
- ./data:/data # DB persistent auf dem Host
|
||||
```
|
||||
|
||||
```bash
|
||||
# Starten
|
||||
docker compose up -d --build
|
||||
|
||||
# Logs anschauen
|
||||
docker logs netmon -f
|
||||
|
||||
# Neu deployen nach .env-Änderung
|
||||
docker compose restart
|
||||
|
||||
# Neu bauen nach Code-Änderung
|
||||
docker compose up -d --build
|
||||
|
||||
# Stoppen
|
||||
docker compose down
|
||||
```
|
||||
|
||||
### Ohne Docker (direkt auf dem Host)
|
||||
|
||||
```bash
|
||||
cd /root/netmon
|
||||
cp .env.example .env && nano .env
|
||||
sudo ./start.sh # sudo wegen raw sockets
|
||||
```
|
||||
|
||||
### Daten sichern
|
||||
|
||||
```bash
|
||||
# Datenbank sichern
|
||||
cp ./data/netmon.db ./data/netmon_backup_$(date +%Y%m%d).db
|
||||
```
|
||||
|
||||
### Auf anderem System deployen
|
||||
|
||||
```bash
|
||||
# Projekt kopieren
|
||||
scp -r /root/netmon user@neuer-server:/opt/netmon
|
||||
|
||||
# Auf neuem Server
|
||||
cd /opt/netmon
|
||||
cp .env.example .env
|
||||
nano .env # IP/Passwort anpassen
|
||||
docker compose up -d --build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Troubleshooting
|
||||
|
||||
### Dashboard zeigt keine Daten
|
||||
|
||||
```bash
|
||||
docker logs netmon --tail=50
|
||||
```
|
||||
|
||||
Häufige Ursachen:
|
||||
- **FritzBox nicht erreichbar**: `FRITZ_HOST` prüfen, Passwort prüfen
|
||||
- **Falsches Interface**: `MONITOR_INTERFACE=auto` oder manuell setzen (z.B. `eth0`)
|
||||
|
||||
### Paketmitschnitt leer
|
||||
|
||||
```bash
|
||||
# Interface prüfen
|
||||
docker exec netmon python3 -c "import scapy.all as s; print(s.get_if_list())"
|
||||
|
||||
# Privileged-Mode aktiv?
|
||||
docker inspect netmon | grep Privileged
|
||||
```
|
||||
|
||||
Muss `true` sein. Falls nicht: `docker compose down && docker compose up -d`.
|
||||
|
||||
### Geräte werden nicht gefunden
|
||||
|
||||
- `NETWORK_RANGE` manuell auf das lokale Subnetz setzen: z.B. `192.168.1.0/24`
|
||||
- Container muss mit `network_mode: host` laufen
|
||||
|
||||
### Kurze Ausfälle werden nicht erkannt
|
||||
|
||||
- `OUTAGE_CHECK_INTERVAL` verringern (z.B. auf `5`)
|
||||
- `OUTAGE_THRESHOLD=1` setzen (sofort beim ersten Fehlschlag)
|
||||
- Ping-Log unter **Ausfälle → Ping-Statistik** zeigt jeden einzelnen Check
|
||||
|
||||
### DB wächst zu schnell
|
||||
|
||||
```bash
|
||||
# Aktuelle Größe
|
||||
du -sh ./data/netmon.db
|
||||
|
||||
# Weniger Pakete cachen
|
||||
# In .env: CAPTURE_MAX_ROWS=10000
|
||||
|
||||
# Daten-Retention verkürzen (in database.py cleanup_old_data aufrufen mit weniger Tagen)
|
||||
```
|
||||
|
||||
### Port 5000 bereits belegt
|
||||
|
||||
```env
|
||||
# In .env
|
||||
WEB_PORT=8080
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*NetMon – gebaut für 24/7-Betrieb auf Linux mit Docker.*
|
||||
Reference in New Issue
Block a user