gendesign/ops
bot-backend de940c7534
All checks were successful
CI Trade-In / changes (pull_request) Successful in 8s
CI Trade-In / backend-tests (pull_request) Has been skipped
CI Trade-In / browser-tests (pull_request) Has been skipped
CI / changes (pull_request) Successful in 10s
CI Trade-In / frontend-checks (pull_request) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (pull_request) Has been skipped
CI / openapi-codegen-check (pull_request) Has been skipped
feat(ops): off-box копия рантайм-конфига — зашифрованной, иначе никак
Четвёртый пункт приёмки #2203. В дампах есть колонки под pgp_sym_encrypt, ключ
к ним лежит на самой машине и никуда не уезжает: потеря машины означает «дампы
есть, расшифровать нечем». Ради этой связки шифрование в базе и заводилось.

КУДА И ПОЧЕМУ ИМЕННО ТУДА. В тот же S3, отдельным префиксом env/, и только
зашифрованным. Разобранные варианты:

  - рядом с дампами открытым — нельзя: ключ рядом с шифротекстом обнуляет
    шифрование, одна утечка доступа к бакету отдаёт и то и другое;
  - на соседний хост по SSH — потребовало бы завести доверие между машинами,
    которого нет (проверено: Permission denied (publickey)), то есть РАСШИРИТЬ
    периметр ровно тогда, когда #3075 его сужает;
  - отдельный бакет с отдельными ключами — правильнее всего, но требует новых
    учётных данных.

Выбран единственный исполнимый без расширения доступа: шифротекст в S3,
парольная фраза — вне S3.

FAIL-CLOSED. Без фразы скрипт не выгружает файл открытым, а падает с явным
сообщением и алертом. Молчаливая выгрузка ключа в бакет с дампами хуже
отсутствия копии: создаёт ложное чувство защищённости.

Фраза уходит через дескриптор, а не аргументом — иначе видна в ps любому
пользователю машины. После шифрования файл проверяется обратной расшифровкой:
без этого можно годами возить нечитаемый мусор и узнать в тот момент, когда он
понадобился.

Прогон на хосте 27.08 (подставной исходник, боевой не трогался):
  без фразы → код 1, файлов создано 0
  с фразой  → «Зашифровано и проверено расшифровкой», 110 байт
  своей фразой читается, чужой — нет

ОДИН ШАГ ЗА ВЛАДЕЛЬЦЕМ, и он неустраним: фраза обязана жить там, где переживёт
смерть машины, иначе копия бесполезна — расшифровать будет нечем. Сгенерировать
её здесь и оставить на хосте нельзя по построению. Инструкция — в шапке скрипта.

Пять тестов сторожат ровно те свойства, ради которых всё сделано.
Прогон: 85 ops-тестов зелёные, ruff чист.

Refs #2203
2026-08-27 16:32:27 +03:00
..
db-bootstrap chore(ops): адрес Poincare — 188.124.37.140 вместо заменённого 188.246.224.93 (#3110) 2026-08-27 11:23:37 +03:00
glitchtip-auth-forwarder fix(tradein/observability): stop basic_auth 401 and RetryError GlitchTip noise 2026-08-15 18:08:04 +03:00
metrics feat(observability): кнопка «Принял в работу» под клиентским инцидентом (#3078) 2026-08-27 13:56:00 +03:00
backup-couchdb.sh chore(ops): backup-couchdb.sh исполняемый, как остальные бэкапы (#3091) 2026-08-25 05:48:41 +00:00
backup-env-offbox.sh feat(ops): off-box копия рантайм-конфига — зашифрованной, иначе никак 2026-08-27 16:32:27 +03:00
backup-forgejo.sh feat(ops): лёгкий Postgres на Beget под forgejo и glitchtip (#3080) 2026-08-24 16:31:12 +00:00
backup.sh fix(ops): бэкап без выгрузки в S3 падает, а не рапортует успех (#3086) 2026-08-24 17:50:18 +00:00
check-backup-staleness.sh fix(ops): restore +x on new ops/*.sh (exec bit lost in prior commit, Windows core.filemode=false) 2026-08-21 15:38:31 +03:00
crontab-beget.cron feat(ops): у волта Obsidian появился автоматический бэкап (#3090) 2026-08-25 05:44:16 +00:00
crontab-poincare.cron feat(ops): off-box копия рантайм-конфига — зашифрованной, иначе никак 2026-08-27 16:32:27 +03:00
docker-prune.sh chore(ops): снятие зависших job-контейнеров раннера + лимит journald + мёртвый Caddy-блок 2026-08-15 22:27:48 +03:00
gendesign-backup-couchdb.default.example feat(ops): у волта Obsidian появился автоматический бэкап (#3090) 2026-08-25 05:44:16 +00:00
gendesign-backup-forgejo.default.example feat(ops): лёгкий Postgres на Beget под forgejo и glitchtip (#3080) 2026-08-24 16:31:12 +00:00
gendesign-backup.default.example fix(ops): бэкап без выгрузки в S3 падает, а не рапортует успех (#3086) 2026-08-24 17:50:18 +00:00
gendesign-uptime.default.example ci(infra): coverage-gate (#68) + OpenAPI codegen-assert (#69) + uptime monitoring (#75) 2026-06-13 23:28:06 +05:00
journald-gendesign.conf.example chore(ops): снятие зависших job-контейнеров раннера + лимит journald + мёртвый Caddy-блок 2026-08-15 22:27:48 +03:00
lib-backup.sh fix(ops): оповещения уходят в тему «алерты», а не в переговорку (#2203) 2026-08-27 13:12:10 +03:00
restore-drill.sh fix(ops): бэкап без выгрузки в S3 падает, а не рапортует успех (#3086) 2026-08-24 17:50:18 +00:00
restore.sh fix(ops): восстановление не падает в хвосте из-за незаведённых ролей (#3089) 2026-08-25 05:18:53 +00:00
selectel-audit.sh feat(ci): деплой проверяет, к тому ли хосту подключился (#3079) 2026-08-24 16:36:50 +00:00
selectel-bootstrap.sh fix(ops): закрепить рабочий адрес api.telegram.org на новом хосте 2026-08-23 23:32:35 +03:00
selectel-ci-access.sh chore(ops): адрес Poincare — 188.124.37.140 вместо заменённого 188.246.224.93 (#3110) 2026-08-27 11:23:37 +03:00
split-infra-postgres.sh chore(ops): адрес Poincare — 188.124.37.140 вместо заменённого 188.246.224.93 (#3110) 2026-08-27 11:23:37 +03:00
uptime-healthcheck.sh fix(ops): оповещения уходят в тему «алерты», а не в переговорку (#2203) 2026-08-27 13:12:10 +03:00