macOS executado com QEMU no Docker
(github.com/sickcodes)- Docker-OSX é um projeto que executa macOS em um contêiner Docker com base em QEMU + KVM, oferecendo saída X11, SSH, VNC, integração USB com iPhone e geração de seriais para pesquisa de segurança do iMessage
- O modo de execução passa para o Docker a estrutura com o dispositivo
/dev/kvm, socket X11, redirecionamento de portas e a variável de ambienteSHORTNAMEpara selecionar a versão do macOS, com exemplos incluídos do Catalina 10.15 ao Tahoe 16 - A composição das imagens é dividida por objetivo, como
latest,auto,nakedenaked-auto, permitindo anexar um.imgcriado pelo usuário ou executar tarefas de linha de comando com uma imagem Catalina pré-configurada - Os requisitos são host x86_64 com suporte a KVM, virtualização ativada na BIOS e pelo menos 20 GB de espaço em disco; com Xcode são necessários 50 GB, e o uso de
:autotambém exige no mínimo 50 GB - Além do Linux, também pode ser executado em virtualização aninhada do WSL2 no Windows 11 build 22000+, mas a saída de vídeo exige configurar WSLg, VNC ou um ambiente desktop
Executando macOS dentro de um contêiner Docker
- Docker-OSX é um projeto para executar macOS dentro de um contêiner Docker
- Funciona sobre QEMU + KVM
- Suporta encaminhamento X11
- Oferece uma configuração com USB de iPhone funcional
- Indica que é possível fazer pesquisa de segurança de macOS em Linux e Windows
- O projeto foi construído sobre OSX-KVM e também menciona KVM-OpenCore e OpenCorePkg
- Também há imagens no Docker Hub: sickcodes/docker-osx
Versões de macOS suportadas e modo de execução rápida
- O Quick Start usa
docker runpassando os seguintes elementos--device /dev/kvm-p 50922:10022para SSH- volume
/tmp/.X11-unixpara X11 DISPLAYSHORTNAMEpara selecionar a versão do macOS
- Os alvos de execução incluídos no README são os seguintes
-
High Sierra 10.13
-
Mojave 10.14
-
Catalina 10.15
-
Big Sur 11
-
Monterey 12
-
Ventura 13
-
Sonoma 14
-
Sequoia 15
- Tahoe 16
- Alguns exemplos a partir do Monterey usam
GENERATE_UNIQUE=truejunto comMASTER_PLIST_URL - Os exemplos de Sonoma, Sequoia e Tahoe também incluem
CPU='Haswell-noTSX'eCPUID_FLAGS
-
Tipos de imagem e finalidade de uso
- Docker-OSX oferece imagens de contêiner para diferentes finalidades
sickcodes/docker-osx:latest: para testar rapidamente ou criar sua própria imagem do macOSsickcodes/docker-osx:auto: usa um sistema Catalina pré-configurado, com nome de usuáriousere senhaalpinesickcodes/docker-osx:naked: executa anexando um arquivo.imgque o usuário já possuisickcodes/docker-osx:naked-auto: automatiza SSH e execução de comandos passandoUSERNAME,PASSWORDeOSX_COMMANDSpara a imagem do usuáriosickcodes/docker-osx:big-sur,:monterey,:ventura,:sonoma,:high-sierra,:mojave: para executar versões específicas
- A imagem
nakedé voltada para fluxos em que uma imagem de disco existente é inicializada repetidamente ou em que o contêiner é revertido ao estado anterior autoenaked-autopodem ser usados para tarefas centradas em linha de comando ou trabalhos headless, como builds com Homebrew
Principais recursos
- Os recursos declarados pelo Docker-OSX são os seguintes
- Uso de iPhone com OSX KVM no Linux por meio do usbfluxd
- Execução de VM macOS Monterey
- Compartilhamento de pastas
- USB passthrough e hotplug
- SSH ativado em
localhost:50922 - VNC ativado em
localhost:8888ao usar a versão./vnc - serial number generator para pesquisa de segurança do iMessage
- Encaminhamento X11
- Suporte a Big Sur, imagens personalizadas e modo headless com Xvfb
- Possibilidade de clonar contêineres com
docker commit
- Também há suporte a Kubernetes, e o projeto informa que o Helm Chart e a documentação ficam no diretório
helm
Requisitos e configuração inicial
- Os requisitos mínimos são os seguintes
- Mais de 20 GB de espaço em disco
- 50 GB ao usar Xcode
- No mínimo 50 GB ao usar
:auto - Virtualização ativada na BIOS
- Host x86_64 com suporte a KVM
- A configuração inicial segue o fluxo de instalar QEMU e dependências relacionadas no host e depois ativar
libvirtd,virtlogde os módulos de kernel do KVM - São fornecidos comandos de instalação de pacotes para Arch, Ubuntu/Debian e CentOS/RHEL/Fedora
- Em alguns casos, o usuário precisa pertencer aos grupos Docker, KVM e libvirt, além de verificar se o daemon do Docker está em execução
Condições para execução no Windows
- A execução do Docker-OSX no Windows é possível em um ambiente Windows 11 + WSL2
- É necessário Windows 11 build 22000+, versão 21H2 ou superior
- Após instalar o WSL, adiciona-se
nestedVirtualization=trueem.wslconfig - Na distribuição WSL, usa-se
kvm-okpara verificar se/dev/kvme a aceleração KVM estão disponíveis - No Docker for Windows, é preciso ativar o engine baseado em WSL2 e a integração com a distribuição WSL padrão
- Os métodos de saída de vídeo se dividem em 3 opções
- WSLg: a opção mais simples e recomendada, embora possa haver problemas com envio do teclado ou exibição de um segundo cursor
- VNC: usar a configuração de VNC do QEMU ou a seção de VNC
- Desktop Environment: consome mais recursos, mas oferece uma experiência completa de desktop Linux
Compartilhamento de arquivos e gerenciamento de disco
- O método de compartilhamento mais fácil e seguro sugerido é o
sshfs- Em Linux/Windows, monta-se o rootfs do macOS no espaço do usuário com algo como
sshfs user@localhost: -p 50922 ~/mnt/osx
- Em Linux/Windows, monta-se o rootfs do macOS no espaço do usuário com algo como
- Também é possível usar compartilhamento QEMU 9p
- A pasta do host é passada ao contêiner como
/mnt/hostshare - Dentro do macOS, monta-se com
sudo -S mount_9p hostshare
- A pasta do host é passada ao contêiner como
- O compartilhamento por NFS também é explicado
- Registra-se o diretório compartilhado do host em
/etc/exports - O contêiner Docker-OSX é iniciado com
--network host - No terminal do macOS, usa-se
mount_nfs
- Registra-se o diretório compartilhado do host em
- Quando falta espaço em disco para o Docker, é possível mover
/var/lib/dockerpara um drive externo, armazenamento em bloco, NFS ou similar e depois criar um link simbólico- O projeto orienta seguir esse tutorial apenas se você aceitar a possibilidade de remover as imagens e camadas atuais do Docker
USB de iPhone e USB passthrough
- Em PCs desktop, o método de USB passthrough de iPhone baseado em VFIO é indicado em um link separado
- Em notebooks, PCs e outros dispositivos, pode-se usar USB passthrough em modo de rede com usbfluxd
- No Linux, conecta-se o iPhone ou iPad via USB
- Expõe-se o
usbmuxdna porta TCP5000 - No guest macOS, conecta-se ao host com algo como
usbfluxd -f -r 172.17.0.1:5000 - O projeto informa que o dispositivo aparece ao fechar e abrir novamente aplicativos como Xcode
- Para USB passthrough genérico, é informado que o QEMU precisa ser iniciado como root
- Usa-se
lsusb -tpara verificar bus e porta - Utilizam-se
--privileged,/dev/kvm,EXTRA="-device ... usb-host ..."e afins - Enquanto a VM estiver em execução, o sistema host não poderá acessar esse dispositivo USB
- Usa-se
Headless, VNC, SPICE e execução remota
- A execução headless é feita removendo duas linhas relacionadas ao X11 em
docker run- remover o volume
/tmp/.X11-unix - remover a variável de ambiente
DISPLAY
- remover o volume
- O projeto indica que contêineres headless baseados em imagens personalizadas são úteis em pipelines de CI/CD
- O VNC pode ser usado apenas localmente, mas o README declara explicitamente que não há qualquer criptografia TLS/HTTPS
- O projeto orienta que usar túnel SSH e fechar portas externas torna o uso mais seguro
- SPICE também pode ser usado
- A conexão é feita com
remote-viewer spice://localhost:3001 - O exemplo com
-disable-ticketingpermite acesso à VM sem autenticação, então o projeto recomenda consultar o manual do SPICE para configurar autenticação
- A conexão é feita com
Números seriais e pesquisa com iMessage/iCloud
- Para usar iMessage ou iCloud, os valores a serem alterados são os seguintes
SERIALBOARD_SERIALUUIDMAC_ADDRESSROM, descrito como o endereço MAC em minúsculas sem os dois-pontos
- Docker-OSX oferece duas formas
GENERATE_UNIQUE=true: gera valores únicos em tempo de execuçãoGENERATE_SPECIFIC=true: usa valores especificados
./custom/generate-unique-machine-values.shpode gerar número serial, endereço MAC, saída CSV/TSV e imagem de disco de boot- Dentro do macOS, o número serial pode ser conferido com
ioreg -l | grep IOPlatformSerialNumber
Desempenho, resolução e configuração de rede
- O projeto informa que é possível deixar o contêiner mais rápido com osx-optimizer
- Pular a tela de login da GUI
- Desativar indexação do Spotlight
- Desativar o plano de fundo pesado da tela de login
- Desativar atualizações
- A resolução pode ser alterada com as variáveis de ambiente
WIDTHeHEIGHT- Devem ser usadas junto com
GENERATE_UNIQUE=trueouGENERATE_SPECIFIC=true - O boot leva cerca de 30 segundos a mais para criar uma nova partição de inicialização
- Resoluções inválidas voltam para o padrão
800x600
- Devem ser usadas junto com
- O adaptador de rede pode ser alterado por variável de ambiente
- Conexão de internet rápida:
NETWORKING=vmxnet3 - Conexão de internet lenta:
NETWORKING=e1000-82545em
- Conexão de internet rápida:
- Em instalações remotas, ativar o encaminhamento IPv4 pode melhorar o desempenho, mas o projeto avisa que o IP do host pode vazar mesmo se um VPN estiver em uso no contêiner
Solução de problemas e limitações
- Se o daemon do Docker não estiver em execução, pode ocorrer o erro
docker: unknown server OS: .sudo dockerdsudo systemctl --start dockerdsudo systemctl --enable --now dockerd
- Não é possível alocar mais RAM do que a máquina física possui
- O valor padrão é
-e RAM=3 - Ao exceder isso, pode ocorrer o erro
cannot set up guest memory 'pc.ram': Cannot allocate memory
- O valor padrão é
- Erros relacionados ao ALSA podem aparecer durante a inicialização do contêiner ou o boot, e o projeto informa que não há motivo para preocupação se a inicialização e os recursos estiverem funcionando normalmente
- O TODO ainda inclui os seguintes itens
- Documentação para pesquisadores de segurança
- Aceleração por GPU
- Suporte a virt-manager
Licença e avisos
- Docker-OSX é licenciado sob GPL v3+
- O projeto declara explicitamente que é permitido usar Docker-OSX como ferramenta para criar software proprietário
- Inclui avisos relacionados à pesquisa de segurança da Apple e ao Apple Bug Bounty Program, além de um link para um texto separado sobre questões legais envolvendo Hackintosh, OSX-KVM e Docker-OSX
- O projeto informa que os nomes de produtos, logos, marcas e trademarks mencionados pertencem a seus respectivos proprietários, e que esses detentores de marca não são afiliados ao repositório nem o patrocinam ou endossam
1 comentários
Opiniões no Hacker News
Para quem realmente pretende usar o projeto, isso é importante, mas não entendo por que tantas receitas de build como Dockerfiles são feitas para baixar materiais aleatórios da internet durante o processo de build
O Dockerfile deste projeto também busca 2 repositórios Git e 1 script no momento do build
Além de falhar, é claro, em servidores de build em sandbox sem acesso à internet, qualquer pessoa que se preocupe minimamente com segurança precisa auditar toda a receita de build antes de usá-la
Já não basta revisar apenas as dependências descritas em especificações de build como README, requirements.txt ou package.json; considerando as recentes falhas em infraestruturas críticas e o aumento dos ataques à cadeia de suprimentos, essa é uma tendência muito preocupante
Surgem surpresas desagradáveis, como problemas de versão, falta de internet ou, no pior caso, a dependência deixar de estar disponível. Distribuição autossuficiente deveria ser o padrão
Fedora e openSUSE geralmente têm políticas para que tudo, incluindo pacotes da distribuição e imagens de contêiner, seja buildado apenas com pacotes dos repositórios, ou use somente binários explicitamente adicionados durante o build
Por isso, se você consegue instalar com
dnf/zypper installou baixar do registro de contêineres do fornecedor, pode confiar no artefatoSe precisar do que há de mais bleeding edge, vai ter que aceitar materiais aleatórios da internet
É difícil para um desenvolvedor open source qualquer produzir artefatos de build prontos para offline e confiáveis, e essa infraestrutura não existe. É por isso que empresas como Red Hat ou SUSE existem
Empresas de bilhões de dólares pagam de bom grado para alguém fazer o trabalho de encanamento que transforma artefatos aleatórios da internet em artefatos confiáveis, reproduzíveis e assinados, além de acompanhar CVEs e fazer atualizações regulares
Nos anos 80, imaginávamos componentes de software modulares e reutilizáveis que se encaixariam como blocos de Lego, e na época chamávamos isso de CASE. Agora isso meio que se realizou, mas obviamente há um preço
Se o Dockerfile não fizer o clone, seriam necessárias instruções pré-build do tipo “use
--recursiveao clonar ougit submodule initpara trazer outros repositórios para o diretório de trabalho atual”A única possibilidade de aceleração por GPU é passar uma dGPU compatível via PCI passthrough. AMD RX 6xxx ou superior funciona no macOS 14.x, mas Nvidia moderna não tem chance
iGPU da Intel funciona até Comet Lake e em parte de Ice Lake, mas nada mais novo que isso
O macOS em builds para Apple Silicon parece difícil de emular por enquanto, e há algum trabalho inicial em boot do ARM Darwin
Além disso, a AMD não tem Intel VT-x, então a virtualização quebra em hosts AMD, embora seja possível fazer o Docker funcionar até certo ponto por emulação usando um hack esquisito com uma versão antiga do VirtualBox
A AMD tem sua própria alternativa ao VT-x, o AMD-V, então isso deveria funcionar sem problemas. Mas há outros obstáculos para inicializar o macOS em CPU AMD, normalmente resolvidos carregando kexts ou com outros truques
Não entendo muito o sentido de rodar um sistema operacional inteiro via Docker. Bastaria distribuir como OVA ou no formato de virtualização preferido. Um qcow2 e um script bash para iniciar a VM provavelmente já seriam suficientes
Posts relacionados:
Docker-OSX: Run macOS VM in a Docker - https://news.ycombinator.com/item?id=34374710 - janeiro de 2023, 110 comentários
macOS in QEMU in Docker - https://news.ycombinator.com/item?id=23419101 - junho de 2020, 186 comentários
Configurei isso como experimento alguns meses atrás, e funcionou bem. Porém, para o iMessage funcionar, descobri que o aplicativo envia IDs de hardware para a Apple, e este projeto usa valores falsos
A partir desse ponto comecei a escorregar pelo caminho do “acho que isso não vai dar certo”, e descobri que valores falsos podem ser marcados pela Apple e, como resultado, o ID do iCloud pode ser sinalizado como potencial spammer, restringindo o acesso a outros dispositivos
A única opção é continuar tentando valores com um script de geração de ID de hardware linkado de forma meio vaga até encontrar um valor que “funcione”, mas não há um sinal claro de que ele realmente bateu bem e não vai prejudicar a reputação do iCloud
Fora isso, funcionou muito bem e é extremamente útil em uma emergência
Logo percebi que era mais fácil copiar o Serial de um Mac antigo, mas real
Ainda assim, esta ferramenta parece mais útil para coisas como scripts de build que dependem de frameworks proprietários do macOS, do que para usar como um computador pessoal
Quero apenas testar se consigo fazer build para iOS. Por exemplo, coisas como Unity e React Native
Mesmo que o build demore 5 vezes mais, em termos de liberdade pode ser bem interessante
É também assim que o Godot faz build mirando iOS: https://github.com/godotengine/build-containers/blob/main/Do...
Há também uma imagem Docker com as ferramentas pré-instaladas, mas para mirar iOS é preciso fazer alguns ajustes: https://github.com/shepherdjerred/macos-cross-compiler
Quando eu estava na RStudio, hoje Posit, trabalhei em compilação cruzada de C/C++/Fortran/Rust em um host Linux mirando macOS x86_64/aarch64
Se você baixa um pacote R com código nativo pelo Posit Package Manager(https://p3m.dev/client/), ele foi compilado de forma cruzada desse jeito :)
Entrevistei o Sick Codes no passado sobre essa abordagem de produto: https://www.vice.com/en/article/akdmb8/open-source-app-lets-...
Também existe o OSX-PROXMOX, que faz algo parecido em um homeserver Proxmox: https://github.com/luchina-gabriel/OSX-PROXMOX
Pessoalmente uso este último em um HP Z420 Xeon e ele é muito estável, especialmente com passthrough de GPU
Seria bom poder rodar sincronização do iCloud em um homeserver. Hoje não há um bom jeito de fazer backup físico do iCloud para um homeserver/NAS, e isso só funciona em Windows/Apple
https://github.com/steilerDev/icloud-photos-sync
https://github.com/icloud-photos-downloader/icloud_photos_do...
Pelo visto, o iCloud não atualiza as fotos originais. Faz sentido, mas não ajuda quem esperava que essas alterações fossem incluídas no backup
rsyncpara copiar a pasta do iCloud de um Mac/PC conectado para o NAS?Fico me perguntando se a redistribuição de imagens do macOS é permitida pela licença. Ou será que este projeto está distribuindo cópias piratas descaradamente no Docker Hub?
Fico me perguntando se o progresso vai parar quando sair uma versão mais nova do macOS que não tenha mais suporte a Intel
Dá para executar Docker dentro deste contêiner para rodar macOS dentro do macOS? ;)
Eu realmente detesto quando a expressão “passthrough USB” é usada para uma situação que, na melhor das hipóteses, é um “proxy USB via Ethernet”
Isso não é passthrough. Traz várias desvantagens que não existem no passthrough comum e talvez nem no passthrough avançado
Mas esse método também traz outros problemas. Digo isso pela experiência de operar grandes fazendas de teste de VMs com muito hardware repassado
Ainda assim, “proxy USB via Ethernet” também é passthrough de verdade; é apenas um passthrough com latência maior que VirtIO