Files

10 KiB
Raw Permalink Blame History

module-03-vm2. Nginx ВМ2 Processing

Статус: целевая спецификация nginx на ВМ2.
Канонический контракт (TLS/ACME, request id, internal 404, logs, reload) — arch-08-nginx.md.
Контур ВМ1 — module-03-nginx-vm1.md. Guest API, SPA, auth и SMS callback на этой машине не публикуются.

1. Назначение и границы

Nginx ВМ2 — самостоятельный ingress Processing:

  • public 80/443 на отдельном DNS host: ACME/redirect и два exact CRM webhook;
  • private 8443 с сертификатом internal CA: только server-to-server Message Safety и approved ops.

Публичный трафик ВМ2 не проходит через ВМ1. Отказ nginx ВМ1 не прерывает приём CRM webhook. SPA, /api/, /auth/, WS и Direct SMS callback здесь отсутствуют.

2. Routing matrix

Public 80/443

Внешний путь Upstream Режим
exact /bitrix/sync/webhook/contact bitrix-sync:8080 public HTTPS Contact event; source IP CIDR/method/body/rate limits, query-token auth в upstream
exact /bitrix/sync/webhook/alert bitrix-sync:8080 public HTTPS smart-process event; те же ограничения

До full sync cutover оба exact webhook route закрыты либо возвращают retryable 503; успешный 2xx ignored запрещён.

Query не участвует в exact location matching: URL штатного робота /bitrix/sync/webhook/<type>?token=...&ID=... попадает в соответствующий exact route.

/internal/, /_internal/, Redis/OTLP/admin/status/config files на public host → 404. Fallback на ВМ1 или SPA запрещён. Прочие paths/methods → 404/405.

Private 8443

Path Local upstream Caller
/internal/safety/v2/* message-safety-api:8080 api-backend ВМ1
exact /internal/safety/status message-safety-api:8080/health/ready api-backend ВМ1, ops; capability snapshot, не correctness gate
/internal/sync/v1/* bitrix-sync:8080 ops/allow-listed service

Public и private server blocks не имеют общего fallback. Safety status alias доступен только на private listener; public /health/ready и /internal/safety/status не публикуются.

3. Webhook allow-list и preflight

До proxy nginx проверяет непосредственный source IP по version-controlled BITRIX_WEBHOOK_ALLOWED_CIDRS; пустой/невалидный список при enabled receiver блокирует deployment. Адрес из недоверенного X-Forwarded-For не используется.

BITRIX_SYNC_ENABLED, public route, readiness и allow-list согласуются одним preflight: disabled требует deny all;, enabled — reviewed non-empty CIDR и ready receiver. Обратные комбинации блокируют deployment.

Запрос вне allow-list получает generic 403 без proxy. В безопасном журнале с ограниченным retention сохраняются только timestamp, source IP, route class и outcome; query/body не сохраняются. Telemetry pipeline экспортирует webhook_rejected_total{receiver,reason="source_ip"} без IP label. Allow-list не расширяется автоматически: всплеск Contact, восстановленных инкрементальной reconciliation, инициирует проверку rejected-IP журнала, подтверждение принадлежности адреса Битрикс24 и reviewed reload конфигурации.

Bitrix webhook retries имеют отдельный достаточный burst, проходят source IP allow-list и проверяют query receiver token в сервисе.

4. Private 8443 fail-closed

До утверждённого Safety cutover active caller allow-list содержит только deny all;; после cutover он совпадает с SG/host-firewall источниками ВМ1. Расхождение любого из трёх слоёв (nginx allow-list, SG, host firewall) блокирует rollout.

Private listener доверяет forwarded headers только от allow-listed private caller.

5. Listeners и TLS

  • :80 — только ACME challenge и 308 https://$host$request_uri;
  • исключение: /bitrix/sync/webhook/contact|alert на HTTP возвращают generic 404/426 без redirect и отражения query token;
  • :443 — только ACME-совместимый TLS и exact CRM webhook;
  • private :8443 — internal CA, SAN совпадает с private DNS именем ВМ2;
  • public и private сертификаты разные; public key недоступен приложению.

6. Timeouts и body limits ВМ2

CRM webhook: connect/send/read 3s / 30s / 60s (arch-08). Private Safety не короче caller budget. JSON body webhook ограничен; file bytes через этот nginx не идут. Cache на webhook выключен.

7. Edge rate limits ВМ2

Отдельные зоны для двух exact webhook (мягкий burst под retries Битрикс24) и limit_conn. Зоны guest API/auth/WS/SPA/SMS на ВМ2 не создаются.

Ответ превышения — 429, Retry-After, request id. Generic 403 для wrong source IP — до proxy, не 429.

8. Security headers

Public webhook: не кэшировать, не ослаблять CSP ради SPA (SPA нет). Server / X-Powered-By скрыты (arch-08). CORS wildcard с credentials запрещён; webhook не требует browser CORS.

9. Health и synthetic ВМ2

Внутренний /nginx-health/live — arch-08 §8. Synthetic отдельно: HTTP redirect/ACME policy, internal 404 на public host, GET webhook 405/404, valid отдельный cert, POST webhook allowed/denied source IP без помещения query token в shell history или логи. Private 8443 проверяется с VM1/ops host, не из интернета.

10. Layout и Compose ВМ2

Каркас arch-08 §10 плюс:

  • отдельный template/server block private 8443;
  • snippet/allow-list BITRIX_WEBHOOK_ALLOWED_CIDRS;
  • без websocket.conf и без frontend-static.

Public ports: ${NGINX_HTTP_PORT}:80, ${NGINX_HTTPS_PORT}:443. Private 8443 публикуется только в сеть/SG, разрешённую ВМ1 и ops — не как internet listener. Детали портов/SG — arch-03 / arch-06 / arch-10-deployment.md.

11. Failure behavior ВМ2

Дополнительно к arch-08 §12:

  • rollback sync: закрыть public webhook routes либо вернуть retryable 503; возврат к фиктивному 202 ignored запрещён;
  • ВМ1 при этом не изменяется;
  • Safety slow на private 8443: не маскировать ошибку 2xx; caller ВМ1 держит poll budget.

12. Валидация и тесты ВМ2

Автоматические тесты:

  • CRM webhook exact routes принимают query без изменения location matching;
  • allowed source IP проксируется, wrong IP получает 403 до upstream;
  • HTTP webhook URL с query token не перенаправляется на HTTPS и не отражает query в Location/error;
  • source-IP rejects попадают в безопасный bounded-retention журнал и low-cardinality telemetry без query/body/IP label;
  • disabled/deny all и enabled/ready/CIDR preflight: обратные комбинации блокируют deployment;
  • public /internal/safety/* и /internal/sync/*404;
  • private exact /internal/safety/status возвращает capability readiness Safety, а соседние неразрешённые health paths → 404;
  • private 8443 до cutover deny all, после cutover только источники ВМ1;
  • GET webhook 405/404; прочие paths 404;
  • TLS scan public host и отдельная проверка internal CA на 8443;
  • ACME/redirect rehearsal без остановки приёма (кроме контролируемого окна);
  • logs/traces не содержат query token, form body, Authorization.

Acceptance не использует public host ВМ1 и не требует running nginx ВМ1.

13. Definition of Done ВМ2

Дополнительно к arch-08 §13:

  • независимые public 80/443 и private 8443;
  • routing matrix §2 покрыта;
  • CRM webhook достигает ВМ2 напрямую и продолжает приниматься при остановленном nginx ВМ1;
  • CRM webhook ограничен version-controlled source IP CIDR allow-list; query token и form body отсутствуют в access/error logs и traces;
  • preflight BITRIX_SYNC_ENABLED согласован с route/allow-list/readiness;
  • private Safety не опубликован на public host.

14. TBD ВМ2

  • N1: доверенные WAF/LB CIDR перед public host ВМ2, если появятся; до этого allow-list — непосредственный source IP.
  • N3: нужен ли публичный health на processing host.
  • N6: финальный burst webhook зон.

15. Ссылки