Обновление ПО с помощью инструментов SSU
Обновление ПО «по воздуху» и реализуется при помощи SSU, который используется для администрирования репозиториев и доступа к ним. Сервис SSU использует oFono, чтобы проверить IMEI (International Mobile Equipment Identifier, Международный идентификатор мобильного оборудования) устройства, который будет использоваться, если возможно, в качестве уникального идентификационного номера устройства.
Использование SSU является частью общей архитектуры сотовой телефонии.
SSU в ОС Аврора
Отдельные установки ОС Аврора будут иметь доступ к различным коллекциям программного обеспечения для обработки изменений в следующих категориях:
- релизы: включая тестирование и разработку;
- аппаратное обеспечение: варианты прошивки для конкретного устройства;
- географическая область: местоположение встроенного программного обеспечения или программного обеспечения;
- лицензионное программное обеспечение: куплено или доступно для использования другим способом;
- персональные коллекции: репозитории сообщества или конкретных людей.
SSU предоставляет как программное обеспечение на устройстве, так и облачный сервис
для аутентификации устройств или пользователей и авторизации доступа к сервисам.
Программное обеспечение на устройстве регистрируется в облачной службе и управляет репозиториями
zypper/packagekit
с использованием предоставленных токенов доступа.
SSU предоставляет низкоуровневый "клей", чтобы предлагать «бесшовные обновления программного обеспечения» (Seamless Software Updates, SSU) с использованием стандартных компонентов (таких как Zypper и PackageKit). SSU предоставляет базовые рекомендации по настройке и выбору пакетов, но не участвует непосредственно в обработке пакетов.
В Аврора IDE можно запустить работу плагина SSU из меню: Инструменты → ОС Аврора → SSU Registration.
Команда ssu
ssu <command> [-command-options] [arguments]
Можно запустить ssu --help
, чтобы увидеть справку.
Управление репозиторием:
updaterepos, ur
— обновить файлы репозитория;repos, lr
— список настроенных репозиториев;[-m]
— формат вывода, подходящий для механизма запуска;[device]
— использовать репозитории дляdevice
;[flags]
— дополнительные флаги;rnd=<true|false>
— установить режим rnd или release (по умолчанию: взять с хоста);
addrepo, ar <repo>
— добавить репозиторий;[url]
— указать URL, если не настроен;
removerepo, rr <repo>
— удалить репозиторий из конфигурации;enablerepo, er <repo>
— включить репозиторий;disablerepo, dr <repo>
— отключить репозиторий.
Управление конфигурацией:
flavour, fl
— отображать использованный индикатор (только RnD);[newflavour]
— установить новый индикатор;
release, re
— отобразить используемый релиз;[-r]
— использовать релиз RnD;[newrelease]
— установить новый (RnD) релиз;
set
— отобразить глобальные переменные;[-r]
— работать только с переменными репозитория;<variable>
— отобразить значение<variable>
;<variable> <value>
— установить значение<variable>
равным<value>
.
Управление устройством:
status, s
— вывести статус регистрации и информацию об устройстве;register, r
— зарегистрировать это устройство;[-h]
— настроить пользователя;
update, up
— обновить учетные данные репозитория;[-f]
— обновить принудительно;
model, mo
— вывести название модели устройства.
Пример работы с SSU: установка недостающих зависимостей
В некоторых случаях разработчик должен будет добавить или включить репозитории для своей цели SDK,
если скрипт mb2
сообщает, что невозможно установить зависимость.
Для этого пользователь должен войти в ScratchBox2 в среде chroot SDK,
а затем выполнить действия:
-
Добавить репозитории:
ssu ar <repo_name> <repo_url>
-
Включить репозитории:
ssu er <repo_name>
-
Обновить информацию об устанавливаемом пакете:
zypper ref -f
ssu lr
может использоваться для вывода списка известных репозиториев,
а ssu rr <repo_name>
удалит репозиторий.
Следует отметить, что пакеты, специфичные для устройства или аппаратной платформы (особенно те, которые необходимы для создания пакетов, связанных с hybris), лучше всего устанавливать в отдельную цель SDK, чтобы избежать осложнений.
Функциональность SSU
SSU предлагает возможность запуска в специальном режиме RnD для использования во время разработки. Основные функции режима:
- использовать другой набор репозиториев, чем для опубликованного продукта;
- разрешить использование частных (защищённых паролем) хранилищ.
Цели реализации и рекомендации по ним:
- Поощрять обновлять свои устройства вместо того, чтобы перепрошивать их.
- Можно добавлять дополнительные шаги, необходимые после перепрошивки.
- Следует избегать штрафов за обновление устройства (например, лучше не добавлять дополнительное взаимодействие с пользователем, чтобы сохранить учетные данные устройства для обновления доступа).
- Оставлять последствия в области безопасности на низком уровне, не причиняя неудобств
пользователям.
- Если устройство потеряно, можно разрешить отключить устройство от получения дополнительных обновлений.
- Не стоит сохранять никакие учётные данные пользователей на устройстве, но по-прежнему можно отслеживать отдельные устройства и пользователей, с которыми они связаны.
- Оставаться как можно ближе к тому варианту, по которому работает управление хранилищем для опубликованного продукта.
- Выполнять реализацию, не добавляя патчи к исходным источникам, которые не будут приняты исходными источниками.
Регистрация устройства
- Клиент отправляет запрос регистрации с учетными данными LDAP в бэкэнд SSU; клиент забывает об учётных данных сразу после отправки запроса.
- Серверная часть SSU проверяет учётные данные и в случае успеха создаёт сертификат клиента, который отправляется клиенту.
- Клиент хранит сертификат и использует его для будущих запросов на аутентификацию. Это поведение учитывает специфические для пользователя регистрации для каждого устройства, которые могут быть индивидуально отозваны в бэкэнде SSU без сохранения части обычных данных учётной записи на устройстве.
Имя пользователя может быть отправлено вместе с доменом (например, user\@example
)
и бэкэндом SSU, отвечающим за сопоставление домена с другой организацией LDAP, базой данных
учётных записей или чем-либо ещё полезным для данной организации.
Домен будет храниться как на устройстве, так и на сервере SSU.
Домен позволяет использовать разные конфигурации репозитория для членов разных организаций,
а также ограничивать доступ к репозиторию для некоторых доменов.
Реализация на стороне клиента для данного алгоритма находится в libssu
, доступном через интерфейс
командной строки ssu и ssud DBUS API.
Защита хранилищ RnD
Zypper позволяет использовать только пары «пользователь/пароль» для аутентификации. Чтобы избежать обновления zypper, используется следующий метод аутентификации. Устройство извлекает токены аутентификации с сервера SSU после успешной аутентификации с помощью сертификата клиента.
Дополнительное преимущество данного метода — более простое развертывание репозиториев. Поддержание огромного списка отдельных учётных данных на сервере репозитория может быть сложным, особенно в CDN. Аутентификация по списку клиентских сертификатов в таком сценарии была бы ещё более проблематичной.
Для защиты хранилища необходимо регулярно менять пароли и сохранять пароли на сервере хранилища и синхронизировать бэкэнд SSU. Сроки действия старых и новых учётных данных должны немного перекрываться. Поскольку устройства совместно используют учётные данные для доступа к репозиторию, это слабое место в данной настройке, поэтому учётные данные следует менять достаточно часто, чтобы сделать их бесполезными, прежде чем они будут обнаружены или использованы при утечках.
Обновление учётных данных на устройстве
Обновление учётных данных на устройстве происходит в плагине распознавателя URL для Zypper. При обновлении хранилища:
- Перед возвратом URL SSU проверяет, требует ли этот репозиторий аутентификации.
- Проверяет время последнего обновления учётных данных.
- Если сохранённые учетные данные слишком старые, нужно выполнить аутентификацию в бэкэнде SSU с помощью сертификата клиента и запросить новый набор учётных данных.
- Сохранить учетные данные на диске для использования Zypper.
- Вернуть разрешённый URL и передать Zypper.
Серверная часть SSU проверяет, является ли пользователь действительным LDAP пользователем, и удаляет регистрацию для удалённых или заблокированных пользователей. Клиентская часть удаляет учётные данные на устройстве, если аутентификация на бэкэнде SSU оказалась неудачной.
Протокол, используемый SSU
Клиентская часть протокола, используемого SSU, реализована в libssu и консольной утилите ssu
.
Серверная часть сильно зависит от доступной инфраструктуры и недоступна публично.
$DEVICEID
в следующих примерах — это переменная, заполняемая клиентом SSU перед выполнением
запроса, заменяемая IMEI устройства, или MAC-адресом WLAN MAC-адреса или резервным кодом
UID устройства, аналогичным QDeviceInfo::uniqueDeviceID()
, если IMEI недоступен.
Регистрация устройства:
- Клиент отправляет запрос POST на https://ssu.example.com/ssu/device/$DEVICEID/register.xml.
- Клиент ОБЯЗАН проверять сертификат сервера по настроенному CA для сервера SSU.
- Клиент ОБЯЗАН отправлять базовую информацию об аутентификации HTTP вместе с запросом, содержащим данные учётной записи LDAP, запрашиваемые у пользователя.
- Клиент НЕ ДОЛЖЕН сохранять учетные данные LDAP, полученные от пользователя на устройстве.
- Клиент МОЖЕТ отправить дополнительные параметры в теле запроса в виде типа контента
application/x-www-form-urlencoded
. Допустимые параметры:deviceModel
, необязательно, строка, определяющая регистрируемое устройство;versionId
, необязательно, число, указывающее версию протокола. Если установлено, сервер ДОЛЖЕН ответить либо запрошенной версией, либо кодом ошибки HTTP;domain
, необязательно, строка, указывающая домен для регистрации (например, "example", "example-investor", "example-developer");
- Сервер отвечает HTTP-статусом 200 в случае успеха или соответствующим кодом HTTP-ошибки
в случае ошибки.
- В случае успеха сервер ОБЯЗАН включать и XML-ответ, в том числе:
certificate
, обязательно, строка, содержащая сертификат клиента SSL в формате PEM;privateKey
, обязательно, строка, содержащая закрытый ключ SSL в формате PEM;deviceId
, обязательно, строка, содержащая IMEI устройства или уникальный идентификатор;action
, обязательно, строка, содержащая запрошенное действие;protocolVersion
, обязательный, число, указывающее версию протокола, используемого сервером. Если клиент запросил конкретную версию, сервер ОБЯЗАН удовлетворить запрос.
- В случае успеха, если идентификатор устройства уже зарегистрирован, сервер МОЖЕТ включить
элемент
replaces
в ответ XML, включая:user
, обязательно, строка, содержащая имя пользователя, на которое устройство было зарегистрировано ранее.
- В случае успеха сервер ОБЯЗАН включать и XML-ответ, в том числе:
Примеры допустимых ответов от сервера:
<response>
<protocolVersion>1</protocolVersion>
<action>register</action>
<certificate>-----BEGIN CERTIFICATE-----
MIIDkjCCAnoCCQD/t7yBlPR2azANBgkqhkiG9w0BAQUFADCBijESMBAGA1UEAxMJ
bG[..]</certificate>
<privateKey>-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,306FB5F5BEC695CC
02UJRwd8euWrs/ZKMoTjFHedvQLYjbC7MTtdiOytAmLV5eGiP27WWg07E67FgUv2
GEiTCDb2pXDmiTR[...]<privateKey>
<deviceId>da39a3ee5e6b4b0d3255bfef95601890afd80709</deviceId>
</response>
<response>
<protocolVersion>1</protocolVersion>
<action>register</action>
<certificate>-----BEGIN CERTIFICATE-----
MIIDkjCCAnoCCQD/t7yBlPR2azANBgkqhkiG9w0BAQUFADCBijESMBAGA1UEAxMJ
bG[..]</certificate>
<privateKey>-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,306FB5F5BEC695CC
02UJRwd8euWrs/ZKMoTjFHedvQLYjbC7MTtdiOytAmLV5eGiP27WWg07E67FgUv2
GEiTCDb2pXDmiTR[...]<privateKey>
<deviceId>da39a3ee5e6b4b0d3255bfef95601890afd80709</deviceId>
<replaces>
<user>sampleuser</user>
</replaces>
</response>
Обновление учётных данных:
- Клиент отправляет запрос GET на https://ssu.example.com/ssu/device/$DEVICEID/credentials.xml.
- Клиент ОБЯЗАН отправить сертификат с запросом.
- Клиент НЕ ДОЛЖЕН отправлять какие-либо данные учётной записи LDAP (о которых он не должен знать в любом случае, на данный момент).
- Клиент МОЖЕТ отправить дополнительные параметры в качестве параметров URL.
Допустимые параметры:
versionId
, необязательно, число, указывающее версию протокола. Если установлено, сервер ДОЛЖЕН ответить либо запрошенной версией, либо кодом ошибки HTTP.
- Сервер отвечает HTTP-статусом 200 в случае успеха или соответствующим кодом HTTP-ошибки
в случае ошибки.
- В случае успеха сервер ОБЯЗАН включать и XML-ответ, в том числе:
credentials
, обязательно, могут использоваться несколько раз, элемент с атрибутомscope
содержит;username
, обязательно, строка, указывающая новое имя пользователя;password
, обязательно, строка с новым паролем;
action
, обязательно, строка, содержащая запрошенное действие;protocolVersion
, обязательно, число, указывающее версию протокола, используемого сервером. Если клиент запросил конкретную версию, сервер ОБЯЗАН удовлетворить запрос.deviceId
, обязательно, строка, содержащая IMEI устройства или уникальный идентификатор.
- В случае успеха сервер ОБЯЗАН включать и XML-ответ, в том числе:
Пример допустимого ответа сервера:
<response>
<protocolVersion>1</protocolVersion>
<action>credentials</action>
<credentials scope="example">
<username>uNaepiu9</username>
<password>Aeng5vah</password>
</credentials>
<deviceId>da39a3ee5e6b4b0d3255bfef95601890afd80709</deviceId>
</response>