macOS unter Docker mit QEMU ausführen
(github.com/sickcodes)- Docker-OSX führt macOS auf Basis von QEMU + KVM in einem Docker-Container aus und bietet X11-Ausgabe, SSH, VNC, iPhone-USB-Anbindung sowie die Generierung von Seriennummern für iMessage-Sicherheitsforschung
- Die Ausführung funktioniert, indem das
/dev/kvm-Device, der X11-Socket, Port-Forwarding und die UmgebungsvariableSHORTNAMEzur Auswahl der macOS-Version an Docker übergeben werden; Beispiele reichen von Catalina 10.15 bis Tahoe 16 - Die Images sind je nach Zweck in Varianten wie
latest,auto,nakedundnaked-autoaufgeteilt; man kann eigene.img-Dateien einbinden oder mit einem vorkonfigurierten Catalina-Image Kommandozeilenaufgaben ausführen - Voraussetzung sind ein x86_64-Host mit KVM-Unterstützung, aktivierte Virtualisierung im BIOS und mindestens 20 GB freier Speicherplatz; für Xcode werden 50 GB benötigt, bei
:automindestens 50 GB - Neben Linux ist die Ausführung auch mit verschachtelter Virtualisierung in WSL2 unter Windows 11 build 22000+ möglich; für die Bildschirmausgabe muss jedoch WSLg, VNC oder eine Desktop-Umgebung eingerichtet werden
macOS in einem Docker-Container ausführen
- Docker-OSX ist ein Projekt, das macOS in einem Docker-Container ausführt
- Läuft auf QEMU + KVM
- Unterstützt X11-Forwarding
- Bietet eine Konfiguration, mit der iPhone-USB funktioniert
- Es wird darauf hingewiesen, dass damit macOS-Sicherheitsforschung unter Linux und Windows möglich ist
- Das Projekt basiert auf OSX-KVM und erwähnt außerdem KVM-OpenCore sowie OpenCorePkg
- Auch ein Docker-Hub-Image ist verfügbar: sickcodes/docker-osx
Unterstützte macOS-Versionen und Schnellstart
- Der Quick Start übergibt bei
docker rundie folgenden Elemente--device /dev/kvm-p 50922:10022für SSH- Das Volume
/tmp/.X11-unixfür X11 DISPLAYSHORTNAMEzur Auswahl der macOS-Version
- Die im README enthaltenen Zielversionen sind folgende
-
High Sierra 10.13
-
Mojave 10.14
-
Catalina 10.15
-
Big Sur 11
-
Monterey 12
-
Ventura 13
-
Sonoma 14
-
Sequoia 15
- Tahoe 16
- Einige Beispiele ab Monterey verwenden zusätzlich
GENERATE_UNIQUE=truezusammen mitMASTER_PLIST_URL - Die Beispiele für Sonoma, Sequoia und Tahoe enthalten außerdem
CPU='Haswell-noTSX'undCPUID_FLAGS
-
Image-Typen und Einsatzzwecke
- Docker-OSX stellt Container-Images für verschiedene Zwecke bereit
sickcodes/docker-osx:latest: Zum schnellen Ausprobieren oder zum Erstellen eines eigenen macOS-Imagessickcodes/docker-osx:auto: Nutzt ein vorkonfiguriertes Catalina-System; Benutzername istuser, Passwort istalpinesickcodes/docker-osx:naked: Zum Starten mit einer eigenen.img-Dateisickcodes/docker-osx:naked-auto: ÜbergibtUSERNAME,PASSWORDundOSX_COMMANDSan ein Benutzer-Image, um SSH und Befehlsausführung zu automatisierensickcodes/docker-osx:big-sur,:monterey,:ventura,:sonoma,:high-sierra,:mojave: Zum Ausführen bestimmter Versionen
- Das
naked-Image ist auf Workflows ausgelegt, bei denen vorhandene Disk-Images wiederholt gebootet oder Container in einen früheren Zustand zurückversetzt werden autoundnaked-autokönnen für kommandozeilenorientierte Aufgaben oder Headless-Workloads wie Homebrew-basierte Builds genutzt werden
Wichtige Funktionen
- Docker-OSX nennt die folgenden Funktionen
- Nutzung von iPhone OSX KVM unter Linux mit usbfluxd
- Ausführen einer macOS-Monterey-VM
- Ordnerfreigabe
- USB-Passthrough und Hotplug
- Aktiviertes SSH:
localhost:50922 - Aktiviertes VNC:
localhost:8888bei Verwendung der Version./vnc - iMessage-Sicherheitsforschung über den serial number generator
- X11-Forwarding
- Unterstützung für Big Sur, Custom Images und Xvfb-Headless-Modus
- Container können mit
docker commitgeklont werden
- Kubernetes wird ebenfalls unterstützt; Helm Chart und Dokumentation befinden sich laut Hinweis im Verzeichnis
helm
Anforderungen und Ersteinrichtung
- Die Mindestanforderungen sind folgende
- 20 GB oder mehr Speicherplatz
- 50 GB bei Verwendung von Xcode
- Mindestens 50 GB bei Verwendung von
:auto - Aktivierte Virtualisierung im BIOS
- x86_64-Host mit KVM-Unterstützung
- Die Ersteinrichtung besteht daraus, QEMU und zugehörige Abhängigkeiten auf dem Host zu installieren und anschließend
libvirtd,virtlogdsowie KVM-Kernelmodule zu aktivieren - Für Arch, Ubuntu/Debian und CentOS/RHEL/Fedora werden jeweils Paketinstallationsbefehle bereitgestellt
- In manchen Fällen muss der Benutzer Mitglied der Gruppen Docker, KVM und libvirt sein; außerdem sollte geprüft werden, ob der Docker-Daemon läuft
Voraussetzungen für Windows
- Docker-OSX kann unter Windows in einer Windows-11-+-WSL2-Umgebung ausgeführt werden
- Erforderlich sind Windows 11 build 22000+ und 21H2 oder neuer
- Nach der WSL-Installation wird
nestedVirtualization=truezu.wslconfighinzugefügt - In der WSL-Distribution wird mit
kvm-okgeprüft, ob/dev/kvmund KVM-Beschleunigung verfügbar sind - In Docker for Windows müssen die WSL2-basierte Engine und die Integration der Standard-WSL-Distribution aktiviert werden
- Für die Bildschirmausgabe gibt es drei Wege
- WSLg: Die einfachste und empfohlene Option, es kann jedoch Probleme mit Tastaturweitergabe oder der Anzeige eines zweiten Mauszeigers geben
- VNC: Nutzung von QEMU VNC oder der Konfiguration aus dem VNC-Abschnitt
- Desktop Environment: Benötigt mehr Ressourcen, bietet aber eine vollständige Linux-Desktop-Erfahrung
Dateifreigabe und Festplattenbetrieb
- Als einfachste und sicherste Freigabemethode wird
sshfsgenannt- Unter Linux/Windows wird das macOS-rootfs mit
sshfs user@localhost: -p 50922 ~/mnt/osxim Userspace gemountet
- Unter Linux/Windows wird das macOS-rootfs mit
- Auch QEMU-9p-Freigaben sind möglich
- Ein Host-Ordner wird als
/mnt/hostsharean den Container übergeben - Innerhalb von macOS wird er mit
sudo -S mount_9p hostsharegemountet
- Ein Host-Ordner wird als
- Auch NFS-Freigaben werden beschrieben
- Das freizugebende Verzeichnis wird in
/etc/exportsdes Hosts eingetragen - Der Docker-OSX-Container wird mit
--network hostgestartet - Im macOS-Terminal wird
mount_nfsverwendet
- Das freizugebende Verzeichnis wird in
- Wenn der Docker-Speicherplatz knapp wird, kann
/var/lib/dockerauf ein externes Laufwerk, Block Storage, NFS oder Ähnliches verschoben und anschließend per symbolischem Link eingebunden werden- Es wird darauf hingewiesen, entsprechenden Tutorials nur zu folgen, wenn man das mögliche Löschen aktueller Docker-Images und Layer in Kauf nimmt
iPhone-USB und USB-Passthrough
- Für Desktop-PCs wird separat auf eine VFIO-basierte Methode für iPhone-USB-Passthrough verwiesen
- Auf Laptops, PCs und ähnlichen Systemen kann netzwerkbasiertes USB-Passthrough mit usbfluxd verwendet werden
- Ein iPhone oder iPad wird unter Linux per USB angeschlossen
usbmuxdwird über den TCP-Port5000bereitgestellt- Im macOS-Gast verbindet sich
usbfluxd -f -r 172.17.0.1:5000mit dem Host - Es wird darauf hingewiesen, dass das Gerät erscheint, wenn man Apps wie Xcode schließt und erneut öffnet
- Für allgemeines USB-Passthrough muss QEMU laut Hinweis als root gestartet werden
- Bus und Port werden mit
lsusb -tgeprüft - Verwendet werden unter anderem
--privileged,/dev/kvmundEXTRA="-device ... usb-host ..." - Während die VM läuft, kann das Host-System nicht auf das betreffende USB-Gerät zugreifen
- Bus und Port werden mit
Headless, VNC, SPICE und Remote-Ausführung
- Für Headless-Ausführung werden bei
docker rundie zwei X11-bezogenen Zeilen entfernt- Das Volume
/tmp/.X11-unixentfernen - Die Umgebungsvariable
DISPLAYentfernen
- Das Volume
- Headless-Container auf Basis von Custom Images sind laut Hinweis nützlich für CI/CD-Pipelines
- VNC kann lokal genutzt werden, das README stellt jedoch klar, dass keinerlei TLS/HTTPS-Verschlüsselung vorhanden ist
- Mit einem SSH-Tunnel und geschlossenen externen Ports sei die Nutzung sicher
- Auch SPICE kann verwendet werden
- Verbindung mit
remote-viewer spice://localhost:3001 -disable-ticketingim Beispiel erlaubt VM-Zugriff ohne Authentifizierung; für Authentifizierungseinstellungen soll das SPICE-Handbuch herangezogen werden
- Verbindung mit
Seriennummern und iMessage/iCloud-Forschung
- Für die Nutzung von iMessage oder iCloud werden die folgenden zu ändernden Werte genannt
SERIALBOARD_SERIALUUIDMAC_ADDRESSROMwird als MAC-Adresse in Kleinbuchstaben ohne Doppelpunkte beschrieben
- Docker-OSX bietet zwei Methoden
GENERATE_UNIQUE=true: Erzeugt zur Laufzeit eindeutige WerteGENERATE_SPECIFIC=true: Verwendet angegebene Werte
./custom/generate-unique-machine-values.shkann Seriennummern, MAC-Adressen, CSV/TSV-Ausgaben und Bootdisk-Images erzeugen- Mit
ioreg -l | grep IOPlatformSerialNumberlässt sich die Seriennummer innerhalb von macOS prüfen
Performance, Auflösung und Netzwerkeinstellungen
- Laut Hinweis kann osx-optimizer verwendet werden, um den Container schneller zu machen
- GUI-Anmeldebildschirm überspringen
- Spotlight-Indizierung deaktivieren
- Aufwendigen Hintergrund des Login-Bildschirms deaktivieren
- Updates deaktivieren
- Die Auflösung kann über die Umgebungsvariablen
WIDTHundHEIGHTgeändert werden- Muss zusammen mit
GENERATE_UNIQUE=trueoderGENERATE_SPECIFIC=trueverwendet werden - Das Booten dauert etwa 30 Sekunden länger, weil eine neue Boot-Partition erstellt wird
- Ungültige Auflösungen werden standardmäßig auf
800x600gesetzt
- Muss zusammen mit
- Der Netzwerkadapter kann per Umgebungsvariable geändert werden
- Schnelle Internetverbindung:
NETWORKING=vmxnet3 - Langsame Internetverbindung:
NETWORKING=e1000-82545em
- Schnelle Internetverbindung:
- Bei Remote-Installationen kann das Aktivieren von IPv4-Forwarding die Leistung verbessern; es wird jedoch darauf hingewiesen, dass die Host-IP auch dann durchsickern kann, wenn im Container ein VPN genutzt wird
Fehlerbehebung und Einschränkungen
- Wenn der Docker-Daemon nicht läuft, kann der Fehler
docker: unknown server OS: .auftretensudo dockerdsudo systemctl --start dockerdsudo systemctl --enable --now dockerd
- Es kann nicht mehr RAM zugewiesen werden, als die physische Maschine besitzt
- Standardwert ist
-e RAM=3 - Bei Überbelegung kann der Fehler
cannot set up guest memory 'pc.ram': Cannot allocate memoryauftreten
- Standardwert ist
- ALSA-bezogene Fehler können während der Container-Initialisierung oder beim Booten auftreten; wenn Bootvorgang und Funktionen normal sind, muss man sich laut Hinweis keine Sorgen machen
- In der TODO-Liste verbleiben folgende Punkte
- Dokumentation für Sicherheitsforscher
- GPU-Beschleunigung
- Unterstützung für virt-manager
Lizenz und Hinweise
- Docker-OSX ist unter GPL v3+ lizenziert
- Es wird ausdrücklich angegeben, dass die Nutzung von Docker-OSX als Werkzeug zur Erstellung proprietärer Software erlaubt ist
- Es enthält Hinweise zur Apple-Sicherheitsforschung und zum Apple Bug Bounty Program sowie Links zu separaten Artikeln über rechtliche Fragen rund um Hackintosh, OSX-KVM und Docker-OSX
- Die im Projekt erwähnten Produktnamen, Logos, Marken und Warenzeichen sind Eigentum ihrer jeweiligen Inhaber; diese Rechteinhaber sind laut Hinweis weder mit dem Repository verbunden noch sponsern oder unterstützen sie es
1 Kommentare
Hacker-News-Meinungen
Für Leute, die das Projekt tatsächlich nutzen wollen, ist das wichtig, aber ich verstehe nicht, warum so viele Build-Rezepte wie Dockerfiles während des Build-Prozesses beliebige Inhalte aus dem Internet herunterladen
Auch das Dockerfile dieses Projekts holt zur Build-Zeit zwei Git-Repositories und ein Skript
Das scheitert natürlich auf Sandbox-Build-Servern ohne Internetzugang, und jeder, dem Sicherheit auch nur ein bisschen wichtig ist, muss vor der Nutzung das gesamte Build-Rezept auditieren
Es reicht nicht mehr, nur die in Build-Spezifikationen wie README, requirements.txt oder package.json aufgeführten Abhängigkeiten zu prüfen; angesichts der jüngsten Ausfälle zentraler Infrastruktur und der Zunahme von Supply-Chain-Angriffen ist das eine sehr besorgniserregende Entwicklung
Es entstehen unangenehme Überraschungen: Versionsprobleme, kein Internetzugang oder im schlimmsten Fall ist eine Abhängigkeit nicht mehr verfügbar. Self-contained Distribution sollte der Standard sein
Fedora und openSUSE haben in der Regel Richtlinien, nach denen Dinge, einschließlich Distributionspaketen und Container-Images, nur aus Paketen im Repository gebaut werden oder nur ausdrücklich während des Builds hinzugefügte Binärdateien verwenden
Wenn man es also per
dnf/zypper installinstallieren oder aus der Container-Registry des Anbieters beziehen kann, kann man dem Artefakt vertrauenWenn man das neueste Bleeding Edge braucht, muss man beliebige Inhalte aus dem Internet in Kauf nehmen
Für beliebige Open-Source-Entwickler ist es schwierig, offline vorbereitete, vertrauenswürdige Build-Artefakte zu erstellen; sie haben diese Infrastruktur nicht. Deshalb gibt es Unternehmen wie Red Hat oder SUSE
Milliardenunternehmen zahlen gerne dafür, dass jemand die Klempnerarbeit übernimmt und beliebige Artefakte aus dem Internet in vertrauenswürdige, reproduzierbare und signierte Artefakte verwandelt, CVEs verfolgt und regelmäßige Updates liefert
In den 80ern stellte man sich modulare, wiederverwendbare Softwarekomponenten vor, die man wie Legosteine zusammensteckt; damals nannte man das CASE. Jetzt ist es gewissermaßen Wirklichkeit geworden, aber natürlich hat es seinen Preis
Wenn man nicht im Dockerfile klont, braucht man vor dem Build Anweisungen wie „beim Klonen
--recursiveverwenden oder mitgit submodule initandere Repositories in das aktuelle Arbeitsverzeichnis holen“Die einzige Chance auf GPU-Beschleunigung besteht darin, eine per PCI-Passthrough unterstützte dGPU durchzureichen. AMD RX 6xxx und neuer funktioniert unter macOS 14.x, moderne Nvidia-Karten haben dagegen keine Chance
Intel-iGPUs funktionieren bis Comet Lake und teilweise bis Ice Lake, aber nichts Neueres
macOS-Builds für Apple Silicon wirken auf absehbare Zeit schwer zu emulieren, und es gibt ein wenig frühe Arbeit zum Booten von ARM Darwin
Außerdem hat AMD kein Intel VT-x, weshalb Virtualisierung auf AMD-Hosts kaputtgeht; mit einem seltsamen Hack über eine alte VirtualBox-Version kann man Docker per Emulation aber einigermaßen zum Laufen bringen
AMD hat mit AMD-V eine eigene Alternative zu VT-x, daher sollte das problemlos funktionieren. Allerdings gibt es andere Hürden beim Booten von macOS auf AMD-CPUs, die meist per kext-Loading oder anderen Tricks gelöst werden
Ich verstehe nicht ganz, welchen Sinn es hat, ein komplettes Betriebssystem in Docker laufen zu lassen. Man könnte es einfach als OVA oder in einem bevorzugten Virtualisierungsformat verteilen. Eine qcow2-Datei und ein Bash-Skript zum Starten der VM würden vermutlich schon reichen
Verwandte Beiträge:
Docker-OSX: Run macOS VM in a Docker - https://news.ycombinator.com/item?id=34374710 - Januar 2023, 110 Kommentare
macOS in QEMU in Docker - https://news.ycombinator.com/item?id=23419101 - Juni 2020, 186 Kommentare
Ich habe es vor ein paar Monaten testweise eingerichtet, und es funktionierte ziemlich gut. Allerdings stellte ich fest, dass die Anwendung, damit iMessage funktioniert, Hardware-IDs an Apple sendet und dieses Projekt gefälschte Werte verwendet
Ab diesem Punkt ging es auf die Rutschbahn von „das wird wohl nicht gutgehen“: Ich erfuhr, dass gefälschte Werte von Apple geflaggt werden und die iCloud-ID dadurch potenziell als Spammer markiert werden kann, was den Zugriff von anderen Geräten einschränken könnte
Die einzige Option ist, mit einem vage verlinkten Skript zur Erzeugung von Hardware-IDs so lange Werte auszuprobieren, bis man einen „funktionierenden“ findet; es gibt aber kein klares Signal, dass er wirklich passt und die iCloud-Reputation nicht schädigt
Abgesehen davon funktionierte es wirklich gut und ist im Notfall sehr nützlich
Bald merkte man, dass es einfacher ist, die Seriennummer eines alten, aber echten Macs zu kopieren
Allerdings scheint dieses Tool eher für Dinge wie Build-Skripte nützlich zu sein, die von proprietären macOS-Frameworks abhängen, als für die Nutzung wie ein persönlicher Computer
Ich möchte einfach ausprobieren, ob man für iOS bauen kann. Zum Beispiel Dinge wie Unity oder React Native.
Selbst wenn der Build fünfmal länger dauert, könnte das in Sachen Freiheit ziemlich cool sein.
Auch Godot baut für iOS auf diese Weise: https://github.com/godotengine/build-containers/blob/main/Do...
Es gibt auch ein Docker-Image mit vorinstallierten Tools, aber für iOS als Ziel braucht es ein paar Anpassungen: https://github.com/shepherdjerred/macos-cross-compiler
Als ich bei RStudio, dem heutigen Posit, war, habe ich an Cross-Compiling von C/C++/Fortran/Rust von Linux-Hosts aus für x86_64/aarch64 macOS gearbeitet.
Wenn man im Posit Package Manager (https://p3m.dev/client/) ein R-Paket mit nativem Code herunterlädt, wurde es auf diese Weise cross-kompiliert :)
Ich habe Sick Codes früher zu diesem Produktansatz interviewt: https://www.vice.com/en/article/akdmb8/open-source-app-lets-...
Es gibt auch OSX-PROXMOX, das Ähnliches auf einem Proxmox-Heimserver macht: https://github.com/luchina-gabriel/OSX-PROXMOX
Ich persönlich nutze Letzteres auf einem HP Z420 Xeon, und es ist sehr stabil, besonders mit GPU-Passthrough.
Es wäre schön, iCloud-Synchronisierung auf einem Heimserver laufen lassen zu können. Derzeit gibt es keine gute Möglichkeit, iCloud physisch auf einen Heimserver/ein NAS zu sichern, und es funktioniert nur unter Windows/Apple.
https://github.com/steilerDev/icloud-photos-sync
https://github.com/icloud-photos-downloader/icloud_photos_do...
Wie sich herausstellte, aktualisiert iCloud die Originalfotos nicht. Das ist nachvollziehbar, hilft aber niemandem, der erwartet hat, dass diese Änderungen beim Backup enthalten sind.
rsyncauf ein NAS zu kopieren?Ich frage mich, ob die Weiterverteilung von macOS-Images lizenzrechtlich erlaubt ist. Oder verteilt dieses Projekt auf Docker Hub offen Raubkopien?
Ich frage mich, ob die Entwicklung stehen bleibt, sobald neuere macOS-Versionen ohne Intel-Support erscheinen.
Kann man innerhalb dieses Containers Docker ausführen und darin macOS innerhalb von macOS laufen lassen? ;)
Ich hasse es wirklich, wenn der Ausdruck „USB-Passthrough“ für etwas verwendet wird, das in Wirklichkeit bestenfalls ein „USB-Proxy über Ethernet“ ist.
Das ist kein Passthrough. Es bringt mehrere Nachteile mit sich, die es bei normalem Passthrough nicht gibt und die es möglicherweise nicht einmal bei fortgeschrittenem Passthrough gibt.
Aber auch diese Methode bringt wieder andere Probleme mit sich. Das sage ich aus Erfahrung mit dem Betrieb großer VM-Testfarmen mit viel durchgereichter Hardware.
Allerdings ist auch ein „USB-Proxy über Ethernet“ echtes Passthrough, nur eben Passthrough mit höherer Latenz als VirtIO.