Внесены правки в документацию

This commit is contained in:
mi
2026-08-14 11:51:21 +03:00
parent 9eb8b2bc6e
commit e06a77ee1d
9 changed files with 286 additions and 22 deletions
+54 -1
View File
@@ -200,6 +200,11 @@ free -h
- [ ] `deploy` не состоит в группе `docker`; `sudo -l` содержит только утверждённые конкретные systemd-команды.
- [ ] Production compose, units, deploy scripts и secret mappings принадлежат root и недоступны `deploy` на запись.
- [ ] UFW и DOCKER-USER активны после restart Docker.
- [ ] Для published Docker ports allow rules сопоставляют original host
destination через `conntrack --ctorigdstport`; positive/negative probes
увеличивают counters нужных allow/deny rules после restart Docker и reboot.
- [ ] После обновления firewall helper active `oneshot RemainAfterExit` unit
явно перезапущен; `enable --now` не считается применением новой версии.
- [ ] Docker Engine/Compose plugin закреплены поддерживаемой версией.
- [ ] NTP active; disk/swap соответствуют sizing.
- [ ] Break-glass процедура сохранена вне VM.
@@ -515,7 +520,10 @@ cd <BACKEND_ROOT>
DOCKER_BUILDKIT=1 docker compose build --pull
```
Build не получает production secrets. Записать image digests.
Build не получает production secrets. Записать image digests и release file
manifest (`path`, owner/group, mode, executable). Sync с blanket
`--chmod=F644` запрещён: scripts, preflight и hooks устанавливаются
`0755/0750` по manifest и проходят `test -x` до activation.
Frontend:
@@ -566,6 +574,10 @@ Volumes:
- `otel-queue`;
- никаких PG data volumes.
Каждый `otel-queue` перед collector подготавливает idempotent
`otel-queue-init` (`10001:10001 0700`, без сети/secrets, только
`CHOWN/FOWNER`); collector стартует только после успешного one-shot.
Проверить:
```bash
@@ -581,7 +593,11 @@ Redis: ACL, AOF everysec, RDB, maxmemory, volume, no host port. OTEL: config rea
- [ ] Только nginx публикует ports.
- [ ] Internal services не подключены к public без причины.
- [ ] Named volumes созданы и permissions проверены.
- [ ] OTEL ownership init завершился `0`, а write-test проходит от collector
UID; root collector/`0777` не используются.
- [ ] Container resource limits/healthchecks заданы.
- [ ] Healthcheck-команды выполнены в exact pinned digests; отсутствуют
`ExitCode 127` и зависимости от несуществующих `wget`/`curl`.
- [ ] `docker compose config --quiet` success.
## 12. Stage 9 — TLS bootstrap, фаза 1
@@ -640,6 +656,9 @@ HSTS пока не включать. Проверить chain/hostname/redirect,
5. записать структурированный результат и метрику времени до истечения;
6. вернуть ненулевой exit code при ошибке, чтобы сработал alert;
7. не удалять действующий сертификат при неуспешном renew.
8. на success path вернуть `0` с пустым stderr; benign output `nginx -t` и
signal command подавить/перенаправить, полную диагностику печатать только
при ошибке.
Пример unit `/etc/systemd/system/han-chat-cert-renew.service`:
@@ -1278,6 +1297,8 @@ certbot delete active cert
- non-secret `.env` validated; runtime secrets разделены по сервисам и защищены;
- `deploy` не имеет Docker/root-equivalent доступа; production files root-owned, sudo ограничен конкретными systemd-units;
- один root Compose и nginx на VM; ВМ1 и ВМ2 имеют независимые public 80/443, ВМ2 дополнительно private 8443; public ВМ2 ограничен exact CRM webhook;
- после Safety cutover ВМ1 не содержит local Safety/Redis DB2 и вызывает ВМ2
только по private HTTPS с проверенным CA bind;
- container hardening и сетевые границы соответствуют arch-06;
- для каждой private/no-egress VM завершён и задокументирован lockdown с негативной проверкой внешнего доступа/egress;
- Redis/Collector volumes/resources/security работают;
@@ -1294,6 +1315,38 @@ certbot delete active cert
Cutover gates: private TLS chain/SAN; Safety v2 PG migration и lease/fencing smoke; capability `text|links|files|worker`; S3 Gate 4; performance acceptance; egress negative tests. Safety Service Owner, Rule Pack Owner, Security Owner, Product Owner и Operations Owner фиксируют approvals. Только после них ВМ1 переключает `MESSAGE_SAFETY_URL`. Legacy v1 остаётся rollback target на ограниченное окно, но один `message_id` нельзя одновременно отправлять в v1 и v2.
#### Обязательный gate миграции legacy ВМ1
Перед переключением caller на ВМ2 существующий backend ВМ1 считается legacy и
должен пройти отдельный migration gate:
1. env validator принимает только production
`MESSAGE_SAFETY_URL=https://<private-vm2-name>:8443`, требует
`MESSAGE_SAFETY_CA_HOST_PATH` и проверяет hostname/SAN; cross-host Docker
hostname и plaintext запрещены;
2. internal CA расположен в едином root-owned staging path, а не под
`deploy:deploy 0700`; positive read-test проходит от UID/GID
`api-backend`, negative — от постороннего UID;
3. local `message-safety`, его Redis DB2 и локальные rules-version env удалены
из target Compose/validator. Одновременный local и remote Safety запрещён;
4. release tree/Compose/unit принадлежат root, `deploy` исключён из `docker`,
установлен реальный root-owned stack systemd unit и permission preflight;
5. VM1 `DOCKER-USER` сопоставляет original published ports через
`conntrack --ctorigdstport`; counters подтверждены positive/negative probe
после Docker restart и reboot;
6. images закреплены digest, release file modes подтверждены manifest,
rollback выбирает совместимые digests/config, а не только строковый
`RELEASE_VERSION`;
7. ordered startup из этого runbook заменяет legacy `docker compose up -d`
всего стека; после readiness выполняется production nginx config
test/reload;
8. `han-secrets` и firewall oneshot после обновления явно перезапущены и
проверены по timestamp/live state; TLS renewal success path имеет пустой
stderr.
Ни старый deployment guide, ни успешный запуск legacy single-VM Compose не
являются доказательством прохождения этого gate.
Rollback возвращает caller adapter/upstream ВМ1 на предыдущий immutable release. Уже созданные v2 tasks завершаются/reconcile по PG checkpoints; down-migration и удаление quarantine versions запрещены.
При потере ВМ2 fail-open запрещён. ВМ2 reprovision-ится из immutable image/config; secrets materialize под отдельным IAM, Redis поднимается пустым, migrations/capability/egress gates повторяются. RTO ≤4 ч; restore rehearsal минимум дважды в год.