rebreak-monorepo/ops/mdm/ARCHITECTURE.md
chahinebrini 5d6c322129 wip: KeyboardAwareSheet migrations + Snake/Tetris UI + iron.png + useMe live-update
Sheets via neuer KeyboardAwareSheet-Composable (in Modal pattern, auto-grow
mit Tastatur, paddingBottom-Lift): EditMail, AddDomain, CreateRoom, ConnectMail.
GameOverScreen behält Spring-Slide-In, nutzt RN Keyboard.addListener für Lift.

- KeyboardAwareSheet.tsx — universal modal with sheet-grow + keyboard-padding
- react-native-keyboard-controller installiert + KeyboardProvider in Root
- Snake: time + ScoreProgressBar + useSnakeSounds (haptic, audio TODO)
- Tetris: title weg, Buttons zentriert, kein Pressable mit style-fn
- DPad-Buttons 60→48, more bg, no scale
- useMe: pub-sub listener pattern für app-weite avatar/nickname-Updates
- dm.tsx: resolveAvatar wrap (iron.png-Warning)
- Mail-error-humanizer + locales

Recovery-Doc-Update in docs/internal/RECOVERY_LOG_2026-05-10.md

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 23:59:25 +02:00

5.0 KiB

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-mdmdocker 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.