在Docker中运行macOS VM的详细指南
技术背景
Docker-OSX项目允许在Docker容器中以接近原生的性能运行Mac OS X,具备X11转发、iMessage安全研究、iPhone USB支持等功能,可用于macOS的安全研究和开发工作。
实现步骤
初始设置
- 开启硬件虚拟化:在BIOS中开启硬件虚拟化,具体方法因机器和BIOS而异。
- 安装依赖:
1
| sudo pacman -S qemu libvirt dnsmasq virt-manager bridge-utils flex bison iptables-nft edk2-ovmf
|
- **UBUNTU/DEBIAN**:
1
| sudo apt install qemu qemu-kvm libvirt-clients libvirt-daemon-system bridge-utils virt-manager libguestfs-tools
|
- **CENTOS/RHEL/FEDORA**:
1
| sudo yum install libvirt qemu-kvm
|
- 启用libvirt和加载KVM内核模块:
1 2 3 4
| sudo systemctl enable --now libvirtd sudo systemctl enable --now virtlogd echo 1 | sudo tee /sys/module/kvm/parameters/ignore_msrs sudo modprobe kvm
|
在Windows上运行
- 安装WSL2:在管理员PowerShell中运行
wsl --install
,确认WSL2已启用,可使用wsl -l -v
查看。 - 配置
.wslconfig
:在C:/Users/<Your_Name>/.wslconfig
文件末尾添加nestedVirtualization=true
。 - 检查KVM:进入WSL发行版,使用
kvm-ok
命令检查KVM是否启用,若未启用,使用sudo apt -y install bridge-utils cpu-checker libvirt-clients libvirt-daemon qemu qemu-kvm
安装。 - 安装Docker for Windows:安装后在设置中勾选“Use the WSL2 based engine”和“Enable integration with my default WSL distro”。
- 安装
x11-apps
:使用sudo apt install x11-apps -y
安装。 - 选择视频输出方式:
1 2
| -e "DISPLAY=${DISPLAY:-:0.0}" \ -v /mnt/wslg/.X11-unix:/tmp/.X11-unix \
|
- **VNC**:参考VNC部分,可添加`-vnc`参数到`qemu`。
- **桌面环境**:可参考相关指南设置。
启动不同版本的macOS
Catalina (10.15)
1 2 3 4 5 6 7
| docker run -it \ --device /dev/kvm \ -p 50922:10022 \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e "DISPLAY=${DISPLAY:-:0.0}" \ -e SHORTNAME=catalina \ sickcodes/docker-osx:latest
|
Big Sur (11)
1 2 3 4 5 6 7
| docker run -it \ --device /dev/kvm \ -p 50922:10022 \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e "DISPLAY=${DISPLAY:-:0.0}" \ -e SHORTNAME=big-sur \ sickcodes/docker-osx:latest
|
Monterey (12)
1 2 3 4 5 6 7 8 9
| docker run -it \ --device /dev/kvm \ -p 50922:10022 \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e "DISPLAY=${DISPLAY:-:0.0}" \ -e GENERATE_UNIQUE=true \ -e MASTER_PLIST_URL='https://raw.githubusercontent.com/sickcodes/osx-serial-generator/master/config-custom.plist' \ -e SHORTNAME=monterey \ sickcodes/docker-osx:latest
|
Ventura (13)
1 2 3 4 5 6 7 8 9
| docker run -it \ --device /dev/kvm \ -p 50922:10022 \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e "DISPLAY=${DISPLAY:-:0.0}" \ -e GENERATE_UNIQUE=true \ -e MASTER_PLIST_URL='https://raw.githubusercontent.com/sickcodes/osx-serial-generator/master/config-custom.plist' \ -e SHORTNAME=ventura \ sickcodes/docker-osx:latest
|
Sonoma (14)
1 2 3 4 5 6 7 8 9 10 11
| docker run -it \ --device /dev/kvm \ -p 50922:10022 \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e "DISPLAY=${DISPLAY:-:0.0}" \ -e GENERATE_UNIQUE=true \ -e CPU='Haswell-noTSX' \ -e CPUID_FLAGS='kvm=on,vendor=GenuineIntel,+invtsc,vmware-cpuid-freq=on' \ -e MASTER_PLIST_URL='https://raw.githubusercontent.com/sickcodes/osx-serial-generator/master/config-custom-sonoma.plist' \ -e SHORTNAME=sonoma \ sickcodes/docker-osx:latest
|
Sequoia (15)
1 2 3 4 5 6 7 8 9 10 11
| docker run -it \ --device /dev/kvm \ -p 50922:10022 \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e "DISPLAY=${DISPLAY:-:0.0}" \ -e GENERATE_UNIQUE=true \ -e CPU='Haswell-noTSX' \ -e CPUID_FLAGS='kvm=on,vendor=GenuineIntel,+invtsc,vmware-cpuid-freq=on' \ -e MASTER_PLIST_URL='https://raw.githubusercontent.com/sickcodes/osx-serial-generator/master/config-custom-sonoma.plist' \ -e SHORTNAME=sequoia \ sickcodes/docker-osx:latest
|
High Sierra
1 2 3 4 5 6 7
| docker run -it \ --device /dev/kvm \ -p 50922:10022 \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e "DISPLAY=${DISPLAY:-:0.0}" \ -e SHORTNAME=high-sierra \ sickcodes/docker-osx:latest
|
Mojave
1 2 3 4 5 6 7
| docker run -it \ --device /dev/kvm \ -p 50922:10022 \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e "DISPLAY=${DISPLAY:-:0.0}" \ -e SHORTNAME=mojave \ sickcodes/docker-osx:latest
|
核心代码
手动下载镜像并使用
1 2 3 4 5 6 7 8 9 10 11
| wget https://images2.sick.codes/mac_hdd_ng_auto.img docker run -it \ --device /dev/kvm \ -p 50922:10022 \ -v "${PWD}/mac_hdd_ng_auto.img:/image" \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e "DISPLAY=${DISPLAY:-:0.0}" \ -e GENERATE_UNIQUE=true \ -e MASTER_PLIST_URL=https://raw.githubusercontent.com/sickcodes/Docker-OSX/master/custom/config-nopicker-custom.plist \ -e SHORTNAME=catalina \ sickcodes/docker-osx:naked
|
共享目录
1 2
| mkdir ~/mnt/osx sshfs user@localhost:/ -p 50922 ~/mnt/osx
|
iPhone USB透传(VFIO)
1 2
| https://github.com/Silfalion/Iphone_docker_osx_passthrough
|
iPhone USB -> 网络风格透传(USBFLUXD)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
|
sudo systemctl start usbmuxd sudo avahi-daemon
sudo systemctl restart usbmuxd sudo socat tcp-listen:5000,fork unix-connect:/var/run/usbmuxd
sudo usbfluxd -f -n
brew install make automake autoconf libtool pkg-config gcc libimobiledevice usbmuxd git clone https://github.com/corellium/usbfluxd.git cd usbfluxd ./autogen.sh make sudo make install sudo launchctl start usbmuxd export PATH=/usr/local/sbin:${PATH} sudo usbfluxd -f -r 172.17.0.1:5000
|
最佳实践
减小镜像大小
- 启动容器,使用
du -sh *
从/
目录开始查找可删除大文件的目录。 - 启用
trim
:sudo trimforce enable
,然后重启。 - 清空磁盘空空间:
dd if=/dev/zero of=./empty && rm -f empty
。 - 复制出
qcow
镜像:docker cp stoppedcontainer:/home/arch/OSX-KVM/mac_hdd_ng.img .
。 - 检查并修复镜像错误:
qemu-img check -r all mac_hdd_ng.img
。 - 转换镜像格式:
qemu-img convert -O qcow2 mac_hdd_ng.img deduped.img
。 - 可选:进一步压缩镜像:
qemu-img convert -c -O qcow2 deduped.img compressed.img
。 - 构建新的Docker镜像:
1 2 3
| FROM sickcodes/docker-osx USER arch COPY --chown=arch ./deduped.img /home/arch/OSX-KVM/mac_hdd_ng.img
|
无头运行
1 2 3 4 5 6
| docker run \ --device /dev/kvm \ -p 50922:10022 \ -e "DISPLAY=${DISPLAY:-:0.0}" \ -e EXTRA="-monitor telnet::45454,server,nowait -nographic -serial null" \ mycustomimage
|
常见问题
确认CPU支持虚拟化
参考初始设置部分。
Docker未知服务器操作系统错误
表示Docker守护进程未运行,可使用以下命令启动:
1 2 3
| sudo dockerd sudo systemctl --start dockerd sudo systemctl --enable --now dockerd
|
权限被拒绝错误
1 2 3 4 5 6 7 8
| echo $DISPLAY
sudo pacman -S xorg-xhost
sudo apt install x11-xserver-utils
sudo yum install xorg-x11-server-utils xhost +
|
RAM分配过多
无法分配超过机器可用的RAM,可清理缓存:
1
| sudo tee /proc/sys/vm/drop_caches <<< 3
|
容器启动时的ALSA错误
只要能正常启动容器且功能正常,这些错误可忽略。