Реализация на отдельных двух машинах с протестированным взаимодействием по проверке сообщений
This commit is contained in:
@@ -22,8 +22,8 @@
|
||||
6. S3 — внешний Selectel-compatible storage; клиент получает только presigned URL.
|
||||
7. Секреты не коммитятся, не вставляются в команды shell history и не выводятся в отчёты.
|
||||
8. Миграции выполняются отдельными one-shot steps до новой версии приложения.
|
||||
9. Message Safety запускается как documented stub до замены; это не production antivirus/moderation.
|
||||
10. `bitrix-sync` вводится только после выполнения preflight/cutover gates module-07; до этого `BITRIX_SYNC_ENABLED=false`, public webhook закрыт на edge.
|
||||
9. Production Message Safety работает только на ВМ2; local stub/fallback на ВМ1 запрещён. Caller ВМ1 использует private HTTPS, service token и проверку internal CA, при недоступности — fail closed.
|
||||
10. `bitrix-sync` работает только на ВМ2 и вводится после preflight/cutover gates module-07; до подтверждённого cutover public webhook остаётся закрыт на edge.
|
||||
11. На ВМ1 и ВМ2 отдельные root Compose projects/systemd units; deploy/rollback выполняются независимо.
|
||||
12. ВМ2 — самостоятельная service VM с минимальным public webhook ingress, allow-listed egress, отдельным IAM principal и service-specific secret files.
|
||||
13. OS-роли, SSH/sudo, secrets delivery, container hardening и private-VM lockdown подчиняются arch-06.
|
||||
@@ -49,7 +49,7 @@
|
||||
<VM_PRIVATE_IP> приватный IPv4 VM
|
||||
<VPC_CIDR> например 10.20.0.0/24
|
||||
<PG_PRIVATE_HOST> private FQDN/IP managed PG
|
||||
<PG_PORT> 5432 или 6432
|
||||
<PG_PORT> 5433 для Selectel PgBouncer; иной порт — только фактическое значение другого provider/endpoint
|
||||
<PG_DATABASE> han_chat
|
||||
<BACKEND_REPO_URL> URL репозитория этой VM
|
||||
<BACKEND_ROOT> /opt/han-chat/backend
|
||||
@@ -115,7 +115,7 @@ DNS: `A <PUBLIC_HOST> → <VM1_PUBLIC_IP>`, `A <PROCESSING_PUBLIC_HOST> → <VM2
|
||||
|
||||
## 5. Stage 2 — hardening Ubuntu
|
||||
|
||||
Процедура первичная для **каждой** application VM. Скрипт-прототип [`../../HAN_chat/deploy/setup-vm-han-chat.sh`](../../HAN_chat/deploy/setup-vm-han-chat.sh) полезен для UFW, fail2ban, Docker и `DOCKER-USER`. Перед production: review версии; не передавать IP/ключи в git; проверить unattended upgrades; `deploy` не в группе `docker`; `AllowTcpForwarding no` по умолчанию; отдельный `tunnel` при необходимости; root-owned systemd-units и `/etc/sudoers.d/deploy` без wildcard.
|
||||
Процедура первичная для **каждой** application VM и выполняется только по её профильному production runbook. Перед production: review версии; не передавать IP/ключи в git; проверить unattended upgrades; `deploy` не в группе `docker`; `AllowTcpForwarding no` по умолчанию; отдельный `tunnel` при необходимости; root-owned systemd-units и `/etc/sudoers.d/deploy` без wildcard.
|
||||
|
||||
`PUBLIC_DOCKER_PORTS` задаёт профильный runbook (ВМ1: `80,443`; ВМ2 — свои public 80/443, private 8443 не internet).
|
||||
|
||||
@@ -216,37 +216,24 @@ Validation: нет `change-me`, paired tokens equal, PG TLS, public HTTPS, `FRON
|
||||
|
||||
## 9. TLS/ACME процедура
|
||||
|
||||
Webroot two-phase, независимо в root Compose каждой VM, без `compose down`. Staging CA rehearsal, затем production `--cert-name` текущего host. Сертификат и ACME volume между VM не разделяются.
|
||||
Канонические bootstrap, renewal, validation и safe reload задаёт
|
||||
[`arch-08-nginx.md`](arch-08-nginx.md). Rollout каждой VM применяет эту модель
|
||||
независимо, без `compose down` и без named volume сертификатов:
|
||||
|
||||
Renew: systemd timer дважды в сутки. Скрипт `<BACKEND_ROOT>/deploy/ssl-renew.sh`:
|
||||
- root-only ACME state: `/etc/letsencrypt`;
|
||||
- read-only для nginx host staging: `/var/lib/han-chat/public-tls`;
|
||||
- host ACME webroot: `/var/lib/han-chat/acme`;
|
||||
- root-owned systemd timer/hook дважды в сутки с `flock`; пользователь `deploy`
|
||||
может запускать только утверждённый unit и не получает доступ к ACME state;
|
||||
- staging CA rehearsal предшествует production issuance; после renewal root
|
||||
hook проверяет certificate/key, атомарно обновляет staging, выполняет
|
||||
container `nginx -t` и только затем HUP;
|
||||
- success path возвращает `0` с пустым stderr; ошибка сохраняет действующий
|
||||
certificate/config и поднимает alert (<21 дней, page <7 дней).
|
||||
|
||||
1. взять `flock`;
|
||||
2. `docker compose --profile certbot run --rm certbot renew --webroot -w /var/www/certbot --quiet`;
|
||||
3. при обновлении проверить `docker compose exec -T nginx nginx -t -c /tmp/nginx.conf`;
|
||||
4. только после успеха `docker compose kill -s HUP nginx`;
|
||||
5. записать результат и метрику expiry;
|
||||
6. ненулевой exit при ошибке;
|
||||
7. не удалять действующий сертификат;
|
||||
8. success path — `0` и пустой stderr.
|
||||
|
||||
Пример unit `/etc/systemd/system/han-chat-cert-renew.service`:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=Renew HAN Chat Let's Encrypt certificate
|
||||
Requires=docker.service
|
||||
After=docker.service network-online.target
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
User=deploy
|
||||
WorkingDirectory=<BACKEND_ROOT>
|
||||
ExecStart=<BACKEND_ROOT>/deploy/ssl-renew.sh
|
||||
```
|
||||
|
||||
Timer `OnCalendar=*-*-* 03,15:20:00`, `RandomizedDelaySec=30m`, `Persistent=true`. `enable --now`, `list-timers`, `certbot renew --dry-run`. Alert <21 дней, page <7 дней. Ошибка renew не останавливает nginx.
|
||||
|
||||
Staging issuance, затем production `--cert-name` текущего host. Host для ВМ1 — `<PUBLIC_HOST>`; для ВМ2 — `<PROCESSING_PUBLIC_HOST>`; private `8443` — internal CA, не Let's Encrypt. Сертификат и ACME volume между VM не разделяются.
|
||||
Host ВМ1 — `<PUBLIC_HOST>`, ВМ2 — `<PROCESSING_PUBLIC_HOST>`; private `8443`
|
||||
использует internal CA, не Let's Encrypt. Ни ACME state, ни staging между VM не
|
||||
разделяются.
|
||||
|
||||
## 10. Сквозной порядок startup и cutover
|
||||
|
||||
@@ -337,4 +324,4 @@ DR потеря VM: новая Ubuntu в VPC, hardening, DNS, secrets из vault
|
||||
|
||||
- ВМ1: [`module-10-deployment-vm1.md`](../VM1_app/documentation/module-10-deployment-vm1.md).
|
||||
- ВМ2: [`module-10-deployment-vm2.md`](../VM2_services/documentation/module-10-deployment-vm2.md).
|
||||
- Прототипы: [`../../HAN_chat/Deploy_steps.md`](../../HAN_chat/Deploy_steps.md), [`../../HAN_chat/deploy/setup-vm-han-chat.sh`](../../HAN_chat/deploy/setup-vm-han-chat.sh), [`../../HAN_chat/deploy/init-managed-postgres.py`](../../HAN_chat/deploy/init-managed-postgres.py).
|
||||
- Исполняемые процедуры: [`RUNBOOK.production.ru.md`](../VM1_app/codebase/backend/deployment/RUNBOOK.production.ru.md) для ВМ1 и [`RUNBOOK.ru.md`](../VM2_services/codebase/services/deployment/RUNBOOK.ru.md) для ВМ2.
|
||||
|
||||
Reference in New Issue
Block a user