Заглядываем под капот Chrome OS

Что десктопные приложения, да и сам десктоп рано или поздно переедет в веб, было понятно едва ли не после рождения JavaScript, поэтому появление Chrome OS во многом предсказуемо. И что облачную ОС выпустила именно Google, тоже абсолютно закономерно. Но давай попробуем отойти от бесконечных дебатов о будущем десктопа, разжигаемых консервативной частью айтишников, и посмотрим на Chrome OS с точки зрения технической реализации.

Дорога в облака

Google анонсировала Chrome OS летом 2009 года и уже в ноябре продемонстрировала ее публике и выложила исходники в открытый доступ под именем Chromium OS. Тогда операционка была довольно проста и представляла собой запущенный на полный экран браузер Chrome, работающий поверх сильно урезанного дистрибутива Ubuntu. В ней были реализованы все те же механизмы изоляции вкладок браузера и плагинов, все та же многопроцессная модель работы браузера, но в целом ничем особенным операционка не отличалась.

На протяжении следующих пяти лет Google непрерывно, но не особо афишируя свою работу развивала Chrome OS. Попутно она выпускала так называемые Chromebook’и и Chromebox’ы, ставшие популярными среди юниксоидов, которые сносили Chrome OS сразу после покупки. Постепенно Gooogle отказалась от Ubuntu в пользу Gentoo (судя по всему - чтобы получить возможность сборки пакетов без «бесполезных» для нее зависимостей и плюшки Hardened-версии дистрибутива) и заменила-таки однооконный режим на стандартный для десктопов многооконный со стандартной панелью задач снизу. Google сознательно отказалась от него в первых версиях Chrome OS, поскольку ОС была ориентирована на нетбуки с их небольшими экранами, но, судя по всему, пользователи этого не оценили.

Появились и офлайновые веб-приложения (доступные также в обычном Chrome) и, наконец, поддержка ряда приложений для Android. Последнее событие стало вполне ожидаемым после того, как руководство разработкой обеих операционок перешло в руки Сундара Пичая (Sundar Pichai), который всегда был ответствен за развитие Chrome, Chrome OS и веб-приложений Google.

Chrome OS развивается вместе с самим браузером, поэтому их версии совпадают. На момент написания статьи это была версия 41, но в отличие от браузера у Chrome OS нет готовых сборок для установки за исключением официально поддерживаемых Chromebook’ов и Chromebox’ов. Однако в Сети вполне можно найти неофициальные сборки на базе исходников Chromium OS. Например, всегда можно скачать ежедневные сборки для x86, x64 и ARM. Достаточно записать одну из них на флешку и загрузиться с нее. Однако надо быть готовым, что не все компоненты машины заведутся (в моем случае отвалился тачпад). К тому же Chromium OS не поддерживает Flash, DRM и Netflix, зато в ней есть доступ к консоли с правами root.

Базовые концепции

Ключевая идея Chrome OS в том, что по большому счету это ОС для тонких клиентов, где все, кроме графического интерфейса и браузера, находится в Сети. Фактически без подключения к интернету и аккаунта Google операционка даже не пустит пользователя внутрь (по крайней мере в первый раз). Файлы Google предлагает сохранять в свой Google Drive (покупателям Chromebook’ов компания дает 100 Гб), настройки, расширения и установленные приложения синхронизируются стандартным для браузера Chrome способом. Для печати предлагается использовать Google Cloud Print.

В российских реалиях такой подход ничего не дает и создает массу трудностей, да и в остальном мире тоже. Но Chrome OS - это задел Google на будущее, и такая модель работы позволила программистам реализовать ряд интересных архитектурных решений и подходов к обеспечению безопасности. О чем мы и поговорим в оставшейся части статьи.

Все начинается с BIOS

Несмотря на то что Chromium OS может работать на компах со стандартным BIOS, Chromebook’и базируются на CoreBoot. И это не просто одна из их технических особенностей, а намеренная оптимизация. CoreBoot - полностью 32-битный «BIOS», лишенный балласта из большого количества кода инициализации оборудования, бесполезного в наши дни. Вкупе с оптимизациями Google он способен выполнить холодный старт от нажатия кнопки питания до загрузки ядра буквально за доли секунды.

Далее CoreBoot находит загрузочный раздел GPT и загружает в память бинарник, содержащий бутлоадер u-boot (он обычно используется во встраиваемой электронике) и ядро Linux, после чего отдает управление u-boot, и начинается почти стандартная для Linux-дистрибутивов процедура загрузки, включающая в себя монтирование корневого раздела, запуск демонов, графической системы и, наконец, интерфейса.

Интересно во всей этой процедуре то, что у загрузчика с ядром и корневой ФС есть «резервные копии» в отдельных разделах, и эта особенность используется для обновления ОС и отката в случае сбоя. Во время автоматического обновления Chrome OS вообще не трогает текущую установку, а вместо этого прописывает новую версию ОС в те самые «резервные разделы», которые становятся «текущими» после перезагрузки. В случае сбоя при загрузке новой версии ОС произойдет обратная перемена местами и юзер сможет получить доступ к заведомо рабочей системе (система сама способна понять, что она успешно загрузилась, и поставить соответствующий флаг на текущие GPT-разделы).

Более того, на каждом этапе передачи управления от одного компонента к другому (например, от CoreBoot к u-boot) происходит сверка цифровой подписи (в случае корневой ФС - поблочная сверка контрольных сумм на лету), при несовпадении которой система также откатится к прошлой версии. Это работает, потому что разделы с текущей версией системы монтируются только на чтение и пользователь даже случайно не сможет их изменить.

INFO

EEPROM Chromebook’а содержит не только две копии firmware (одна из которых резервная), но и неперезаписываемый recovery firmware, позволяющий загрузить систему с USB-флешки или карты памяти и произвести проверку и восстановление системы.

Кроме CoreBoot, EEPROM любого Chromebook’а включает в себя SeaBIOS - открытую реализацию BIOS, которая позволяет без лишних хлопот установить на устройство Windows или Linux.

Вездесущий Linux

Текущие версии Chrome OS основаны на Gentoo Linux с тем исключением, что вместо стандартной для данного дистрибутива системы инициализации OpenRC здесь задействован убунтовский Upstart. По сравнению с обычным дистрибутивом Linux система сильно урезана, поэтому загружать тут особого нечего и стартует она буквально за секунду. Обычного терминала нет, но есть местный shell crosh, доступный по.

Выполнив в нем команду shell, мы получим доступ к стандартному bash с правами root (в Chromium OS, естественно) и сможем исследовать систему. Здесь есть всем нам известные демоны rsyslogd, dbus-daemon (D-Bus используется в Chrome OS для обмена данными между браузером и остальными частями системы), wpa_supplicant (аутентификация в Wi-Fi-сетях), dhcpcd, иксы, ModemManager (работа с 3G-модемами), udev, ConnMan (управляет соединениями с сетью) плюс более десятка специфичных для Chrome OS демонов, отвечающих в том числе за обновление системы (update_engine), работу с TPM-модулем (chapsd), шифрование домашнего каталога (cryptohomed), отладку (debugd) и другие задачи.

Особое место здесь занимает демон session_manager, ответственный за инициализацию высокоуровневой части ОС. В его задачи входит:

  1. Запустить X-сервер.
  2. Инициализировать переменные окружения для браузера Chrome.
  3. Создать необходимые каталоги, файлы и правила cgroups для Chrome.
  4. Запустить Chrome.
  5. Вызвать Upstart-событие login-prompt-visible, в результате чего на экране появится окно логина.

Во время этого процесса действительно не запускаются какие-либо компоненты, отвечающие за формирование «рабочего стола» (за исключением окна логина). Его отрисовкой занимается сам браузер, полагаясь на фреймворк Aura, включающий в себя низкоуровневые функции для работы с графикой и окнами (с хардварным ускорением через DRI) и окружение рабочего стола Ash, которое отрисовывает панель задач, декорации окон, Google Now и другие стандартные элементы интерфейса ОС. Являясь частью браузера Chrome, они, тем не менее, работают внутри нескольких независимых процессов.

INFO

В случае сбоя загрузки системы, который регистрируется, если процесс браузера не может быть запущен в течение 30 с, Chromium OS автоматически запускает SSH-сервер и перезапускает опрос ядра на наличие оборудования с помощью команды udevtrigger.

Благодаря интеграции Aura и Ash в сам Chrome получить рабочий стол Chrome OS можно в любой ОС, запустив браузер с флагом —open-ash.

Безопасность

Помимо уже рассмотренных методов обеспечения безопасности и целостности данных, таких как безопасная загрузка системы, зашифрованный домашний каталог с кешированными данными (шифрование выполняется отдельно для каждого юзера), а также стандартных для браузера Chrome методов изоляции процессов, плагинов и Native Client от системы (здесь используется механизм seccomp-bpf, позволяющий фильтровать обращения к системным вызовам), в Chrome OS задействован ряд других подходов к обеспечению безопасности.

Центральное место среди них занимает minijail - небольшое приложение, применяемое для изоляции системных сервисов (демонов) и других компонентов системы. Это очень гибкое приложение, которое позволяет выполнять такие функции, как наделение приложения «возможностями» или их отзыв (capabilities - специальная подсистема ядра Linux для наделения не SUID-бинарников некоторыми возможностями root), запереть его в chroot, отозвать права root, установить лимиты на ресурсы (rlimits), разместить процесс в выделенных пространствах имен (на манер LXC и Docker) и применить к нему правила cgroups.

Если взглянуть на вывод ps aux|grep minijail (см. скриншот) в работающей системе, то можно заметить, что minijail используется для запуска демонов с теми или иными настройками, но число таких демонов по отношению ко всем работающим в системе не так уж и велико. Судя по документам разработчиков , в будущем minijail планируют существенно расширить и применять его к гораздо большему количеству компонентов системы, включая графический стек и Chrome. Пока же что есть, то есть.

Из остальных средств обеспечения безопасности можно отметить применение флагов компилятора для минимизации риска срыва стека (-fno-delete-null-pointer-checks, -fstack-protector, FORTIFY_SOURCE), задействование «усиленного» механизма ASLR (Address space layout randomization) в ядре Linux (патч PaX), использование capabilities вместо SUID-бинарников где это возможно, ограничения на загрузку модулей ядра, использование модуля TPM (в Chromebook’ах) для хранения ключей шифрования диска и пароля пользователя, запрет на запуск обычных ELF-бинарников юзером и некоторые другие вполне стандартные техники, многие из которых пересекаются с Android и Hardened Gentoo.

Выводы

Конечно, Chrome OS гораздо сложнее, чем я смог описать в этой статье. В ней есть множество нюансов и огромное количество интересных идей. Обо всем этом можно почитать на сайте проекта Chromium , благо авторы открыты по отношению к сторонним разработчикам и написали весьма неплохую документацию.