Обновления¶
Обновление на 0.33¶
Текущая опубликованная версия — 0.33 у всех компонентов: backend, worker, frontend, сканер инфраструктурного кода и DomainScope. Версии при этом независимые, и совпадение номеров — не правило: полный набор образов есть не для каждой версии.
0.33 — крупный релиз: плагинная платформа доведена до состояния, в котором она несёт интеграции целиком, а ядро от них разгружено. Ниже — только то, что требует действий при обновлении. Что появилось нового — в разделе Что нового в 0.33.
⚠️ Миграций много, и две из них долгие¶
С 0.31 до 0.33 накопилось 69 миграций схемы. Таблицу находок целиком ни одна не переписывает, но на инсталляции с накопленным объёмом две стоят внимания:
00141создаёт три сводных представления сразу с наполнением — это три полных прохода по таблице находок;00159строит GIN-индекс по номерам CVE в неблокирующем режиме (CONCURRENTLY). На очень большой таблице он может не уложиться в бюджет ожидания общей блокировки миграций и помешать старту остальных реплик.
Что сделать заранее:
- поднять
MIGRATION_LOCK_WAIT_SECONDS(по умолчанию 180 секунд) — либо построить этот индекс руками в тихие часы до обновления; - обновлять сначала backend, потом воркеры: воркеры ждут ту же блокировку и на долгой миграции уходят в цикл перезапусков;
-
проверять применение по схеме, а не по статусу выката:
Резервная копия базы перед обновлением обязательна: обратных миграций нет.
⚠️ Каналы Mattermost и MAX вынесены из ядра в плагины¶
Встроенного пути доставки для этих двух каналов больше нет: панели в
настройках проекта исчезли, очереди mattermost_notifications и
maxru_notifications удалены. Доставку ведут плагины mattermost-notifier и
maxru-notifier.
Порядок обновления обязателен именно такой: обновиться → установить плагин → перенести настройки. Перенос требует установленного плагина-получателя, поэтому заранее, на 0.32, его выполнить нечем.
- Обновите компоненты до 0.33.
- Установите плагин канала (
mattermost-notifier,maxru-notifier) — пошагово это описано в Официальных плагинах. Оба — нативные (Tier 2), поэтому источнику каталога нужно разрешение на исполнение нативных плагинов. - Для Mattermost заполните в конфигурации установки плагина поле
«Адрес сервера Mattermost» (
mattermost_base_url). Без него установка и настройка проходят, а доставка отклоняется: Mattermost размещают у себя, адрес заранее неизвестен и в подписанном описании плагина его нет — именно это поле и разрешает исходящее соединение к вашему серверу. -
Перенесите настройки проектов админским запросом. Интерфейса у переноса нет:
# dry-run (по умолчанию): показывает, что будет сделано, ничего не меняя curl -X POST -H "Authorization: Bearer $TOKEN" \ "https://hub.example.com/api/v1/admin/maintenance/channel-config-backfill?channel=mattermost" # перенос; в ответе — сколько перенесено, сколько пропущено curl -X POST -H "Authorization: Bearer $TOKEN" \ "https://hub.example.com/api/v1/admin/maintenance/channel-config-backfill?channel=mattermost&mode=final"Параметр
channel—mattermostлибоmaxru. Проекты, у которых конфиг плагина уже есть, не трогаются и считаются отдельно.
Между «посмотреть» и «перенести» есть окно
В этом окне правки, сделанные старым путём (PUT /projects/:id),
потеряются. Поэтому режим по умолчанию — dry-run, а момент переноса
выбирает оператор. До переноса уведомления по этим каналам не
отправляются: прежние настройки никуда не делись, но читает их только
перенос.
Данные в базе сохранены: колонки projects.mattermost_config,
projects.maxru_config и projects.mattermost_bot_config остаются на месте и
будут удалены отдельным релизом — после того, как у вас была версия, на
которой перенос возможен. Обновление настройки не теряет.
Настройка «Mattermost через бота» удалена без переноса: доставки по этому пути не существовало — форма сохранялась, уведомления не приходили.
⚠️ Удалённые переменные окружения¶
| Переменная | Что с ней |
|---|---|
MATTERMOST_NOTIFICATION_WORKERS |
Удалена — очереди, которой она управляла, больше нет |
MAXRU_NOTIFICATION_WORKERS |
Удалена — то же |
TELEGRAM_NOTIFICATION_WORKERS |
Не читается — Telegram доставляет плагин, своей очереди у канала нет |
MATTERMOST_ALLOW_LOCAL_DIAL |
Не читается никем; Hub при старте сообщает, что переменные подсистемы больше ничем не управляют |
Оставленные в конфигурации значения не читаются и не мешают старту.
⚠️ Образ frontend работает от непривилегированного пользователя¶
Образ dexionius/sshub-frontend:0.33 запускается под uid/gid 101 и пишет
pid-файл в /tmp. Чарт из этой поставки задаёт то же самое
(frontend.frontend.podSecurityContext), поэтому обновление по чарту действий
не требует. Проверьте окружение, если вы переопределяли
securityContext (например, runAsUser: 0 из-за прежнего поведения образа)
или монтировали тома с расчётом на root.
⚠️ Официальный каталог плагинов подключается сам¶
При обновлении заводится источник каталога hub-official — регистрировать его
руками больше не нужно. Инсталляции, зарегистрировавшие тот же каталог раньше,
дубля не получают; удалённая запись при следующем обновлении не возвращается.
Разрешение на нативные плагины при этом не выдаётся — это решение оператора. На свежей инсталляции каталог виден, а нативные плагины (в том числе все шесть каналов уведомлений) не ставятся, пока источнику не разрешено исполнение вне песочницы WASM. Провайдерам задач разрешение не нужно: им нативный режим запрещён, и они всегда исполняются в песочнице. Отказ не молчаливый: в каталоге такие записи помечены, а карточка объясняет причину и куда нажать.
Что нового в 0.33 — Hub¶
Плагинная платформа
- Tier 2 — нативные плагины в изолированном процессе (gRPC), в дополнение к WASM; публикация нативных плагинов в общий каталог.
- Каналы уведомлений как плагины: Telegram, Slack, Microsoft Teams, Mattermost, MAX, электронная почта. Диспетчер рассылает событие любому канальному плагину, а не захардкоженному списку — см. Уведомления.
- История версий в каталоге, установка конкретной версии и явный откат; установка из файла и отзыв подписи по digest'у.
- Обогащение находок данными БДУ ФСТЭК по номеру CVE; источник инвентаря FleetDM (хосты и уязвимости периодическим опросом); кэш данных о CVE на стороне Hub — плагин спрашивает, что уже известно, и не резолвит это заново.
Учёт задач
- Провайдеры задач как плагины: Jira, GitHub Issues, Trello. Курируемый список целей заведения, привязка существующей задачи, опрос статусов, авто-закрытие, групповое заведение и бэкфилл истории, попроектная конфигурация — см. Учёт задач.
Находки
- Свод инвентарных находок по пакету, хосту и CVE с drill-down и массовыми действиями по строке свода.
- Ручное объединение находок и его отмена; ручные теги с аудитом; правила автоподавления; автоматическая связь находок по значению секрета; ручной ввод находки без SARIF — см. Жизненный цикл находки.
Доступ и наблюдаемость
BOOTSTRAP_ADMIN_EMAILS— первый администратор без временного отключения SSO; интерфейс управления ролями с матрицей прав; работа по ключу сервисного аккаунта (чтение и изменение находок, дашборд, нарушения SLA).- Метрики Prometheus на отдельном порту у всех трёх долгоживущих процессов и трейсинг OpenTelemetry — см. Эксплуатация.
Интерфейс и API
sshub— консольный клиент: находки, дашборд, отчёты, инвентарь, SLA, задачи, админка, гейт для CI — см. Консольный клиент.- Портируемая спека OpenAPI 3 и генерация клиентов.
- Уведомление о вышедшем релизе, выключенное по умолчанию.
Что нового в 0.33 — DomainScope¶
- Suspended-домены: запрет по специфичности и зонд возврата — зонд отчитывается в начале цикла и не ждёт перечисления поддоменов.
- Цели nuclei и ZAP проверяются скоупом Hub, а не только владением адресом: прежде сканировалось и то, что из скоупа уже убрали.
- Зоны перечисляются по расписанию, а не все на каждом цикле.
Из 0.32, если вы обновляетесь с 0.31: цели портскана берутся из текущего
резолва активных доменов, а не из истории резолвов; обогащение из Metabase
убрано в пользу плагина Hub metabase-cmdb.
Полный список изменений, включая замеренные улучшения производительности, —
в CHANGELOG.md поставки.
Формат версий¶
Hub использует единую схему для всех компонентов:
Пример: 0.9.20260602093200+a1b2c3d
| Часть | Что |
|---|---|
X.Y |
Major.Minor — общий для всех компонентов |
BUILD |
UTC timestamp YYYYMMDDHHMMSS (когда собрали) |
COMMIT |
Короткий git-hash (для аудита со стороны поставщика) |
DomainScope версионируется независимо.
Где смотреть текущую версию¶
# UI Hub — footer показывает версии frontend + backend; warning при рассинхроне X.Y
# Backend HTTP
curl https://hub.example.com/version
curl https://hub.example.com/api/v1/version
Ответ /version:
{
"component": "backend",
"version": "0.9.20260602093200+a1b2c3d",
"commit": "a1b2c3d",
"built_at": "2026-05-24T00:00:00Z"
}
Поле component — имя компонента (backend, worker, …), built_at — ISO-таймстамп сборки.
Выбор версии¶
Образы публикуются с явными тегами вида X.Y, а также с тегом latest.
Указывайте явный тег и в docker-compose.yml, и в значениях чарта.
Причины две:
latestне позволяет понять, что именно развёрнуто, и не даёт откатиться на предыдущее состояние;- в Kubernetes под с
latestне перечитает образ без явного перезапуска и политикиimagePullPolicy: Always— легко получить смесь версий между репликами.
Проверьте, что тег есть у всех компонентов
Теги публикуются независимо, и не для каждой версии существует полный набор образов. Прежде чем менять версию, убедитесь, что нужный тег доступен для всех компонентов, которые вы разворачиваете: backend, worker, frontend, сканер конфигураций, DomainScope, образ песочницы.
Проверить перечень опубликованных тегов можно так:
for img in sshub-backend sshub-worker sshub-frontend \
sshub-iac-scanner domain-scope sshub-sandbox-tools; do
echo "== $img"
curl -s "https://hub.docker.com/v2/repositories/dexionius/$img/tags?page_size=20" \
| grep -o '"name":"[^"]*"'
done
Разворачивайте все компоненты одной версией. Интерфейс сравнивает свою
версию X.Y с версией backend и показывает предупреждение при
расхождении — это признак того, что обновились не все компоненты.
Перед обновлением — всегда¶
- Резервная копия базы — см. Эксплуатация.
- Проверить наличие тега у всех компонентов, как описано выше.
- Прочитать описание изменений к новой версии.
- Проверить переменные окружения — новая версия может требовать новых.
- Продумать откат: на какой тег возвращаться. Учтите, что миграции базы вперёд применяются автоматически, а обратно — нет.
Docker Compose¶
cd /opt/hub
docker compose pull
docker compose up -d
# Проверка
curl https://hub.example.com/version
Backend стартует, прокатывает миграции, потом обслуживает.
Kubernetes (Helm)¶
Задайте новый тег в значениях чарта и примените их:
Поды пересоздаются последовательной заменой. Backend при старте применяет миграции под блокировкой: первая реплика мигрирует, остальные ждут — поэтому обновление с миграцией занимает больше времени, чем обычная замена реплик.
Если вы всё же используете latest, смена тега не произойдёт сама: под не
перечитает образ без imagePullPolicy: Always и явного перезапуска.
kubectl -n hub rollout restart deploy/hub-backend
kubectl -n hub rollout restart deploy/hub-worker
kubectl -n hub rollout restart deploy/hub-frontend
Миграции БД¶
Hub использует встроенную систему миграций — backend накатывает изменения схемы автоматически при старте.
Когда применяются¶
- При старте backend
- Применяется только то, чего нет в
goose_db_version
Что важно знать¶
- Прямые миграции — backend стартует, обновляет схему, потом начинает обслуживать
- Обратной совместимости миграций нет — нельзя откатить схему на старую версию без рестора БД
- Длительные миграции — release notes от поставщика отмечают ETA для тяжёлых миграций
- Блокирующие — backend не отвечает на запросы пока миграция идёт
Если миграция упала¶
# Compose
docker compose logs backend | grep -i goose
# K8s
kubectl -n hub logs deploy/hub-backend | grep -i goose
# Состояние
docker compose exec postgres psql -U securityhub securityhub -c \
"SELECT * FROM goose_db_version ORDER BY version_id DESC LIMIT 5;"
Если миграция упала — обычно goose откатывает транзакцию. Перезапустите backend. Если повторно падает — соберите логи и обратитесь к поставщику. Не правьте схему руками.
Rollback¶
Compose¶
# Остановить
docker compose down
# Восстановить БД из бэкапа (если миграции уже прокатились)
gunzip -c /backup/hub-pre-upgrade.sql.gz | docker compose exec -T postgres psql -U securityhub securityhub
# Откатиться на предыдущий образ (попросите у поставщика конкретный тэг)
# В .env: HUB_IMAGE_TAG=0.9.PREVIOUS
docker compose up -d
Kubernetes¶
# Helm revision history
helm history hub -n hub
# Откат на предыдущую ревизию
helm rollback hub <revision> -n hub
# Если БД продвинулась — restore + redeploy
kubectl -n hub scale deploy --all --replicas=0
# restore from PV snapshot / pgdump
helm rollback hub <revision> -n hub
kubectl -n hub scale deploy --all --replicas=2
DomainScope обновление¶
DomainScope обновляется независимо от Hub:
Совместимость API между Hub и DomainScope: оба сервиса используют публичные REST эндпоинты Hub (/api/v1/products/<id>/reports и /api/v1/projects/<id>/scope/proposals). При major-bump поставщик отмечает в release notes изменения контракта, если они есть.
Frontend и backend совместимость¶
Hub-frontend завязан на minor-версию backend. В footer UI отображается:
При расхождении minor — warning в UI. При major — приложение может вести себя некорректно.
В compose/k8s они обновляются вместе (один тэг :latest).
Расписание обновлений¶
| Окружение | Частота |
|---|---|
| Staging / dev | каждый минор |
| Pilot prod | каждый минор +1 неделя после release |
| Production stable | каждый второй минор, или security-only |
| Closed environments | quarterly review + security patches |
Hot-fix (security CVE) — катите ASAP в любом окружении.
Major-upgrade (X → X+1)¶
Major-upgrades содержат breaking changes. Перед накаткой:
- Прочитайте migration guide от поставщика
- Тестируйте на staging — полный цикл upload SARIF, Jira sync, notifications
- Запланируйте maintenance window (минимум 1 час)
- Подготовьте rollback-план (БД snapshot)
- Уведомите пользователей — за 24 часа
Major-upgrade обычно требует:
- Обновить env vars (новые / переименованные)
- Перенастроить интеграции (если поменялся формат конфига)
- Сначала остановить worker, потом обновить backend, потом запустить worker
Связанные документы¶
- Эксплуатация — backup перед обновлением
- Диагностика — если что-то пошло не так