rebreak-monorepo/ops/mdm/profiles/rebreak-iphone-protection.mobileconfig
chahinebrini 8f2ef2cc98 feat(mdm,vip): MDM-VPN-Pivot + Layer-2-Country-Curated + Custom-Domain-Refactor
MDM-VPN-Pivot (Phase F.2 done):
- ops/mdm/profiles/rebreak-iphone-protection.mobileconfig auf v5 mit
  com.apple.vpn.managed Payload + OnDemandUserOverrideDisabled. iPhone-User
  kann ReBreak-VPN-Profile nicht entfernen und "Bedarf verbinden"-Toggle
  ist disabled. allowEnablingRestrictions empirisch widerlegt für FC-Toggle-
  Lock — out.
- DEV-removable Variante als Test-Profile dazu.
- Bootstrap-Tool (rebreak-supervise.sh) + Supervision-Identity-Setup-Doc.
- PHASES.md updated mit empirischen Befunden.

App-side MDM-Detect (Pfad-a Banner-Logic):
- modules/rebreak-protection: getDeviceState() returnt mdmManaged via
  Heuristik NETunnelProviderManager.count > 1 (App selbst kann nur einen
  eigenen erstellen, MDM-Push fügt einen zweiten hinzu).
- DeviceLayers.mdmManaged?: boolean Type.
- blocker.tsx: lockedIn-Bedingung erweitert um mdmManaged. Bei MDM-managed
  iPhones wird der App-Lock-Card (FC-Authorization-Toggle UI) ausgeblendet
  weil der per-App FC-Toggle nicht lockbar ist und durch den MDM-VPN-Layer
  redundant.

Layer-2-Country-Curated-Pivot:
- backend: vip-swap.post.ts raus, suggest.post.ts rein. Curated-domains
  durch admin (separate Tabelle/Pfad), getrennt von User-Custom-Domains.
- Admin-APIs für curated-domain Pflege (index.get + [id].patch).
- seed-country-blocklists Script für initiale Curated-Domain-Liste.
- protection/webcontent-domains.get refactored für Country-Curated-Pfad.
- Migration drop_vip_swap_fields.sql + schema.prisma adjusted.
- docs/concepts/layer2-country-pivot.md mit Architektur + Decision-Trail.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 07:11:47 +02:00

233 lines
12 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<!--
ReBreak iPhone Protection Profile
---------------------------------
Scope (2026-05-25, Phase F.2 — NEFilter+MDM-Pivot):
1. Rebreak (und andere Apps) nicht entfernbar → Restrictions.allowAppRemoval=false
2. Profil selbst nicht entfernbar → PayloadRemovalDisallowed=true
3. System-DNS auf dns.rebreak.org locken → com.apple.dnsSettings.managed (DoH)
4. Anti-Tampering → allowEraseContentAndSettings=false,
allowUIConfigurationProfileInstallation=false
5. ReBreak-VPN als Managed-VPN pushed → com.apple.vpn.managed
→ ProviderBundleIdentifier =
org.rebreak.app.PacketTunnelExtension
→ Profile non-removable durch MDM
→ User kann VPN-Toggle in Settings nicht aus
Architektur (Pivot 2026-05-25):
Der Per-App-Family-Controls-Authorization-Toggle ist via Standard-Apple-MDM nicht
lockbar (dokumentierte security gap). Statt diesen Arms-Race zu spielen pushen wir
ReBreak-VPN selbst via MDM — damit ist das VPN-Profile non-removable und der User
kann den Filter nicht abschalten. App-seitig wird MDM-Präsenz detected und der
Protection-Layer dynamisch gewählt:
- MDM präsent: PacketTunnel (NEFilter-Path) bleibt always-on via Managed-VPN
- kein MDM: bisheriger VPN-DNS-Filter wie gehabt (user-toggleable)
Bypass-Vektor: 3rd-Party-VPN (ExpressVPN) bleibt installierbar, akzeptiert für DiGA-Pilot.
Voraussetzungen am Gerät:
- Supervised-Mode aktiv (sonst greifen allowAppRemoval / PayloadRemovalDisallowed NICHT)
- iOS 14+ (DNS-Settings-Payload erfordert iOS 14)
- ReBreak-App mit PacketTunnel-Extension installed BEVOR Profile-Install
(sonst kann iOS den ProviderBundleIdentifier nicht auflösen)
Apple-Referenzen:
- Restrictions: https://developer.apple.com/documentation/devicemanagement/restrictions
- DNS Settings: https://developer.apple.com/documentation/devicemanagement/dnssettings
- VPN-Managed: https://github.com/apple/device-management/blob/release/mdm/profiles/com.apple.vpn.managed.yaml
- Profile Format: https://developer.apple.com/documentation/devicemanagement/toplevel
Stand: 2026-05-25, Profile-Version 2 (VPN-Managed-Payload hinzugefügt)
-->
<plist version="1.0">
<dict>
<key>PayloadType</key>
<string>Configuration</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadIdentifier</key>
<string>org.rebreak.protection.iphone.20260525</string>
<key>PayloadUUID</key>
<string>A1B2C3D8-E5F6-4789-ABCD-EF1234567894</string>
<key>PayloadDisplayName</key>
<string>ReBreak Schutz</string>
<key>PayloadDescription</key>
<string>Schützt dich vor Glücksspiel-Rückfall: Rebreak nicht entfernbar, DNS-Filter auf dns.rebreak.org gelocked, VPN-Toggle deaktiviert. Profil kann nicht selbst entfernt werden — Notfall-Entfernung via deinem Trustee.</string>
<key>PayloadOrganization</key>
<string>ReBreak</string>
<key>PayloadRemovalDisallowed</key>
<true/>
<key>ConsentText</key>
<dict>
<key>default</key>
<string>Du installierst hiermit das ReBreak-Schutz-Profil. Dieses Profil bindet dich freiwillig an folgende Einschränkungen:
• Apps können während des Schutzes nicht über Long-Press gelöscht werden
• Das ReBreak-VPN kann nicht in den iPhone-Einstellungen deaktiviert werden
• System-DNS-Anfragen laufen über dns.rebreak.org (verschlüsselt via DoH)
• Du kannst dieses Profil nicht selbst entfernen
Das ist gewollt. Der Schutz wirkt, weil er gegen deine impulsive Selbst-Override-Tendenz steht. Die Entfernung läuft über deinen Trustee oder deinen 7-Tage-Cooldown in der App.
Bei Verlust deines iPhones: das Profil verschwindet mit Factory-Reset, das ist normal.</string>
</dict>
<key>PayloadContent</key>
<array>
<!-- ===================================================================
1) RESTRICTIONS-PAYLOAD
Supervised-only Restrictions: blockt App-Removal + VPN-User-Eingriffe
=================================================================== -->
<dict>
<key>PayloadType</key>
<string>com.apple.applicationaccess</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadIdentifier</key>
<string>org.rebreak.protection.iphone.restrictions</string>
<key>PayloadUUID</key>
<string>B3234567-ABCD-4F01-9345-67890ABCDEF6</string>
<key>PayloadDisplayName</key>
<string>ReBreak Restrictions</string>
<key>PayloadDescription</key>
<string>Verhindert App-Löschung und VPN-Eingriffe.</string>
<!-- App-Removal komplett blocken (supervised only)
Per-Bundle-ID-Lock wäre chirurgischer, erfordert aber MDM-managed-Convert
via separatem InstallApplication-Command. Akzeptierter Trade-off für Prototype:
alle Apps sind während Schutz nicht löschbar. Für Self-Binding gewünscht.
User-Verhalten-Test 2026-05-24: zeigt "Vom Home-Screen entfernen" statt
"App löschen" — User kann App in Mediathek verschieben, nicht deinstallieren. -->
<key>allowAppRemoval</key>
<false/>
<!-- Verhindert dass User per Erase-All-Content-and-Settings entkommt
(supervised only). Bewusst gesetzt: Wipe ist Trustee-/Cooldown-Pfad. -->
<key>allowEraseContentAndSettings</key>
<false/>
<!-- Schutz vor Profil-Install-Bypass: User kann keine konkurrierenden
Konfigurationsprofile installieren die unsere Restrictions overriden -->
<key>allowUIConfigurationProfileInstallation</key>
<false/>
<!-- 2026-05-25 empirisch getestet: allowEnablingRestrictions=false
deaktiviert zwar die Bildschirmzeit-Setup-Page komplett, hat
aber KEINEN Effekt auf den per-App "Apps mit Zugriff auf
Bildschirmzeit"-Toggle (FC-Authorization). Apple unterscheidet
die beiden Permission-Systeme.
→ Rollback, FC-Toggle wird via App-Code-Bypass (MDM-Detect)
geregelt statt via MDM-Restriction.
→ ManagedSettings-API bleibt damit für die App weiter verfügbar. -->
</dict>
<!-- ===================================================================
2) DNS-SETTINGS-PAYLOAD
Lockt System-DNS auf unseren DoH-Endpoint
Belt+Suspenders zur VPN-Schicht: greift auch wenn VPN aus irgend-
einem Grund nicht aktiv ist
=================================================================== -->
<dict>
<key>PayloadType</key>
<string>com.apple.dnsSettings.managed</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadIdentifier</key>
<string>org.rebreak.protection.iphone.dns</string>
<key>PayloadUUID</key>
<string>C1234567-ABCD-4F01-9345-67890ABCDEF2</string>
<key>PayloadDisplayName</key>
<string>ReBreak DNS-Filter</string>
<key>PayloadDescription</key>
<string>Leitet alle DNS-Anfragen verschlüsselt über dns.rebreak.org. Glücksspiel-Domains werden blockiert.</string>
<key>DNSSettings</key>
<dict>
<key>DNSProtocol</key>
<string>HTTPS</string>
<key>ServerURL</key>
<string>https://dns.rebreak.org/dns-query</string>
</dict>
</dict>
<!-- ===================================================================
3) VPN-MANAGED-PAYLOAD (Phase F.2 — NEFilter+MDM-Pivot 2026-05-25)
Pushed ReBreak's eigenen NEPacketTunnelProvider als MDM-Managed-VPN.
Effekt: VPN-Profile non-removable via Settings → User kann den
Filter nicht abschalten. ReBreak-App's eigene NEVPNManager-Aufrufe
überschreiben diese Config nicht (MDM-managed wins).
Voraussetzung: ReBreak-App MIT PacketTunnel-Extension muss installed
sein BEVOR dieses Profile gepushed wird (sonst kann iOS den
ProviderBundleIdentifier nicht auflösen → InstallProfile-Fail).
=================================================================== -->
<dict>
<key>PayloadType</key>
<string>com.apple.vpn.managed</string>
<key>PayloadVersion</key>
<integer>1</integer>
<key>PayloadIdentifier</key>
<string>org.rebreak.protection.iphone.vpn</string>
<key>PayloadUUID</key>
<string>D2234567-ABCD-4F01-9345-67890ABCDEF4</string>
<key>PayloadDisplayName</key>
<string>ReBreak Schutz-VPN</string>
<key>PayloadDescription</key>
<string>Aktiviert den ReBreak-DNS-Filter als nicht-abschaltbaren VPN. Verhindert dass du dich impulsiv selbst aussperrst-vom-Schutz.</string>
<key>UserDefinedName</key>
<string>ReBreak Schutz</string>
<key>VPNType</key>
<string>VPN</string>
<!-- VPNSubType + VPN.ProviderBundleIdentifier referenzieren die
Extension im ReBreak-App-Bundle. iOS findet den Provider via
diesem Bundle-ID und ruft den ReBreak-PacketTunnel auf. -->
<key>VPNSubType</key>
<string>org.rebreak.app.PacketTunnelExtension</string>
<key>VPN</key>
<dict>
<!-- RemoteAddress ist Pflichtfeld, hat aber bei lokal-only
PacketTunnel keine echte Funktion. Muss mit App-Code
übereinstimmen (RebreakProtectionModule.swift:1225). -->
<key>RemoteAddress</key>
<string>ReBreak DNS-Filter (lokal)</string>
<key>AuthenticationMethod</key>
<string>Password</string>
<key>ProviderBundleIdentifier</key>
<string>org.rebreak.app.PacketTunnelExtension</string>
<key>ProviderType</key>
<string>packet-tunnel</string>
<key>DisconnectOnIdle</key>
<integer>0</integer>
<!-- OnDemand-User-Override blocken: "Bedarf verbinden"-Toggle in
Settings → VPN → ReBreak Schutz wird disabled (grau).
Apple-Schema-Doku: "If 1, the Connect On Demand toggle in
Settings is disabled for this configuration." iOS 14+ -->
<key>OnDemandUserOverrideDisabled</key>
<true/>
</dict>
<!-- Empty VendorConfig — Apple-Schema erlaubt das, ReBreak-Extension
liest providerConfiguration nicht (Blocklist kommt aus AppGroup). -->
<key>VendorConfig</key>
<dict/>
<!-- On-Demand: VPN startet automatisch bei jedem Netzwerk-Connect.
Kombiniert mit MDM-non-removable + OnDemandUserOverrideDisabled
= always-on Schutz, User kann nicht abschalten. -->
<key>OnDemandEnabled</key>
<integer>1</integer>
<key>OnDemandRules</key>
<array>
<dict>
<key>Action</key>
<string>Connect</string>
</dict>
</array>
</dict>
</array>
</dict>
</plist>