Хакер - M1 для хакера. Тестируем Homebrew, виртуалки, Docker и Node на новой архитектуре Apple
hacker_frei
Denis Simonov
Содержание статьи
- Внешний монитор
- Homebrew и zsh
- Виртуальные машины
- Parallels Desktop
- VMware
- QEMU
- VirtualBox (спойлер: его нет)
- Metasploitable3
- Docker и Node.js
- Проксирование трафика приложений macOS
- Wi-Fi и захват пакетов
- Программы для iOS
- Выводы
В 2020 году Apple представила новую архитектуру Apple Silicon на базе ARM и объявила, что в течение двух лет переведет на нее все свои компьютеры. Для простых пользователей миграция проходит практически незаметно, а как насчет продвинутых? В этой статье я расскажу об итогах года использования MacBook Pro с M1 внутри и покажу те немногие подводные камни, с которыми мне довелось столкнуться.
ВНЕШНИЙ МОНИТОР
Макбуки из первого поколения компьютеров на M1 поддерживали всего один внешний монитор (к Mac mini можно подключить два). С выходом новых MacBook Pro на M1 Pro и M1 Max ситуация изменилась: у них есть порт HDMI, который можно использовать для второго экрана.
Если же менять ноутбук ты пока не хочешь, а для работы нужно несколько мониторов, то решением может стать док‑станция с поддержкой DisplayLink — например, Dell D6000 или CalDigit. Однако я просто отказался от использования трех мониторов и купил один, но UltraWide. Да, это не Retina Display, но если тебе нужно разрешение 5K, то выбор не велик — только LG UltraFine, стоящие 90 с чем‑то тысяч рублей.
Недавно товарищ посоветовал мне великолепную утилиту, которая позволяет в разы улучшить работу с моим монитором. BetterDummy создает фиктивный дисплей, который поддерживает огромный набор разрешений Retina, а затем передает картинку с него на твой. Если твой монитор плохо поддерживается в macOS, то эта программа может кардинально изменить ситуацию.
Например, для дисплея с разрешением 3440 × 1440 я рекомендую использовать следующие настройки.

Единственная проблема, с которой я столкнулся при использовании BetterDummy, — невозможно выставить высокую частоту обновления (144 Гц). Оказалось, что это ограничение API CGVirtualDisplay в macOS, и исправить эту проблему может только Apple. Возможно, все изменится, когда появится поддержка ProMotion для AirPlay или Sidecar.
Если ты хочешь иметь высокую частоту обновления экрана (144 Гц и выше) с разрешением 3440 на 1440 точек и более, то придется отказаться от BetterDummy и купить отдельный кабель USB Type-C → DisplayPort. Через универсальные хабы (у меня Native Union) работать с такими настройками не выйдет — не хватит пропускной способности порта для одновременного вывода изображения и подключения периферии.
HOMEBREW И ZSH
Homebrew — популярный сторонний пакетный менеджер для macOS. Если тебе нужна какая‑то консольная утилита, то, скорее всего, ты найдешь ее в Homebrew. С версии 3.0 Homebrew поддерживает ARM. До этого рабочим решением была установка Homebrew через слой бинарной трансляции Rosetta 2. Соответственно, все приложения, установленные оттуда, тоже проходили трансляцию и работали (но не так быстро, как могли бы армовские бинарники).
Сейчас достаточно поставить Homebrew через скрипт‑установщик и получать нативные пакеты для ARM.
$ xcode-select --install
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
$ echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/$(logname)/.zprofile
$ eval "$(/opt/homebrew/bin/brew shellenv)"
Но если понадобится переключаться между архитектурами, то можешь сделать себе такие алиасы в файле ~/.bashrc или ~/.zshrc:
alias intel="env /usr/bin/arch -x86_64 /bin/zsh --login"
alias arm="env /usr/bin/arch -arm64 /bin/zsh --login"
Чуть позже мы столкнемся с практическим применением такого решения, но если вкратце, то скрипт конфигурации (./configure) перед сборкой определяет переменные системы, в том числе и для какой архитектуры компилировать проект. Например, если сейчас выбрать режим i386 при установке Homebrew, то вместо бинарников для ARM64 мы получим версии для x86_64, что приведет к потере производительности.
ВИРТУАЛЬНЫЕ МАШИНЫ
Parallels Desktop
Продукт Parallels — это в данный момент самое функциональное решение для виртуализации на M1. Недаром его показывали на презентации Apple. Через Parallels Desktop можно в один клик установить дистрибутивы Ubuntu, Fedora, Debian и macOS Monterey. С версии 17.1.1 добавлена поддержка актуальной на данной момент версии Kali Linux — 2021.3.
Драйверы гостевых машин оптимизированы и работают без нареканий (буфер обмена, сеть, динамическое разрешение, 3D-ускорение и прочие фичи). Проброс адаптера Wi-Fi или любого другого устройства работает корректно.
Отдельно хочется поговорить о Windows 11 для ARM, которая умеет транслировать код приложений x86_64 в нативные вызовы ARM. Причем делает это весьма качественно, как и Rosetta 2. При помощи такой матрешки мне удалось запустить отладчик для кода x64 и без проблем увидеть регистры RBX, RSP, RBP и так далее.
Так же работает и Visual Studio, которая смогла скомпилировать небольшой тестовый проект (Quasar RAT) в классическую архитектуру i386. И это все на виртуальной машине с гостевой Windows, для которой хостом выступает macOS для ARM. Фантастика!

Не могу не отметить энергоэффективность при работе с виртуальными машинами. Запущенные фоном VM без серьезной нагрузки практически не влияют на время работы от аккумулятора. Помимо этого, в новых версиях Parallels был добавлен режим поездки, в котором еще сильнее снижается энергопотребление при бездействии VM.
VMware
Еще один производитель популярных решений для виртуализации до недавнего времени был за бортом затеянного Apple переворота, но в конце сентября 2021 года компания VMware представила на всеобщее обозрение техническое превью VMware Fusion.

Сейчас VMware Fusion можно бесплатно загрузить на странице продукта или же по прямой ссылке. Минимальный набор удобств присутствует, однако в Ubuntu мне не удалось настроить VMware Tools. Я установил открытую версию — open-vm-tools, но и это не помогло мне сделать адаптивное разрешение экрана и общий с хостовой системой буфер обмена.
В общем, решение сыроватое, но вполне работоспособное и пока что бесплатное.
QEMU
QEMU — это глыба не только среди продуктов эмуляции, но и среди средств аппаратной виртуализации. Это основа гипервизора KVM, который использует аппаратные возможности современных процессоров. Базовая поддержка Apple Silicon уже есть в QEMU, и ее активно дорабатывают. Так что его в ряде случаев можно использовать как мощное средство виртуализации на M1.
Установка QEMU
Для начала подготовим необходимые пакеты для сборки:
$ brew install libffi gettext glib pkg-config autoconf automake pixman ninja
Клонируем репозиторий QEMU, добавляем ветку со включенным расширением BFloat16 и применяем патч Александра Графа:
$ git clone https://github.com/qemu/qemu && cd qemu
$ git checkout 3c93dfa42c394fdd55684f2fbf24cf2f39b97d47
$ curl https://patchwork.kernel.org/series/485309/mbox/ | git am
Собираем и устанавливаем QEMU:
$ mkdir build && cd build
$ ../configure --target-list=aarch64-softmmu
$ make -j8
$ sudo make install
Готово, можно пользоваться!
Создание виртуальной машины с Ubuntu в QEMU
Давай попробуем поставить Ubuntu для x86_64.
Перед установкой нужно подготовить диск:
$ curl https://cdimage.ubuntu.com/releases/20.04/release/ubuntu-20.04.3-live-server-arm64.iso -o ubuntu-20.0.4.iso
$ qemu-img create -f qcow2 virtual-disk.qcow2 8G
$ cp $(dirname $(which qemu-img))/../share/qemu/edk2-aarch64-code.fd .
$ dd if=/dev/zero conv=sync bs=1m count=64 of=ovmf_vars.fd
$ qemu-system-aarch64 \
-machine virt,accel=hvf,highmem=off \
-cpu cortex-a72 -smp 4 -m 4G \
-device virtio-gpu-pci \
-device virtio-keyboard-pci \
-drive "format=raw,file=edk2-aarch64-code.fd,if=pflash,readonly=on" \
-drive "format=raw,file=ovmf_vars.fd,if=pflash" \
-drive "format=qcow2,file=virtual-disk.qcow2" \
-cdrom ubuntu-20.0.4.iso
После этой команды должна запуститься установка Ubuntu. По завершении запускаем виртуальную машину:
$ qemu-system-aarch64 \
-machine virt,accel=hvf,highmem=off \
-cpu cortex-a72 -smp 4 -m 4G \
-device virtio-gpu-pci \
-device virtio-keyboard-pci \
-drive "format=raw,file=edk2-aarch64-code.fd,if=pflash,readonly=on" \
-drive "format=raw,file=ovmf_vars.fd,if=pflash" \
-drive "format=qcow2,file=virtual-disk.qcow2" \
-nic hostfwd=tcp:127.0.0.1:4422-0.0.0.0:22 &
Для коннекта по SSH:
$ ssh <username>@127.0.0.1 -p 4422
Для Windows все аналогично, отличия в оборудовании, формате образа диска и еще всякое по мелочи. Единственный минус прямой работы с QEMU — все придется делать руками. С другой стороны, это добавляет гибкости. Однако можно и избежать лишнего труда, если использовать утилиту UTM.
UTM
QEMU — мощная штука и в умелых руках может творить чудеса. Однако не всегда удобно разбираться в пятиэтажных аргументах конфигурации, особенно если нужно что‑то быстро изменить или добавить.
UTM — это графическая оболочка, которая значительно упрощает работу с QEMU в macOS. У проекта есть официальный сайт и репозиторий на GitHub. Отдельно стоит отметить галерею готовых образов для быстрой раскатки. Среди ожидаемых систем можно найти ReactOS (x86), Sun Solaris (SPARC), Mac OS 9.2.1 (PPC) и старушку Windows XP (x64). Конечно, эти ребята в эмуляции будут работать не так быстро, как гостевые системы с поддержкой ARM, зато как зрелищно!

Я практически не использую это решение, поскольку работать с софтом в гостевой ОС все же неудобно, да и стабильность не блещет. Но бывают случаи, когда эта штука может выручить.
Существует, кстати, и версия UTM для iOS, но установить ее можно только через сайдлоадинг.
VirtualBox (спойлер: его нет)
Увы, разработчики этого популярного опенсорсного решения для виртуализации пока что не добрались до M1. А это значит, что нельзя запустить и виртуалки с Android вроде Genymotion, NoxPlayer и BlueStacks. Так что пока приходится довольствоваться Android Developer Studio.
Metasploitable3
Когда я попытался использовать эту виртуальную машину для тестирования эксплоитов, то столкнулся с проблемой. Запустить ее получилось лишь в QEMU, но работать с комфортом это не позволяет — производительность выходит слишком низкая.
К тому же в macOS Big Sur и Monterey QEMU не может использовать проброс портов через NAT из‑за отсутствия TAP-устройств (виртуальные сетевые драйверы ядра системы для эмуляции Ethernet). Единственная возможность — переадресация локального порта на виртуальную машину, как в примере с установкой Ubuntu Server выше и SSH-доступом к ней.
DOCKER И NODE.JS
Сейчас с Docker сложностей практически нет. Приложение давно нативное, установка — стандартная.
Единственный нюанс, о котором хочется рассказать, — это отсутствие в Docker Hub версий некоторых образов для ARM. А еще бывает, что образ есть, но в нем несовместимые библиотеки, которые нужно перекомпилировать. Если в первом случае все очевидно, то о второй проблеме я бы хотел поговорить подробнее.
Например, в своем проекте я столкнулся с тем, что невозможно собрать модуль sharp@0.28.3 для Node.js в базовом образе Node из Docker Hub.
INFO
Sharp — это высокоскоростной модуль Node.js для преобразования больших изображений распространенных форматов (JPEG, PNG, AVIF и WebP) в более мелкие.
В этом популярном образе были проблемы с зависимостями. Как оказалось, столкнулся с ними не я один.
Суть проблемы — в том, что в образе Docker для сборки зависимостей пакета sharp необходима библиотека libvips версии 8.10.6 или старше, которая идет с glibc 2.29+. В своем файле сборки я использовал образ node:16.3-buster-slim с glibc 2.24. Понадобилось вручную собирать подходящую версию libvips.
Мой Dockerfile:
FROM node:16.3-buster-slim
WORKDIR /opt/app
ADD . .
RUN npm install
RUN npm run build api
CMD ["node", "./dist/apps/api/main.js"]
Лог установки Sharp на node:16.3-buster-slim:
#8 21.23 sharp: Installation error: Use with glibc 2.24 requires manual installation of libvips >= 8.10.6
#8 21.23 sharp: Please see https://sharp.pixelplumbing.com/install for required dependencies
#8 21.47 npm WARN The package typescript is included as both a dev and production dependency.
#8 21.48 npm WARN optional SKIPPING OPTIONAL DEPENDENCY: fsevents@2.3.2 (node_modules/fsevents):
#8 21.48 npm WARN notsup SKIPPING OPTIONAL DEPENDENCY: Unsupported platform for fsevents@2.3.2: wanted {"os":"darwin","arch":"any"} (current: {"os":"linux","arch":"arm64"})
#8 21.48
#8 21.51 npm ERR! code ELIFECYCLE
#8 21.51 npm ERR! errno 1
#8 21.51 npm ERR! sharp@0.28.3 install: `(node install/libvips && node install/dll-copy && prebuild-install) || (node install/can-compile && node-gyp rebuild && node install/dll-copy)`
#8 21.51 npm ERR! Exit status 1
В такой ситуации нужно или пересобирать libvips для ARM64, или же использовать более свежий образ операционной системы. Например, можно взять node:14-alpine, который уже содержит скомпилированные для ARM бинарники и занимает на 700 Мбайт меньше, чем Debian.
Я выбрал хардкорный вариант пересборки библиотеки libvips под ARM64. Добавил несколько строк в Dockerfile:
FROM node:16.3-buster-slim
RUN apt-get update -qq && apt -y upgrade && \
apt-get install -y git build-essential libpng-dev wget pkg-config glib2.0-dev libexpat1-dev autoconf nasm libtool dpkg g++
RUN wget https://github.com/libvips/libvips/releases/download/v8.12.1/vips-8.12.1.tar.gz
RUN tar xf vips-8.12.1.tar.gz && cd vips-8.12.1 && ./configure && make && make install && ldconfig
WORKDIR /opt/app
ADD . .
RUN npm install
RUN npm run build api
CMD ["node", "./dist/apps/api/main.js"]
И собираю без ошибок.
docker build -t test -f apps/api/Dockerfile .
В общем, когда работаешь на менее популярной архитектуре, это может время от времени приводить к проблемам вроде той, что я описал. Но зато теперь ты знаешь, что делать в таких случаях!
ПРОКСИРОВАНИЕ ТРАФИКА ПРИЛОЖЕНИЙ MACOS
Для перехвата и анализа трафика есть отличная утилита mitmproxy, а в паре с ProxyChains-ng они способны замитмить практически любое приложение macOS, которое использует HTTP.
В начале статьи мы делали быстрые алиасы для переключения архитектур, теперь самое время их применить. К слову, поддержку macOS Monterey и M1 в ProxyChains-ng добавили совсем недавно — в начале января 2022 года.
Мы соберем две разные версии библиотек libproxychains4.dylib для работы с обеими архитектурами. Большинство программ универсальны и скомпилированы для двух архитектур сразу (Mach-O universal binary). Например:
$ file /usr/bin/python
/usr/bin/python: Mach-O universal binary with 2 architectures: [x86_64:Mach-O 64-bit executable x86_64] [arm64e:Mach-O 64-bit executable arm64e]
/usr/bin/python (for architecture x86_64): Mach-O 64-bit executable x86_64
/usr/bin/python (for architecture arm64e): Mach-O 64-bit executable arm64e
Версии для x86_64 и для ARM предназначены для работы с приложениями, собранными под соответствующие архитектуры. Начнем с x86_64.
$ intel
$ arch
i386
$ git clone https://github.com/rofl0r/proxychains-ng
$ cd proxychains-ng
$ ./configure
$ make && make install
Пробуем, например с TOR:
$ proxychains4 curl icanhazip.org
[proxychains] config file found: /usr/local/etc/proxychains.conf
[proxychains] preloading /usr/local/lib/libproxychains4.dylib
[proxychains] DLL init: proxychains-ng 4.15-git-8-g2739fb5
[proxychains] Strict chain ... 127.0.0.1:9050 ... icanhazip.org:80 ... OK
45.153.160.135
Отлично работает для утилиты curl. Давай попробуем сделать прокси для Telegram. Он как раз написан только под ARM, и нам потребуется пересобрать proxychains4.
Удостоверимся, что это приложение для ARM:
$ file /Applications/Telegram.app/Contents/MacOS/Telegram
/Applications/Telegram.app/Contents/MacOS/Telegram: Mach-O 64-bit executable arm64
Все так, теперь меняем архитектуру:
$ arm
$ arch
arm64
Пересоберем ProxyChains-ng:
$ make clean
$ ./configure
$ make
Здесь я намеренно не делал make inastall, так как затрется предыдущая версия. Буду запускать из папки proxychains-ng. После сборки бинарник и библиотека лежит в корне. Подкорректирую конфиг:
$ cp src/proxychains.conf ./
$ sed -i '' 's/socks4/#socks4/g' proxychains.conf
$ echo "http 127.0.0.1 8080" >> proxychains.conf
Теперь установим mitmproxy:
$ brew install mitmproxy
Проверим работу:
$ mitmproxy
Установим необходимые сертификаты:
$ sudo security add-trusted-cert -d -p ssl -p basic -k /Library/Keychains/System.keychain ~/.mitmproxy/mitmproxy-ca-cert.pem
В одной вкладке терминала запускаем mitmproxy, в другой — Telegram через proxychains:
$ ./proxychains4 /Applications/Telegram.app/Contents/MacOS/Telegram
Конечно, помимо «Телеграма», мы можем перехватывать, например, целый Firefox и смотреть, куда летят запросы самого браузера или его расширений:
$ proxychains4 /Applications/Firefox.app/Contents/MacOS/firefox

Таким образом мы можем захватывать трафик практически любых приложений для macOS. К слову, для анализа трафика на интерфейсе всегда можно использовать Wireshark, который с версии 3.6.0 стал нативным приложением для архитектуры ARM.
WI-FI И ЗАХВАТ ПАКЕТОВ
Стандартный адаптер Wi-Fi, который ставят в макбуки, вполне неплохо работает в режиме мониторинга и позволяет захватывать пакеты на определенном канале. Продемонстрирую это на практике:
$ sudo ln -s /System/Library/PrivateFrameworks/Apple80211.framework/Versions/Current/Resources/airport /usr/local/bin/airport
$ airport -s # Смотрим сети
$ sudo airport -z # Отключаемся от активных сетей
$ airport <interface> sniff <channel>
$ ls /tmp/airportSniff*.cap
Однако со встроенным адаптером не выйдет использовать Wifite2 и прочие подобные утилиты для Linux, так как aircrack-ng на M1 пока что собрать нельзя. Если без них тебе не обойтись, придется использовать внешний адаптер и виртуальную машину.
WWW
Дополнительную информацию о работе с Wi-Fi стандартными методами macOS можешь узнать из отличного материала Павла Жовнера.
ПРОГРАММЫ ДЛЯ IOS
Напоследок — еще одно занятное отличие от машин с Intel. На «маках» с M1 возможен запуск приложений, разработанных для iOS, для этого достаточно зайти в App Store и выбрать соответствующую вкладку. Это удобно. Например, у меня дома есть несколько умных розеток, но, кроме мобильного приложения, способа управлять ими нет. По умолчанию все приложения для iOS доступны на «маках» с M1, но разработчики могут при желании запретить использование на десктопе.
ВЫВОДЫ
Могу с уверенностью сказать, что это один из лучших ноутбуков для работы. Использую его как замену десктопа с док‑станцией и внешним монитором (к сожалению, одним, но большим и широким). Прекрасная энергоэффективность и рекордная мощность обеспечены лучшим на сегодняшний день техпроцессом и архитектурой, где память расположена вплотную к процессору. Удобная и безопасная ОС довершает картину.
Бояться ARM не нужно. Приложения для Intel великолепно запускаются через Rosetta 2, виртуализация отлично работает практически без потери производительности, и даже Windows 11 ARM сможет транслировать приложения x86_x64 в код для ARM. Все твои приложения внутри Windows будут работать, вплоть до дебаггеров и Visual Studio с компиляцией проектов в x86_64.
Да, проблемы еще встречаются, но они решаемы, и разработчики активно трудятся над тем, чтобы через год‑другой о совместимости можно было не думать вовсе. Прошедший год показывает, что это вполне реально.
Подводя итог: Apple Silicon — это рабочее решение, которое я даже не думаю менять на что‑то другое. А на самый крайний случай всегда есть удаленный сервер с классической архитектурой.
Читайте ещё больше платных статей бесплатно: https://t.me/hacker_frei