M1 macOS 上很令人头疼的就是虚拟机软件,想装 Kali 的虚拟机,试了一大堆感觉没一个能用的,Parallels 17 是最完美的也是贵得最离谱的,UTM 作为开源免费的解决方案从 iPad 而来,实在有点拉垮,VMware Fusion、VirtualBox 都还不支持 M1 芯片……
于是某天突发奇想:有没有可能拿 Kali Linux 的 Docker 容器当虚拟机,然后 VNC 连接桌面来使用呢?

关于 host 网络

本来想要让容器加入 host 网络,可以和宿主机共享网络,结果尝试之后发现容器里和宿主机里的网络信息仍然是不一样的,而且各种连接也连不上。

去查了下资料了解到,Docker for MacOS 其实并不是完全标准的 Docker 实现。一般 Linux 上运行的 Docker 是「容器和宿主机共用 Linux 内核」,而 MacOS 本身不是 Linux,它的 Docker 在虚拟机上运行,总之就是不支持这个 host 网络。

非常形象的两张图,Linux 下网络是这样的:

Linux 下的 Docker 网络结构

而 MacOS 下是这样的:

MacOS 下的 Docker 网络结构

解决方案也不是没有,比如 docker-mac-network 这个项目是用 OpenVPN 建立信道,不过实践起来都非常麻烦,感觉对于本项目而言没有必要。

于是只能选择开放 SSH、VNC 之类的几个端口了。

运行容器

Kali 官方提供了 Docker 镜像,是支持 arm64 架构的!

由于没法使用 host 网络,我们启动的时候就最好要设置好开放的端口。留个 22 给 SSH,5900 开始的几个留给 VNC:

docker run -itd -P \
  --name kali \
  -p 22:22 \
  -p 5900:5900 \
  -p 5901:5901 \
  -p 5902:5902 \
  kalilinux/kali-rolling

安装环境

这个 kali 的镜像基本上是个空壳,啥都没有。要先换源,然后装一些包,包括图形环境。

阿里云的源:

deb http://mirrors.aliyun.com/kali kali-rolling main non-free contrib
deb-src http://mirrors.aliyun.com/kali kali-rolling main non-free contrib
docker exec -it kali bash
nano /etc/apt/sources.list
apt-get update & apt-get upgrade
apt-get install kali-linux-arm kali-desktop-core kali-desktop-xfce

其他一些可以安装的包列举在这里

安装之后最好 commit 一下,可以做个备份,免得玩坏了下次重新安装……

配置运行 TightVNC

apt-get install tightvncserver

创建一个新的用户并给予 root 权限(不建议以 root 用户登录),同时最好加入 sudoers 里(visudo)。
然后切换到新用户运行 vncpasswd,会提示设置 VNC 连接的密码。之后就可以在当前用户下直接启动 VNCServer 了:

tightvncserver :1 -geometry 1440x900

第一次启动会自动在 ~/.vnc/ 目录下生成默认的 xstartup 配置文件。

VNCServer 的端口默认从 5900 开始,:0 表示 5900,:1 就表示 5901。不同的端口可以配置登陆不同的用户。

-geometry 选项调整分辨率。之后进入 Kali 会发现系统设置里的分辨率是没法调整的,进入 Display 设置就显示错误。实际上分辨率只能在启动 VNCServer 的时候控制。
我的 Macbook 屏幕比例是 16:10,比较适合的分辨率是 1440x900

使用 tightvncserver -kill :1 停止。不结束进程就直接 docker stop kali 相当于强制关机,第二次启动图形环境会有进程占用问题,要手动处理。

客户端连接

地址直接填写本机 127.0.0.1:5901 即可。由于是本地的连接,就不做 SSH 通道加密啥的了。

今天才发现,MacOS 有个深藏不露的自带的 VNC 客户端,叫做「屏幕共享」。应用列表里都找不到,搜索才能找到。也可以直接在 Safari 里输入 vnc://127.0.0.1:5901 进入这个 App(Chrome 好像也行)。
也可以用 VNC Viewer 客户端连接。

VNC Viewer 连接,体验极佳!

也可以用 noVNC,直接在浏览器里用(虽说这样就不像一个「虚拟机」了 QwQ)。

apt-get install net-tools
apt-get install novnc
/usr/share/novnc/utils/launch.sh --listen 5901 --vnc localhost:5900

浏览器访问 http://127.0.0.1:25901/vnc.html 即可连接。

其他奇怪的探索

基于异想天开的想要找一个 Windows 虚拟机解决方案的想法,发现真的存在 ReactOS 的 Docker 镜像(这个项目),并且居然在 arm64 上可以奇迹般地跑起来……(虽然不知道这玩意是怎么在 Docker 容器里运行的)

docker run --detach \
  --name reactos \
  --publish 127.0.0.1:5900:5900/tcp \
  --publish 127.0.0.1:6080:6080/tcp \
  docker.io/hectormolinero/qemu-reactos:latest

于是去体验了一下 ReactOS on Docker,虽然,基本上是卡得没法用的状态。Firefox 网页基本上加载不出……
并且在第二次启动之后,之前装的软件居然都打不开了,显示「FILE_NOT_FOUND」。估计是我没正常关机而是直接 docker stop reactos 的原因。

ReactOS 的奇妙体验

不能说像,简直一模一样。「Windows 经典」主题,非常复古。想想毕竟是个伟大的开源项目,这个体验还是挺有意思的。