Перейти к содержимому

Устранение неполадок (симптом → диагноз → исправление)

Каждая запись следует одной и той же структуре: симптом, который вы видите, как подтвердить, что это именно он, и исправление. Приведённые строки лога — это фактические строки движка, так что вы можете искать их через grep. Там, где существует более глубокий runbook, запись ссылается на соответствующую страницу, а не выводит его заново.

Перезапуск не выводит его повторно (хранится только хеш токена, в setup.token в каталоге данных). Пока пользователей ещё нет, восстановление безопасно: остановите движок, удалите setup.token, запустите его — генерируется и выводится новый токен. Это работает только на установке без пользователей, поэтому это не путь для захвата. Токен выводится только в stdout (journal под systemd, лог контейнера в Docker/Kubernetes) — никогда в файлы логов.

Пользователи уже существуют в этом каталоге данных — вы не на первой загрузке. Либо войдите с существующим администратором, либо для действительно свежего старта используйте свежий --data-dir.

Движок предупреждает о ключах при первой загрузке

Заголовок раздела «Движок предупреждает о ключах при первой загрузке»
generated a new audit signing key; back it up path=/var/lib/olivares/audit-signing.key
generated a self-signed TLS certificate; clients must trust it, or pin it with --pin-sha256=<pin_sha256> (that value, verbatim) cert=/var/lib/olivares/tls.crt cert_fingerprint_sha256=d38567e8…378c4e7f pin_sha256=JsdrhrY77Me8miAmobJsqamE3NDWIOSBrDTwbHkyCD0

Оба намеренны, и первый — это тот, который аукнется позже: принудительного депонирования (escrow) нет — скопируйте audit-signing.key за пределы сервера сейчас и закрепите публичный ключ (GET /v1/audit/pubkey) за пределами сервера, иначе будущая компрометация хоста оставит вас неспособными доказать целостность собственного ledger (резервное копирование и восстановление).

Строка TLS печатает два хэша, и они не взаимозаменяемы: cert_fingerprint_sha256 — это хэш сертификата, тот, что показывает браузер; pin_sha256 — хэш SPKI конечного сертификата, и только его сравнивает --pin-sha256. Скопируйте это значение дословно:

Окно терминала
olivares status --server https://127.0.0.1:8443 \
--pin-sha256 JsdrhrY77Me8miAmobJsqamE3NDWIOSBrDTwbHkyCD0

Если вместо этого закрепить отпечаток сертификата, ошибки неверного значения флага не будет — это корректный 32-байтовый хэш, поэтому соединение будет предпринято и отклонено с TLS SPKI pin mismatch, и эта ошибка сообщит значение, которое следовало использовать. Для curl --pinnedpubkey sha256//… добавьте завершающее дополнение =: движок намеренно печатает base64 без дополнения, чтобы значение выводилось без кавычек и переживало копирование, но curl требует дополненную форму.

Сначала проверьте, подключено ли вообще что-нибудь. Движок прямо сообщает об этом при загрузке:

ingest: no observation sources configured (OLIVARES_SOURCES_CONFIG.sources is empty); no connector will ingest — the estate runs on no live traffic

Отсутствующий, нечитаемый или невалидный файл источников предупреждает и продолжает (загрузка никогда не падает из-за него) — поэтому здорово выглядящий движок с пустой картой обычно означает, что конфигурация так и не загрузилась. Исправьте файл/путь и перезапустите; успех выглядит как ingest: wired source … kind=… для каждого источника. Источник, который не удалось сконструировать, логирует ingest: failed to register in-process source; not wired с указанием причины — об этом сообщается, оно никогда не отбрасывается молча.

Три причины покрывают почти все случаи, все по замыслу (руководство по pgAudit):

  1. Сервер не логирует в UTC. Записи с аббревиатурой зоны, отличной от UTC, пропускаются, а не получают неверную временную метку — задайте log_timezone = 'UTC'.
  2. csvlog — это пакет, а не хвост (tail). follow применяется только к jsonlog; источник csvlog принимает данные на каждом проходе, а не непрерывно.
  3. Аудируемые классы отключены — проверьте, что pgaudit.log включает read, write.

Ожидаемо на свежей установке: при отсутствии объявленных grant’ов каждый наблюдаемый доступ честно считается «неожиданным». Это начальное состояние, а не баг — разберите его, объявив grant’ы, которые вы намереваетесь предоставить.

Прочитайте тело — оно различает два случая:

  • {"status":"unavailable","store":"down"} — хранилище недоступно. На SQLite: переполнен диск, проблемы с PVC, права доступа к файлу. На Postgres: доступность и учётные данные. Liveness намеренно продолжает проходить (процесс жив), так что ничто не зацикливается на перезапуске при сбое хранилища; перезапустите pod/сервис вручную после исправления хранилища, если оно остаётся заклиненным.
  • {"status":"standby","leader":false,…} — резервный узел HA, отвечающий честно. Это не ошибка: Service маршрутизирует на лидера; резервные узлы дренируются по замыслу. Если все реплики сообщают standby, выбор лидера застрял — проверьте связность advisory-lock Postgres.

В топологии с одной репликой по умолчанию автоматического failover нет — восстановление — это перепланирование StatefulSet плюс переподключение тома RWO (следите за ошибками Multi-Attach; том привязывает восстановление к своей AZ). Автоматический failover — это свойство HA-топологии (Postgres + реплики + общий ключ подписи). Никогда не запускайте продакшен с отключённым хранением: emptyDir теряет ключ подписи при каждом перепланировании.

Латентность приёма p99 растёт (обратное давление)

Заголовок раздела «Латентность приёма p99 растёт (обратное давление)»

Шина блокирует, а не отбрасывает — растущий p99 olivares_ingest_duration_seconds — это задуманный сигнал того, что подписчик насыщен, а не потеря данных. Назовите виновника напрямую:

olivares_eventbus_queue_depth / olivares_eventbus_queue_capacity > 0.9

Метки по подписчикам указывают на медленный модуль; olivares_eventbus_publish_blocked_total подсчитывает события обратного давления. Обычная коренная причина — пропускная способность записи в хранилище (потолок единственного писателя SQLite) — это исправление через ёмкость (перейти на Postgres или снизить амплификацию записи), а не ручка для тюнинга. Медленные выходные коннекторы (webhook, SIEM) никогда не должны быть синхронными подписчиками.

С включённой распределённой шиной (OLIVARES_BUS_CONFIG) помните, что межузловой мост работает не более одного раза (at-most-once): насыщенный мост заполняет olivares_eventbus_bridge_pending_messages и затем отбрасывает удалённые события, подсчитанные в olivares_eventbus_bridge_dropped_total — оповещайте о любом росте и поднимайте по пейджеру, когда olivares_eventbus_bridge_connected == 0.

Рост olivares_auth_login_attempts_total{outcome="locked_out"} означает, что ограничитель по аккаунту/по IP сработал после повторных неудач. Он очищается сам; расследуйте источник неудач, а не повышайте лимиты.

Сначала разберитесь, что вы запустили: audit verify по умолчанию завершается с кодом 0 даже при неудачной цепочке (результат находится в JSON-отчёте) — автоматизация должна использовать --strict или разбирать отчёт:

Окно терминала
olivares audit verify --tenant $TENANT --data-dir /var/lib/olivares --strict \
--pubkey <BASE64-PINNED-OFF-BOX>

Закрепите внесерверный публичный ключ: без закреплений верификатор доверяет ключам, прочитанным с (возможно скомпрометированного) хоста — приемлемо как рекомендательная проверка, но не как доказательство нарушения целостности. Затем классифицируйте по полю reason:

ПричинаКлассРеакция
hash-mismatch, prev-mismatch, head-mismatch, tail-truncatedподделка или усечениерассматривайте как SEV1: сохраните сервер, сверьте с внесерверной контрольной точкой
checkpoint-sig-invalid, checkpoint-link-mismatch, event-sig-invalidподделка или неверный ключSEV1, если только вы не можете доказать путаницу с хранением ключей
seq-gapудаление или несогласованность восстановлениясверьте с внесерверной контрольной точкой, прежде чем кричать о подделке
event-sig-missingвозможно, устаревшие записи до включения подписиограничьте это --from на границе включения; отсутствие до границы ожидаемо

Восстановленная резервная копия, которая проходит наивный обход, но расходится с вашей закреплённой внесерверной контрольной точкой — это случай аномалии восстановления; именно ради этого сравнения и существует закрепление.

Контрольные точки перестали записываться (каденция по умолчанию 1ч; OlivaresAuditCheckpointStale срабатывает на 2ч). Проверьте лог движка на наличие ошибок контрольных точек и записываемость хранилища — пока оно растёт, ваш якорь доказательства нарушения целостности стареет.

Назначение с неизвестным kind пропускается и логируется (notify: destination has unknown connector kind; skipped — проверьте написание kind). Для приёмников событий POST …/subscriptions/{id}/test отправляет доставку, за которой вы можете наблюдать, а конечные точки должны быть HTTPS (отправка в SIEM).


Если симптома здесь нет, и собственное сообщение движка его не объясняет — это баг документации; пожалуйста, сообщите о нём, приложив строку лога.