Ночной update «как в лаборатории»: образ с флешки, который вчера вставал на стендовый контроллер той же линейки. На объекте после перезапуска чёрный экран, RUN не загорается, веб-морда молчит, пинг иногда есть, иногда нет. В сервисном меню - отказ подписи или «image not trusted». Заводская поддержка спрашивает: «чей ключ в цепочке, ваш или наш?» На площадке никто не отвечает. Образ «чуть доработанный» интегратором. Контроллер не кирпич в смысле расплавленной платы, но и не устройство, которое смена вернёт кнопкой. Линия стоит, пока ищут подписанный откат и человека, у которого есть право его залить.
Разбираем secure boot на ARM-контроллере как цепочку доверия, а не как галочку «ИБ в паспорте». Почему устройство отказывается брать прошивку, кто владеет ключами у завода и у заказчика, чем это стыкуется с обновлением по сети, как не получить «кирпич» из хороших намерений. Здесь нет пошагового чек-листа download проекта и online change: процедура окна смены, retain и отката application - отдельная тема. Фокус - криптографическая загрузка образа и ключи. Нет инструкций, как обойти подпись.
Короткий ответ
Secure boot на ARM-ПЛК - это проверка подписи каждого звена от неизменяемого boot ROM до ядра и, часто, до корневой ФС и runtime: неподписанный или «не тем» ключом подписанный образ устройство не стартует. Отказ выглядит как «прошивку не берёт», чёрный экран, boot loop, сервисный код ошибки - не как обычный STOP прикладной программы.
Ключи почти всегда принадлежат заводу-изготовителю контроллера (или вендору SoC): заказчик получает право ставить только официальные пакеты. Свой ключ у площадки бывает в контуре доверенного ПАК и в отдельных линейках с заказной прошивкой; это не «галочка в web». Обновление по сети не отменяет подпись: канал доставки может быть Ethernet, проверка - локальная, тем же ключом, что и с USB.
До update сверяют: включён ли secure boot на этом экземпляре, какой ключ в цепочке, совпадает ли пакет с моделью и ревизией, есть ли подписанный откат, кто имеет право залить recovery. Лабораторный unsigned-образ, который «удобно отлаживать», на объекте с включённой цепочкой не друг, а причина простоя.
Цепочка доверия: не антивирус, а кто имеет право стартовать
На ARM-системе первого уровня доверия обычно несколько. Инженеру АСУ достаточно модели, без курса по fuse SoC.
Нулевой уровень - код в ROM кристалла. Его не обновляют «с флешки цеха». Он знает публичный ключ или хеш ключа, записанный на заводе (fuse, OTP). Если эта точка скомпрометирована или не совпадает с образом - дальше ничего не проверяют, устройство не живёт как ПЛК.
Первый загрузчик проверяет подпись второго (U-Boot или аналог). Второй проверяет ядро и device tree. Дальше - корневая ФС: dm-verity, подписанный squashfs, либо проверка пакета runtime. Прикладной проект (application) может жить в отдельной доверенной зоне или, наоборот, не входить в secure boot вообще: тогда «не берёт прошивку» и «не берёт проект» - разные отказы. Их путают на разборе, потому что оба случаются после «залили с ноутбука».
Linux RT как среда исполнения цикла не равна включённому secure boot. Контроллер может быть с Linux RT и с открытой загрузкой: предсказуемый цикл есть, цепочки подписи нет. И наоборот: secure boot не делает из ядра ОСРВ. Пуск и FAT смотрят jitter и watchdog отдельно; перенос проекта с Windows-станции на Linux RT - тоже другой слой. База по runtime и ОС: Linux RT и перенос проекта, ОСРВ на пуске. Secure boot на этом фоне - ответ на вопрос «кто имеет право заменить ядро», не «успеет ли PID за 50 мс».
Что видит площадка, когда звено не сходится:
нет старта runtime, экран тёмен или логотип вендора зациклен;
индикатор не выходит в привычный RUN;
по Ethernet отвечает только загрузчик или не отвечает ничего;
в журнале сервисного канала - verify fail, bad signature, unknown key, rollback protection;
после «успешного» копирования файла обновления устройство уходит в reboot и не возвращается.
Rollback protection - отдельная ловушка. Даже правильно подписанный, но более старый образ система может отвергнуть, если монотонный счётчик версии в fuse/efuse ушёл вперёд. Откат «на прошлогоднюю прошивку с полки ЗИП» тогда не проходит, пока вендор не даст подписанный пакет с допустимой политикой отката или сервисную процедуру. ЗИП без учёта ключа и счётчика версии - ложное спокойствие.
Кирпич в бытовом смысле - плата, которую не оживить штатным recovery. На практике чаще «мягкий кирпич»: загрузчик жив, он отвергает payload. Это лечится подписанным recovery, если он есть, и кабелем, который регламент не запретил. Если первый загрузчик затёрли неполным update питания - это уже аппаратный сценарий, его не путают с «не та подпись». Питание и окно update остаются дисциплиной процедуры; криптография не спасает от обрыва на середине записи boot-раздела. Чек-лист сети, окна и отката application к этой дисциплине относится, но не заменяет вопрос ключа: обновление прошивки и проекта по сети.
Кто хранит ключи: завод, заказчик, никто на площадке
Три модели. В договоре должна быть одна, не «посмотрим по ходу».
Ключи завода. Типичный серийный ARM-ПЛК. Вендор подписывает образы своим закрытым ключом, публичная часть в устройстве. Площадка ставит только пакеты с портала поддержки или с диска поставки. Интегратор не «дособирает ядро». Плюс: нет церемонии ключей на заводе заказчика, меньше шансов потерять USB с секретом. Минус: зависимость от политики вендора и от того, что официальный пакет существует для вашей ревизии железа. Реестр российского изделия этот риск не снимает: подпись - про жизненный цикл ПО, не про страну сборки.
Ключи заказчика или совместная модель. Встречается в контуре доверенного ПАК, в спецпоставках, иногда как опция «customer key». Закрытый ключ не должен лежать в почте главного инженера и в папке «прошивки» на общем диске. Это HSM или хотя бы регламентированное хранилище с актом, список лиц, процедура выпуска пакета. Если ключ у интегратора «для удобства», через два года интегратор другой, а контроллеры принимают только его подпись. Доверенный комплекс как раз про связку железа, среды и правил оценки, а не про один контроллер с красивым словом «secure»: доверенный ПАК АСУ ТП. Secure boot - один кирпич такого контура. Сам по себе он не делает ПАК.
Лабораторная отладка без подписи. Стенд, unsigned, удобные пакеты. На объект этот режим не переносят «на время пуска». Включить secure boot после месяца жизни на unsigned - значит, следующее обновление обязано быть заводским, а локальные доработки ядра умрут. Выключить secure boot на серийном изделии часто нельзя без сервисной процедуры вендора, и это уже вопрос гарантии и ИБ, не «галочка для наладчика».
Кто на площадке должен уметь ответить за пять минут: включена ли цепочка на этом серийнике; чей ключ; где лежит последний подписанный образ и его хеш; есть ли recovery. Если ответы «в документации вендора, которую не скачивали», update по сети - лотерея.
Передача ключа «на флешке директору» не модель владения. Закрытый ключ, которым подписан boot, равен праву подменить ядро на всём парке. Его не копируют в проект CODESYS и не кладут рядом с application. Application подписывают другим контуром, если подписывают вообще. Смешение «ключ проекта» и «ключ загрузчика» в одном сейфе без описи - будущий отказ в 3 часа ночи: подпишут не тот артефакт.
Срок жизни ключа. Вендор ротирует сертификаты. Образ 2022 года может перестать приниматься политикой 2026-го, даже если файл с того же FTP. Перед парковым update читают bulletin: новый корневой ключ, нужно ли промежуточное «мостовое» обновление. Без моста часть парка останется на старой цепочке, часть уйдёт вперёд, ЗИП разъедется.
Прошивка, которую «не берёт»: не всегда злой умысел
Список причин, которые на объекте встречаются чаще атаки.
Образ от другой модели или ревизии платы: подпись сходится на ключе линейки, загрузчик сравнивает board id / dtb и отказывается. Сообщение может быть тем же «verify failed», что и при чужом ключе. Смотрят точный код, не общее «secure boot ругается».
Пакет обрезан при копировании, хеш не тот. Подпись считается по полному образу. Обрыв USB, антивирус, который «почистил», почтовый архив с битым zip.
Update application приняли за update firmware. Проект залился, ядро старое, или наоборот: ждали программу, а сложили системный пакет не туда. После ребута - смесь. Разделение «runtime / application» в голове наладчика должно быть до файла, не после.
Не та среда исполнения в образе. На одном железе заказывают разные runtime. Образ с «чужой» средой, даже подписанный заводом для другой комплектации, устройство имеет право не взять. Это не повод считать среды иерархией «ПЛК против SCADA»: это комплектация изделия и подпись пакета под неё.
Часы и сертификаты. Реже на встроенном boot, чаще если проверка тянет цепочку X.509 с датами. Если RTC сбросилась в 2012-й, «ещё не валиден» выглядит как отказ прошивки. Сначала время, потом повтор. Не NTP журналов SCADA, а часы самого контроллера до начала update.
Политика отката: пытаются накатить старый ЗИП на устройство, которое уже съело более новый счётчик.
Частичный brick после потери питания на записи загрузчика. Симптом похож, лечение другое: сервисный разъём, не «другой signed файл в тот же веб».
Свой скрипт интегратора, который перепаковывает официальный архив (логотип, лишние демоны, «облегчили»). Перепаковка ломает подпись. Официальный пакет + отдельные файлы application - допустимая схема. Официальный пакет, вскрытый и заново зашитый без ключа завода - гарантированный отказ на серийнике с secure boot.
На стенде «тот же» контроллер без включённой цепочки принимает всё. На объекте цепочка включена с завода. Стенд врёт, если не повторяет fuse-состояние серийника. FAT прошивки обязан идти на экземпляре с той же политикой загрузки, что в поставке, не на отладочной плате с открытым boot.
Стык с обновлением по сети
Сеть - транспорт. Подпись - локальный страж. VPN, HTTPS, «закрытый VLAN» не заменяют проверку образа на устройстве. Перехваченный канал без подписи - риск подмены. Подпись без дисциплины канала - риск залить правильный пакет не в то окно и не на тот узел. Нужны оба слоя; эта статья про второй.
Практические следствия для регламента, которые не повторяют чек-лист download проекта.
В репозиторий площадки кладут только заводские (или заказчиком подписанные) артефакты с хешем. Не «пересобранное». Хеш считают до копирования в контроллер и после, если протокол вендора это позволяет.
Команда update по сети должна быть доступна роли, которая имеет право менять систему, не паролю смены на мнемосхеме. Иначе WebVisu-удобство становится путём смены ядра.
Откат - тоже signed пакет, лежащий рядом до начала операции, проверенный на совместимость со счётчиком rollback. «Откатимся application» не лечит ядро, которое не встало.
После отказа подписи не долбить тот же файл циклически: смотреть лог загрузчика, модель, ключ, полноту файла. Повтор той же ошибки не оживляет устройство и изнашивает flash.
Групповой update парка: одно несовпадение ревизии платы - один «не берёт», остальные уже ушли вперёд. Партии бьют по ревизиям, не по «всем ARM в цехе».
Диагностика «пинг есть, управления нет» после неудачного boot может выглядеть как живой Linux без runtime. Это не повод лечить прикладной watchdog. Сначала: дошёл ли образ до стадии runtime. Три «жизни» процесса (железо, служба, цикл IEC) - соседняя диагностика; здесь достаточно не спутать отказ подписи с STOP программы.
Версии образов учитывают как конфигурацию объекта, наравне с проектом. Кто залил системный пакет, какой номер, какой ключ - строка в паспорте. Иначе через год ЗИП не сходится с тем, что в шкафу. Дисциплина «кто залил» для application уже привычна в Git; для firmware её часто нет. Имеет смысл тот же реестр: ветки и теги проекта контроллера не заменяют журнал образа, но дают образец, как фиксировать автора изменения.
Что требовать у вендора до закупки и до первого update
Не набор эксплойтов, а закрытие слепых зон договора.
Включена ли цепочка на серийных изделиях по умолчанию, можно ли её состояние прочитать без разбора корпуса.
Чей ключ, есть ли опция ключа заказчика, что будет с парком при ротации ключа вендора.
Как выглядит отказ: код, индикация, доступен ли recovery, нужен ли физический доступ.
Есть ли подписанный rollback и как он соотносится со счётчиком версии.
Совместимость образа с ревизией железа: таблица, не устное «должно подойти».
Канал update: только локальный носитель, или сеть, или оба; что именно проверяется (ядро, ФС, runtime, application).
Срок выпуска подписанных патчей после CVE в компонентах образа. Secure boot без обновляемого подписанного пакета превращает найденную дыру в вечную.
Это стыкуется с доверенным контуром там, где заказчик обязан объяснить состав ПО. Само по себе наличие secure boot не закрывает требование «знать, что внутри образа». Но без подписи любой USB становится легитимным источником ядра.
На FAT достаточно сценария: штатный подписанный пакет принимается; заведомо чужой файл (не подобранный «под атаку», а просто другой официальный пакет иной модели или обрезанный файл) отвергается предсказуемо; устройство остаётся в recovery или в прежнем образе, не в неопределённости. Цель - доказать политику загрузчика, не устроить конкурс обхода.
Таблица: симптом на объекте, причина подписи/ключа, что проверить до update
| Симптом на объекте | Вероятная причина подписи / ключа | Что проверить до update (и до повтора) |
|---|---|---|
| Чёрный экран, boot loop, «not trusted» / verify fail | Образ не подписан, подписан другим ключом, обрезан | Состояние secure boot на серийнике; чей ключ; хеш пакета; полнота файла; модель и ревизия |
| Стенд принял тот же файл, объект нет | На стенде цепочка выключена или другой ключ/ревизия | Fuse-состояние и ревизия платы стенда = объект; не гонять unsigned-стенд как доказательство |
| Официальный старый ЗИП отвергнут после прошлого update | Rollback protection, счётчик версии ушёл вперёд | Политика отката вендора; наличие signed rollback; не обещать «вернём прошлогодний образ» без бумаги |
| Пинг есть, runtime нет, RUN не тот | Загрузчик/ядро встали, пакет runtime не прошёл проверку или не тот комплект среды | Разделить firmware и application; лог какого звена упал; комплектация runtime в паспорте |
| Отказ после «чуть перепаковали» архив вендора | Подпись сломана вскрытием контейнера | Только неизменённый заводской пакет; доработки - в application, не в корне образа |
| «Не та прошивка» при файле с правильным именем | Другая модель/ревизия, другой dtb, совпал ключ линейки | Таблица совместимости; board id; не ориентироваться на имя файла |
| Update по сети «успех», после reboot отказ | На устройство ушёл не тот артефакт; проверка на устройстве строже, чем скрипт копирования | Хеш до и после; роль, кто имеет право системного update; не путать download проекта с образом ОС |
| Массовый отказ на части шкафов одной линии | Разные ревизии железа или разные поколения ключа в партии | Партии по серийникам; bulletin о ротации ключа; не лить «на все ARM» одним пакетом |
| RTC в прошлом, отказ «сертификат ещё не валиден» | Проверка цепочки с датами при сброшенных часах | Часы контроллера до update; затем повтор того же signed пакета |
| Нет реакции после обрыва питания в момент записи boot | Повреждён загрузчик, это не (только) подпись | Сервисный recovery вендора; ИБП на время update; не лечить «другим signed файлом» вслепую |
| После смены интегратора свои пакеты больше не принимаются | Ключ был у подрядчика, не у заказчика | В договоре: чей ключ, эскроу, процедура выпуска; не оставлять закрытый ключ у ушедшей фирмы |
Таблица - заготовка для журнала объекта: симптом пишет смена, графу «причина» не заполняют гаданием, пока нет лога загрузчика.
Типовые ошибки
Считать secure boot антивирусом линии. Он не смотрит Modbus и не закрывает пароль operator. Он решает, чьё ядро стартует.
Гонять на объекте стендовый unsigned, «потому что так быстрее». На серийнике с цепочкой это простой.
Хранить закрытый ключ заказчика в той же папке, что проект визуализации. Разные секреты, разные люди, разный ущерб при утечке.
Обещать откат с полки ЗИП без учёта rollback counter. Полк врёт.
Перепаковывать заводской образ «для удобства». Подпись умрёт, устройство честно откажется.
Путать отказ application и отказ загрузчика. Лечат разными пакетами и разными ролями.
Не читать bulletin о смене ключа вендора. Половина парка уедет, половина останется.
Проверять update только на плате с открытым boot. FAT должен повторять политику серийника.
Вопросы при работе
Контроллер не берёт прошивку. Это всегда secure boot?
Нет. Сначала отделите: нехватка места, неверный файл application, не та среда, обрыв записи, питание. Сообщение verify/signature/key - тогда цепочка. Без лога не гадайте.
Можно ли выключить secure boot, чтобы ЗИП вставал любой?
На серийном изделии часто нельзя штатно, и это не цель площадки. Цель - подписанный ЗИП под ту же цепочку. Отключение - сервис вендора и вопрос ИБ, не приём наладки.
Нужен ли ключ заказчика среднему заводу?
Нет, если вас устраивает заводская подпись и поставка пакетов. Да, если политика ИБ/ПАК требует контролировать, кто имеет право собрать образ. Тогда ключ - отдельный проект хранения, не строка в КП.
Update по сети безопаснее, чем с USB, если есть secure boot?
Подпись одинакова. Сеть добавляет маршрут и роль. USB добавляет физический доступ к шкафу. Небезопасна любая доставка unsigned на устройство с цепочкой: она просто не стартует. Опасна доставка signed, но не того пакета на не ту ревизию.
Что класть в ЗИП шкафа?
Последний принятый подписанный образ этой ревизии, хеш, инструкцию recovery, не «набор ISO с FTP за три года». Счётчик rollback должен позволять этот файл.
Secure boot заменяет доверенный ПАК?
Нет. Это механизм загрузки. ПАК - состав комплекса, оценка, документация. Можно иметь подпись и не иметь ПАК. Можно требовать ПАК и отдельно описать, чья подпись в boot.
Ссылки по теме
- Обновление прошивки и проекта ПЛК по сети: чек-лист;
- Доверенный ПАК АСУ ТП: состав и границы применения;
- Linux RT на ПЛК и Runtime под Windows: где ломается перенос проекта;
- ОСРВ в контроллере: зачем это смотрят на пуске;
- Git для проектов контроллера: ветки, теги, кто залил;
- FAT и SAT: приёмка АСУ ТП без сюрпризов на пуске.
Обсуждение