Всем привет! Меня зовут Эрик, я работаю инженером технической поддержки в компании Ринго. Это первая часть статьи о пакетах (packages, которые у нас часто так и называют “пэкиджи”) в экосистеме Apple. В этом материале мы разберём, как устанавливаются приложения в macOS, чем отличаются форматы DMG и PKG и подробно рассмотрим устройство установочных пакетов. Мы изучим их структуру, роль Gatekeeper, затронем цифровую подпись и нотаризацию, а также изучим способы инспектирования пакетов перед установкой. 

Все темы будут подкреплены примерами, чтобы материал был понятен и полезен. Если вам интересно — поехали!

Что такое DMG?

DMG (Disk Image) — это образ диска в macOS, виртуальный контейнер для приложений и файлов. После загрузки такой файл монтируется как отдельный диск (Рис.1), отображаясь в Finder.

Рис.1 -  Kiwix
Рис.1 - Kiwix

Структура: внутри DMG обычно лежит само приложение (.app), псевдоним (alias - ссылка, ярлык) на папку Applications и иногда документация или графическое оформление, чтобы при монтировании образа диска в его окошке появлялось подготовленное разработчиком изображение (например, картинка с надписью “перетащите приложение в папку “Программы”).

Установка: достаточно открыть DMG и перетащить приложение в /Applications(Рис.2). 

Рис.2 - Пример экрана установки приложения из DMG.
Рис.2 - Пример экрана установки приложения из DMG.

Для монтирования .dmg-образов права администратора не требуются, однако сама программа при первом запуске может запросить доступ к системным ресурсам. Важно учитывать, что при копировании приложения в каталог /Applications система, как правило, запрашивает права администратора. Если же использовать папку ~/Applications в домашней директории пользователя, то установка выполняется без дополнительных привилегий.

Об этом способе знают не все, так как в большинстве .dmg-образов присутствует ярлык именно на системный каталог /Applications. Из-за этого пользователи по привычке пытаются перенести приложения туда, даже если у них нет прав администратора. На самом деле практически любое приложение можно установить в личную папку ~/Applications, и оно будет работать.

Преимущества образов дисков:

  • Простой и привычный для пользователя формат.

  • Удобное распространение.

Недостатки:

  • Ручная установка.

  • Не подходит для сложных сценариев с множеством файлов и скриптов.

  • Кроме того, существуют приложения, которые внешне выглядят, как обычный .app внутри .dmg, но на самом деле являются установщиком. При запуске такого .app запускается инсталлер, который может загружать дополнительные файлы из интернета и устанавливать программу не только в /Applications. Примером такого подхода может служить Dropbox.

Использование: DMG идеально подходит для большинства приложений, например, Google Chrome, Slack, WhatsApp, VLC, BBEdit или Kiwix, как на картинке выше. Чаще всего именно с DMG сталкиваются обычные пользователи macOS, если скачивают программу с сайта разработчика, а не устанавливают через AppStore. Мы не будет подробно останавливаться на DMG, так как эта статья про пакеты.

Что такое PKG и зачем они нужны

В экосистеме Apple пакеты (packages) — это стандартизированный способ распространения и установки программного обеспечения. В отличие от .dmg и простого перетаскивания .app файлов в папку Applications, пакеты позволяют:

  • выполнять сложные операции установки с проверкой зависимостей;

  • размещать файлы в различных системных директориях;

  • запускать пре- и пост-установочные скрипты;

  • обеспечивать корректную деинсталляцию компонентов;

  • интегрироваться с корпоративными системами управления, такими как MDM (Mobile Device Management) для автоматизированного развертывания на множество устройств.

Установка пакетов с помощью Installer.app

Наиболее распространённый способ установки пакета — двойной щелчок по файлу pkg, что автоматически запускает приложение по умолчанию для расширения .pkg: Установщик (Installer.app), расположенный в /System/Library/CoreServices/. Прямое открытие Установщика требуется редко. 

Для записи файлов в системные каталоги и выполнения встроенных скриптов Установщик запрашивает права администратора. Его интерфейс состоит из нескольких панелей, их содержание и порядок определяется разработчиком пакета. В минимальной конфигурации пакета пользователь увидит стандартные элементы установки (Рис.3):

Рис.3 - Интерфейс инсталлятора пакета Go
Рис.3 - Интерфейс инсталлятора пакета Go

Файл пакета может содержать как полезную нагрузку (Payload), так и скрипты, либо их комбинацию. Полезная нагрузка представляет собой архив всех файлов, которые будут установлены в систему, вместе с описанием их расположения и назначенных прав доступа. Установочные скрипты могут выполняться как до, так и после установки полезной нагрузки. Разработчик пакета также может включать дополнительные скрипты или бинарные файлы, используемые в процессе установки. Кроме того, дистрибутивный пакет может содержать изображения и текстовые файлы, например, лицензионные соглашения, которые влияют на отображение интерфейса в Installer.app.

Когда вы открываете файл установщика пакета с помощью приложения Installer.app, вы можете выбрать из строки меню «Файл» → «Показать файлы…», чтобы получить список файлов в полезной нагрузке (Рис.4).

Рис.4 - Перечень файлов пакета
Рис.4 - Перечень файлов пакета

Поскольку этот список может быть очень обширным, существует поле поиска для фильтрации его содержимого.

Если во время установки возникает ошибка или вы хотите проследить ход процесса, можно выбрать в меню «Окно» -> «Журнал установщика» (Рис.5).

Рис.5 - Журнал установщика пакета
Рис.5 - Журнал установщика пакета

Инструмент командной строки installer

Вы можете использовать терминал для установки .pkg. Поскольку все системы управления пакетами вызывают команду installer при их установке, это считается стандартным способом тестирования пакета перед его установкой конечным пользователем.

Самая простая команда выглядит так:

sudo installer -package Firefox.pkg -target /

Эта команда устанавливает пакет Firefox.pkg на системный или текущий загрузочный том (корневой /). Вы можете указать другой том или диск в качестве целевого, используя аргумент -target. Учтите, что многие пакеты, созданные без соблюдения стандартов, могут работать некорректно или выдавать ошибки при установке на том, отличный от /, поэтому рекомендуется тщательно тестировать такие случаи.

В /var/log/install.log сохраняются записи о процессе установки, поэтому вы можете отслеживать или просматривать журнал через терминал.

Установка пакета через командную строку не требует автоматической перезагрузки или выхода из системы, даже если пакет подразумевает это. Если перезагрузка нужна, её придётся выполнить или запланировать вручную.

Вы также можете использовать флаг -allowUntrusted для команды installer, который отключает проверку подписи и позволяет устанавливать пакеты с недействительным, отозванным или истекшим сертификатом. Об этом я подробнее расскажу далее.

Gatekeeper, нотаризация и цифровая подпись в macOS

В macOS безопасность приложений обеспечивается тремя ключевыми технологиями: Gatekeeper, цифровая подпись и нотаризация.

Gatekeeper

Gatekeeper появился ещё в OS X 10.7.5 Lion и предназначен для защиты пользователя от случайной установки потенциально вредоносного ПО. Он проверяет, что пакет или приложение подписаны зарегистрированным разработчиком с сертификатом, выданным Apple. Если пакет не подписан или подпись не заверена, Gatekeeper блокирует установку. Пользователь видит предупреждение, как на изображении ниже (Рис.6).

Рис.6 - Предупреждение macOS при установки пакета от неизвестного разработчика
Рис.6 - Предупреждение macOS при установки пакета от неизвестного разработчика

Проверить сертификат подписи пакета можно через значок замка в верхнем правом углу окна установщика (Рис.7). С настройками по умолчанию Gatekeeper откажется устанавливать неподписанный пакет, предотвращая случайную установку вредоносного ПО.

Рис.7 - Проверка сертификата подписи пакета
Рис.7 - Проверка сертификата подписи пакета

Цифровая подпись

Цифровая подпись подтверждает подлинность разработчика и целостность пакета. Для её создания требуется сертификат Developer ID Installer от Apple. Без подписи пакеты блокируются Gatekeeper. Истекшие или отозванные сертификаты не работают.

Нотаризация

С macOS 10.14 Apple добавила нотаризацию — дополнительную автоматизированную проверку на наличие вредоносного кода. Разработчик подписывает пакет своим идентификатором и загружает его в нотариальную службу Apple. Apple сканирует программное обеспечение, проверяет код на соответствие требованиям и наличие известных угроз. После успешной проверки пакет получает «нотариальный билет», который позволяет Gatekeeper подтвердить его безопасность.

Если пакет не подписан или не заверен нотариально, пользователи могут обойти Gatekeeper через контекстное меню Finder, выбрав «Открыть» (не работает начиная с macOS 15), либо в настройках безопасности через Open Anyway (всё равно открыть) (Рис.8). Это допустимо для пакетов �� открытым исходным кодом или внутреннего ПО, но для официального распространения конечным пользователям подпись и нотаризация остаются обязательными.

Рис.8 - Обход Gatekeeper через параметры безопасности
Рис.8 - Обход Gatekeeper через параметры безопасности

Инспектирование пакетов с pkgutil

При установке .pkg на macOS инсталлятор запускает его с правами root. Это означает, что любой скрипт или исполняемый файл внутри пакета получает полный доступ к системе. Поэтому крайне важно, чтобы администратор заранее проверял, что именно будет установлено и выполнено.

В macOS уже есть встроенные инструменты для работы с пакетами, большинство из которых работают через Терминал. Например, в предыдущем разделе мы использовали команду installer. Сейчас рассмотрим pkgutil — инструмент, который позволяет исследовать пакеты до установки, просматривать их содержимое, а также проверять уже установленные пакеты (Рис.9).

Помимо встроенных средств, существуют сторонние утилиты, позволяющие проверять содержимое .pkg, но об этом позже. 

Ниже приведены полезные команды для работы с уже установленными пакетами. Более подробную информацию можно найти в руководстве: man pkgutil.

Список установленных пакетов:

pkgutil --pkgs

Эта команда выводит список идентификаторов пакетов. Эти идентификаторы задаются разработчиком и, как правило, используют схему обратной DNS-нотации (пример com.ringo.agent). С их помощью система определяет, что является новым пакетом, что — обновлением, а что уже установлено.

Сведения о конкретном пакете:

pkgutil --pkg-info com.example.myapp

Перечень файлов, установленных пакетом:

pkgutil --files com.example.myapp

Определение, каким пакетом был установлен файл:

pkgutil --file-info /Applications/MyApp.app

Пример выполнения команд (Рис.9).

Рис.9 - Пример использования команды pkgutil
Рис.9 - Пример использования команды pkgutil

Как устроен пакет

Как мы уже говорили ранее, плоские пакеты (flat package) сжаты в единый архивный файл. Чтобы заглянуть внутрь, можно использовать pkgutil для его распаковки:

pkgutil --expand Firefox.pkg ~/Firefox

Анализ метаданных: файл Distribution

В корне распакованной папки лежит файл Distribution, это XML с метаданными установки (Рис.10). Откройте его в любом текстовом редакторе (PS: я буду использовать VS code). Здесь вы найдете:

  • pkg-ref: указывает версию и идентификатор пакета;.

  • options: описывает доступные или отключенные опции в установщике.

Рис.10 - Содержимое файла Distribution
Рис.10 - Содержимое файла Distribution

В некоторых пакетах есть папка Resources, которая может содержать дополнительные файлы: фоновое изображение для интерфейса (Рис.11) и лицензии на разных языках.

Рис.11 - Фоновое изображение в пакете Go
Рис.11 - Фоновое изображение в пакете Go

Вложенные пакеты: просмотр org.golang.go.pkg

Внутри основного пакета находится вложенный пакет — org.golang.go.pkg. Его содержимое уже было автоматически распаковано командой pkgutil --expand, поэтому повторно выполнять её не требуется. Просто перейдите в этот пакет. Если вы используете Finder, кликните по файлу правой кнопкой мыши и выберите пункт Show Package Contents (Показать содержимое пакета). Внутри вы найдете четыре основных элемента.

1. PackageInfo: метаданные пакета

Это еще один XML-файл . Самая важная информация содержится в корневом теге <pkg-info>: уникальный идентификатор пакета, его версия, уровень привилегий для установки, сведения о формате и генераторе пакета, количество файлов и размер полезной нагрузки, а также ссылки на скрипты, выполняемые до и после установки (Рис.12).

Рис.12 - Содержимое файла PackageInfo
Рис.12 - Содержимое файла PackageInfo

2. Payload: архив с файлами

Здесь хранится основная полезная нагрузка — файлы, которые будут скопированы при установке. Чтобы извлечь их вручную:

tar xvf Payload

Tar распакует все файлы в текущую директорию (Рис.13). 

Рис.13 - Распакованные файлы полезной нагрузки пакета
Рис.13 - Распакованные файлы полезной нагрузки пакета

3. Scripts: скрипты установки

Папка “Scripts” содержит скрипты preinstall и postinstall (Рис.14), которые выполняются до и после копирования файлов соответственно. Не все пакеты имеют оба скрипта, некоторые обходятся и вовсе без них. Разработчики могут добавить в эту папку дополнительные исполняемые файлы или ресурсы, которые вызываются этими скриптами. Всегда читайте код: они могут менять разрешения, регистрировать сервисы или даже запускать внешние команды.

Рис.14 - Cкрипты preinstall и postinstall пакета Go
Рис.14 - Cкрипты preinstall и postinstall пакета Go

4. Bom: смета файлов

Файл Bom (Bill of Materials) — список всех файлов из Payload с метаданными: путь, режим доступа (permissions), UID/GID владельца, размер и 32-битная CRC-сумма (для файлов). Чтобы прочитать его:

lsbom Bom

Вывод — таблица с колонками (Рис.15). Для кастомизации формата загляните в man lsbom — там полно опций.

Рис.15 - Пример вывода команда lsbom
Рис.15 - Пример вывода команда lsbom

Поскольку Bom часто нужен, pkgutil упрощает задачу:

 pkgutil --bom go1.25.1.darwin-arm64.pkg

Это извлечет Bom во временный файл и выведет путь к нему. Комбинируйте с lsbom для удобства:

lsbom $(pkgutil --bom go1.25.1.darwin-arm64.pkg)

А для быстрого просмотра списка файлов в пакете без подробностей используйте:

pkgutil --payload-files go1.25.1.darwin-arm64.pkg

Эта опция эквивалентна lsbom с флагом -s (только пути). Если нужно больше деталей, вернитесь к полному синтаксису с опциями lsbom.

Инспектирование пакетов – Suspicious Package

Вы можете получить много информации из пакета с помощью инструментов pkgutil и lsbom, но это требует выполнения нескольких действий и занимает больше времени. Существуют приложения, которые делают процесс гораздо проще. Например, мне нравится Suspicious Package (Рис.16).  

Рис.16 - Информация о пакете Go в приложении Suspicious Package
Рис.16 - Информация о пакете Go в приложении Suspicious Package

В целом я не буду подробно описывать функционал этого приложения, так как он в основном повторяет то, что я показывал с pkgutil и lsbom, только через графический интерфейс. Вы можете скачать приложение и попробовать всё самостоятельно.

Заключение

В этой статье мы рассмотрели процесс установки приложений в macOS и особенности форматов DMG и PKG. Вы узнали, как устроены установочные пакеты, из чего состоит их полезная нагрузка, какие скрипты они могут содержать, и как инспектировать пакеты с помощью встроенных инструментов pkgutil, lsbom. Мы также разобрали, как Gatekeeper, цифровая подпись и нотаризация обеспечивают безопасность приложений и защищают систему от вредоносного ПО.

В следующих статьях мы покажем, как пересобрать пакет и внести в него изменения, преобразовать DMG в PKG, а также как распространять пакеты в корпоративной среде