# MDM Server — Technische Architektur ## Server - **Hostname:** rebreak-mdm - **IP:** 178.105.101.137 - **Provider:** Hetzner Cloud - **OS:** Ubuntu 24.04 - **SSH:** `ssh rebreak-mdm` (via ~/.ssh/config Alias) ## DNS - **Domain:** mdm.rebreak.org - **Registrar:** IONOS - **Record:** A-Record, 178.105.101.137 - **TTL:** Standard (300-3600s) ## Stack-Komponenten ### nginx (System-Service) - Version: nginx/1.24.0 - Port 80: HTTP-zu-HTTPS-Redirect (301) - Port 443: SSL/TLS mit HTTP/2, reverse proxy zu nanomdm - Config: `/etc/nginx/sites-available/mdm.rebreak.org` (symlinked in sites-enabled) - TLS: Let's Encrypt via certbot, auto-renewal via systemd-Timer ### NanoMDM (Docker-Container) - Image: `ghcr.io/micromdm/nanomdm:latest` (v0.9.0 zum Zeitpunkt Setup) - Container-Name: `nanomdm` - Compose-File: `/opt/nanomdm/docker-compose.yml` - Netzwerk-Mode: `host` (kein Bridge-Netzwerk — direkter Zugriff auf localhost:5432) - Lauscht: `127.0.0.1:9000` (nur localhost, nginx proxiet) - Restart-Policy: `unless-stopped` - Volumes: - `/opt/nanomdm/certs:/certs:ro` (CA-cert + Push-cert) - `nanomdm-data:/data` (Docker-Volume) ### PostgreSQL (System-Service) - Version: PostgreSQL 16 - Socket: `127.0.0.1:5432` (localhost only) - Datenbank: `nanomdm` - User: `nanomdm` - Passwort: in `/root/.nanomdm_db_pass` (chmod 600) - pg_hba: scram-sha-256 für localhost + 172.17.0.0/16 + 172.18.0.0/16 (Docker-Netze) ### Certbot (System-Service) - Cert-Pfad: `/etc/letsencrypt/live/mdm.rebreak.org/` - Auto-Renewal: systemd-Timer (certbot.timer), prüft 2x täglich - Renewal: nginx-Reload nach Renewal via Hook ## Port-Übersicht | Port | Bind | Service | Beschreibung | |------|--------------|-----------|------------------------------------| | 80 | 0.0.0.0 | nginx | HTTP → HTTPS redirect | | 443 | 0.0.0.0 | nginx | HTTPS, TLS termination, MDM-proxy | | 9000 | 127.0.0.1 | nanomdm | MDM-Protokoll (intern only) | | 5432 | 127.0.0.1 | postgres | DB (intern only) | | 22 | 0.0.0.0 | sshd | Admin-SSH | UFW-Regeln: 22/tcp, 80/tcp, 443/tcp erlaubt. Alles andere denied by default. ## Zertifikat-Pfade | Datei | Inhalt | Permissions | |------------------------------------|---------------------|-------------| | `/opt/nanomdm/certs/ca.crt` | MDM CA (self-signed)| 644 | | `/opt/nanomdm/certs/ca.key` | MDM CA Private Key | 600 | | `/opt/nanomdm/certs/push.csr` | Apple Push CSR | 644 | | `/opt/nanomdm/certs/push.key` | Apple Push Priv-Key | 600 | | `/opt/nanomdm/certs/push.pem` | Apple Push Cert (*) | 600 geplant | | `/root/.nanomdm_db_pass` | Postgres-Passwort | 600 | (*) `push.pem` existiert noch nicht — warte auf Apple-Portal-Upload (Phase D.1) ## Apple Push Zertifikat — Ablauf Apple-Geräte erhalten MDM-Befehle via Apple Push Notification Service (APNS). Dafür braucht NanoMDM ein von Apple signiertes Push-Zertifikat. Ablauf (einmal jährlich zu erneuern): ``` 1. Server generiert push.key + push.csr (einmalig, Key bleibt gleich bei Renewal) 2. Admin lädt push.csr auf identity.apple.com/pushcert hoch 3. Apple signiert und stellt push.pem aus (Download) 4. push.pem wird auf Server kopiert: /opt/nanomdm/certs/push.pem 5. nanomdm via -apns-cert oder Umgebungsvariable konfigurieren 6. docker compose restart nanomdm ``` Wichtig: Bei Renewal (jährlich) den GLEICHEN push.key verwenden. Wenn ein neuer Key generiert wird, müssen alle enrollten Geräte re-enrollen. ## Trust-Modell ``` Chahine (Device-Owner) - enrolled freiwillig - hat KEINEN MDM-Admin-Zugriff - kann Profil NICHT selbst entfernen Olfa (Co-Admin) - hat SSH-Zugriff auf rebreak-mdm - kennt MDM-Admin-API-Key (nach Phase E generiert) - kann Profil entfernen via nanomdm API Ina Wittek (Trustee, ina.wittek@gmx.de) - bekommt Notfall-Credentials per Email (Phase E) - kann Profil entfernen wenn weder Chahine noch Olfa erreichbar - hat kein Server-Zugriff, nur Credentials für nanomdm-Endpoint ``` ## Recovery-Szenarien | Szenario | Lösung | |-----------------------------------|-------------------------------------------------------------| | Profil-Entfernung nötig | Olfa oder Ina nutzen MDM-API oder nanomdm-UI | | Server down | `ssh rebreak-mdm` → `docker compose -f /opt/nanomdm/docker-compose.yml up -d` | | Apple Push Cert abgelaufen | Neues Push Cert via identity.apple.com, gleicher push.key | | DB korrupt | Backup einspielen (pg_dump), dann nanomdm restart | | Server kompromittiert | Apple Push Cert revoken auf identity.apple.com, neuer Server, neues Enrollment | | Device verloren (gestohlen) | MDM-remote-wipe triggern (löscht Gerät), nicht MDM-Profil | | Factory-Reset vom User | Nuclear option: alle Daten weg, aber MDM-Profil auch weg. Dann re-enroll. |