Files
location-mqtt-tracker-app/MQTT_INTEGRATION.md
2025-11-24 16:30:37 +00:00

560 lines
14 KiB
Markdown

# MQTT Provisioning Integration
Diese Anleitung beschreibt die Integration des MQTT Provisioning Systems (aus `mosquitto-automation`) in die Location Tracker App.
## 🎯 Übersicht
Die Integration vereint zwei vormals separate Systeme:
- **mosquitto-automation**: Device Provisioning und MQTT Credential Management
- **location-tracker-app**: GPS Tracking Visualisierung mit OwnTracks
### Was wurde integriert?
**MQTT Credentials Management** - Direkt im Admin Panel
**ACL (Access Control List) Management** - Feine Kontrolle über Topic-Berechtigungen
**Mosquitto Sync** - Password & ACL Files werden automatisch generiert
**MQTT Subscriber** - Direkte Verarbeitung von OwnTracks Messages (kein n8n mehr nötig)
**Docker Compose Setup** - All-in-One Deployment
---
## 📋 Features
### Admin Panel: MQTT Provisioning
**Route:** `/admin/mqtt`
#### Device Provisioning
- Erstelle MQTT Credentials für registrierte Devices
- Automatische Generierung von Username & Passwort
- Passwörter werden mit `mosquitto_passwd` gehasht
- Default ACL Regel: `owntracks/[device-id]/#` (readwrite)
#### Credentials Management
- Liste aller provisionierten Devices
- Enable/Disable MQTT Zugriff pro Device
- Passwort Regenerierung
- Credentials löschen (inkl. ACL Regeln)
#### ACL Management
- Custom Topic Patterns definieren
- Berechtigungen: `read`, `write`, `readwrite`
- Wildcard Support mit `#`
- Regeln pro Device verwalten
#### Mosquitto Sync
- **"Zu Mosquitto Syncen"** Button im Admin Panel
- Generiert `/mosquitto/config/password.txt`
- Generiert `/mosquitto/config/acl.txt`
- Sendet SIGHUP an Mosquitto Container (Config Reload)
- Zeigt ausstehende Änderungen an
---
## 🗄️ Datenbankschema
### Neue Tabellen
#### `mqtt_credentials`
```sql
CREATE TABLE mqtt_credentials (
id INTEGER PRIMARY KEY AUTOINCREMENT,
device_id TEXT NOT NULL UNIQUE, -- Referenz zu Device Tabelle
mqtt_username TEXT NOT NULL UNIQUE,
mqtt_password_hash TEXT NOT NULL, -- Mosquitto-kompatible Hash
enabled INTEGER DEFAULT 1, -- 0 = disabled, 1 = enabled
created_at TEXT,
updated_at TEXT,
FOREIGN KEY (device_id) REFERENCES Device(id) ON DELETE CASCADE
);
```
#### `mqtt_acl_rules`
```sql
CREATE TABLE mqtt_acl_rules (
id INTEGER PRIMARY KEY AUTOINCREMENT,
device_id TEXT NOT NULL,
topic_pattern TEXT NOT NULL, -- z.B. "owntracks/device10/#"
permission TEXT NOT NULL, -- read | write | readwrite
created_at TEXT,
FOREIGN KEY (device_id) REFERENCES Device(id) ON DELETE CASCADE
);
```
#### `mqtt_sync_status`
```sql
CREATE TABLE mqtt_sync_status (
id INTEGER PRIMARY KEY CHECK (id = 1), -- Singleton
pending_changes INTEGER DEFAULT 0,
last_sync_at TEXT,
last_sync_status TEXT, -- success | error: ...
created_at TEXT,
updated_at TEXT
);
```
### Migration
```bash
# Datenbanken initialisieren
npm run db:init
# MQTT Tabellen hinzufügen
node scripts/add-mqtt-tables.js
```
---
## 🚀 Installation & Setup
### Voraussetzungen
- Docker & Docker Compose
- Node.js 20+ (für lokale Entwicklung)
### 1. Repository Setup
```bash
cd location-tracker-app
# Dependencies installieren
npm install
# .env Datei erstellen
cp .env.example .env
```
### 2. Environment Variables
Bearbeite `.env`:
```env
# MQTT Configuration
MQTT_BROKER_URL=mqtt://mosquitto:1883
MQTT_ADMIN_USERNAME=admin
MQTT_ADMIN_PASSWORD=dein-sicheres-passwort
MOSQUITTO_PASSWORD_FILE=/mosquitto/config/password.txt
MOSQUITTO_ACL_FILE=/mosquitto/config/acl.txt
MOSQUITTO_CONTAINER_NAME=mosquitto
# NextAuth
NEXTAUTH_URL=http://localhost:3000
NEXTAUTH_SECRET=<generiere mit: openssl rand -base64 32>
# Verschlüsselung für SMTP Passwords
ENCRYPTION_KEY=<generiere mit: node -e "console.log(require('crypto').randomBytes(32).toString('hex'))">
```
### 3. Docker Compose Start
```bash
# Build und Start
docker-compose up -d
# Logs verfolgen
docker-compose logs -f
# Status prüfen
docker-compose ps
```
Die App läuft auf: `http://localhost:3000`
Mosquitto MQTT Broker: `mqtt://localhost:1883`
### 4. Admin Zugang
**Default Credentials:**
- Username: `admin`
- Password: `admin123`
⚠️ **Ändere das Passwort nach dem ersten Login!**
---
## 🔧 Entwicklung
### Lokale Entwicklung (ohne Docker)
```bash
# 1. Mosquitto extern starten (oder Docker Compose nur Mosquitto)
docker run -d -p 1883:1883 -p 9001:9001 \
-v $(pwd)/mosquitto.conf:/mosquitto/config/mosquitto.conf \
-v mosquitto_data:/mosquitto/data \
eclipse-mosquitto:2
# 2. .env anpassen
MQTT_BROKER_URL=mqtt://localhost:1883
# 3. Datenbanken initialisieren
npm run db:init
node scripts/add-mqtt-tables.js
# 4. App starten
npm run dev
```
### Neue MQTT Credentials testen
```bash
# Mit mosquitto_sub testen
mosquitto_sub -h localhost -p 1883 \
-u "device_10_abc123" \
-P "dein-generiertes-passwort" \
-t "owntracks/10/#" \
-v
# OwnTracks Message simulieren
mosquitto_pub -h localhost -p 1883 \
-u "device_10_abc123" \
-P "dein-generiertes-passwort" \
-t "owntracks/10/device" \
-m '{"_type":"location","lat":52.5200,"lon":13.4050,"tst":1234567890,"batt":85,"vel":5.2}'
```
---
## 📡 MQTT Subscriber
Der MQTT Subscriber läuft automatisch beim App-Start und verarbeitet OwnTracks Messages.
### Implementierung
- **Service:** `lib/mqtt-subscriber.ts`
- **Startup:** `instrumentation.ts` (Next.js Hook)
- **Topic:** `owntracks/+/+`
- **Datenbank:** Schreibt direkt in `locations.sqlite`
### OwnTracks Message Format
```json
{
"_type": "location",
"tid": "XX",
"lat": 52.5200,
"lon": 13.4050,
"tst": 1234567890,
"batt": 85,
"vel": 5.2,
"acc": 10,
"alt": 50
}
```
### Logs
```bash
# Docker Logs
docker-compose logs -f app
# Du solltest sehen:
# ✓ Connected to MQTT broker
# ✓ Subscribed to owntracks/+/+
# ✓ Location saved: device10 at (52.52, 13.405)
```
---
## 🔐 Sicherheit
### Mosquitto Authentication
- **Keine Anonymous Connections:** `allow_anonymous false`
- **Password File:** Mosquitto-kompatible Hashes (SHA512)
- **ACL File:** Topic-basierte Access Control
### Best Practices
1. **Starke Admin Passwörter:** Ändere `MQTT_ADMIN_PASSWORD` in `.env`
2. **Device Passwörter:** Auto-generierte Passwörter haben 128 Bit Entropie
3. **ACL Regeln:** Gib Devices nur Zugriff auf ihre eigenen Topics
4. **Docker Socket:** Container benötigt Zugriff für Mosquitto Reload (optional)
### ACL Beispiele
```text
# Device darf nur in eigenes Topic schreiben
user device_10_abc123
topic readwrite owntracks/10/#
# Device mit zusätzlichem Read-only Topic
user device_11_xyz789
topic readwrite owntracks/11/#
topic read status/#
# Admin hat vollen Zugriff
user admin
topic readwrite #
```
---
## 🐛 Troubleshooting
### Problem: "Mosquitto configuration reloaded" fehlgeschlagen
**Symptom:** Nach Sync kommt Warnung "Could not reload Mosquitto automatically"
**Lösung:** Docker Socket Zugriff fehlt. Entweder:
```bash
# Option 1: Manuelle Mosquitto Neustart
docker-compose restart mosquitto
# Option 2: Docker Socket in docker-compose.yml freigeben (bereits konfiguriert)
volumes:
- /var/run/docker.sock:/var/run/docker.sock
```
### Problem: MQTT Subscriber verbindet nicht
**Debug Steps:**
```bash
# 1. Prüfe Mosquitto läuft
docker-compose ps mosquitto
# 2. Prüfe Mosquitto Logs
docker-compose logs mosquitto
# 3. Prüfe App Logs
docker-compose logs app | grep MQTT
# 4. Teste MQTT Verbindung manuell
mosquitto_sub -h localhost -p 1883 -u admin -P admin -t '#'
```
### Problem: Password Hash falsch
**Symptom:** Authentication failed im Mosquitto Log
**Lösung:** `mosquitto_passwd` Tool muss im Container verfügbar sein (ist im Dockerfile installiert)
```bash
# Im Container testen
docker exec -it location-tracker-app mosquitto_passwd -h
```
### Problem: ACL Regeln funktionieren nicht
**Debug:**
```bash
# ACL File prüfen
docker exec -it location-tracker-app cat /mosquitto/config/acl.txt
# Mosquitto Logs auf "Access denied" prüfen
docker-compose logs mosquitto | grep -i denied
```
---
## 📊 API Endpoints
### MQTT Credentials
```http
# Liste aller Credentials
GET /api/mqtt/credentials
# Credential für Device abrufen
GET /api/mqtt/credentials/{device_id}
# Neue Credentials erstellen
POST /api/mqtt/credentials
Content-Type: application/json
{
"device_id": "10",
"auto_generate": true
}
# Credentials aktualisieren
PATCH /api/mqtt/credentials/{device_id}
Content-Type: application/json
{
"regenerate_password": true,
"enabled": true
}
# Credentials löschen
DELETE /api/mqtt/credentials/{device_id}
```
### ACL Rules
```http
# ACL Regeln für Device
GET /api/mqtt/acl?device_id=10
# Neue ACL Regel erstellen
POST /api/mqtt/acl
Content-Type: application/json
{
"device_id": "10",
"topic_pattern": "owntracks/10/#",
"permission": "readwrite"
}
# ACL Regel löschen
DELETE /api/mqtt/acl/{rule_id}
```
### Mosquitto Sync
```http
# Sync Status abrufen
GET /api/mqtt/sync
# Sync triggern
POST /api/mqtt/sync
```
Alle Endpoints erfordern Admin-Authentifizierung (Role: ADMIN).
---
## 🔄 Migration von mosquitto-automation
Wenn du bereits Devices in `mosquitto-automation` hast:
### Automatische Migration (TODO)
```bash
# Script erstellen das aus der alten DB liest
node scripts/migrate-from-mosquitto-automation.js \
--old-db /pfad/zu/mosquitto-automation/data/devices.db
```
### Manuelle Migration
1. Exportiere Devices aus alter DB:
```sql
SELECT id, name, username, password_hash, permissions
FROM devices
WHERE active = 1;
```
2. Erstelle Devices im neuen System über Admin Panel
3. Provisioniere MQTT Credentials manuell
4. Importiere ACL Regeln
---
## 📚 Architektur
### Komponenten
```
┌─────────────────────────────────────────────────────┐
│ Location Tracker App (Next.js) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────┐ │
│ │ Admin Panel │ │ MQTT Service │ │ API │ │
│ │ /admin/mqtt │ │ Subscriber │ │ Routes │ │
│ └──────────────┘ └──────────────┘ └──────────┘ │
│ │ │ │ │
│ └──────────────────┴────────────────┘ │
│ │ │
│ ┌────▼────┐ │
│ │ SQLite │ │
│ │ DB │ │
│ └────┬────┘ │
│ │ │
│ ┌────▼────────┐ │
│ │ Mosquitto │ │
│ │ Sync Service│ │
│ └────┬────────┘ │
└─────────────────────────┼──────────────────────────┘
┌───────────▼───────────┐
│ Mosquitto Broker │
│ │
│ • password.txt │
│ • acl.txt │
└───────────┬───────────┘
┌───────────▼───────────┐
│ GPS Tracking │
│ Devices │
│ (OwnTracks) │
└───────────────────────┘
```
### Datei-Struktur
```
location-tracker-app/
├── app/
│ ├── admin/
│ │ └── mqtt/
│ │ └── page.tsx # MQTT Provisioning UI
│ └── api/
│ └── mqtt/
│ ├── credentials/ # Credentials Management
│ ├── acl/ # ACL Management
│ └── sync/ # Mosquitto Sync
├── lib/
│ ├── mqtt-db.ts # MQTT Datenbank Operations
│ ├── mqtt-subscriber.ts # MQTT Message Processing
│ ├── mosquitto-sync.ts # Config File Generation
│ └── startup.ts # Service Initialization
├── scripts/
│ └── add-mqtt-tables.js # Datenbank Migration
├── docker-compose.yml # Docker Setup
├── Dockerfile # App Container
├── mosquitto.conf # Mosquitto Config
└── instrumentation.ts # Next.js Startup Hook
```
---
## ✨ Vorteile der Integration
### Vorher (Separate Systeme)
```
GPS Device → MQTT → n8n → HTTP API → location-tracker-app → UI
mosquitto-automation (separate)
```
**Probleme:**
- n8n als zusätzliche Dependency
- Zwei separate Admin Panels
- Keine zentrale User/Device Verwaltung
- Komplexes Setup
### Nachher (Integriert)
```
GPS Device → MQTT → location-tracker-app → UI
(integriertes Provisioning)
```
**Vorteile:**
✅ Ein Admin Panel für alles
✅ Direkte MQTT Verarbeitung (schneller)
✅ Einfaches Docker Compose Setup
✅ Zentrale Datenbank
✅ Weniger Dependencies
---
## 🎉 Fertig!
Die Integration ist komplett. Du kannst jetzt:
1. **Devices verwalten** unter `/admin/devices`
2. **MQTT Credentials provisionieren** unter `/admin/mqtt`
3. **ACL Regeln definieren** im MQTT Panel
4. **Zu Mosquitto syncen** mit einem Klick
5. **GPS Tracking visualisieren** auf der Hauptseite
Bei Fragen oder Problemen: Siehe Troubleshooting oder check die Logs.
Happy Tracking! 🚀📍