Реализация на отдельных двух машинах с протестированным взаимодействием по проверке сообщений
This commit is contained in:
@@ -40,7 +40,8 @@ Upstream failures не перенаправляются на другой сер
|
||||
|
||||
## 3. HTTP/HTTPS и TLS
|
||||
|
||||
- public host каждой VM на `:80` обслуживает только ACME challenge и `308 https://$host$request_uri`, кроме явно зафиксированных исключений профильной спецификации;
|
||||
- public host каждой VM на `:80` обслуживает только ACME challenge и `308 https://$host$request_uri`;
|
||||
- единственное route-specific исключение: exact CRM webhook ВМ2 по HTTP возвращает `404/426` без redirect, чтобы query token не отражался в `Location`;
|
||||
- выделенный API host, если появится, не имеет listener `:80`;
|
||||
- `:443 ssl http2`, TLS 1.2/1.3, современные cipher suites, session tickets по ops policy;
|
||||
- сертификат доверенного CA, private key read-only и недоступен приложению;
|
||||
@@ -53,24 +54,33 @@ Upstream failures не перенаправляются на другой сер
|
||||
|
||||
## 4. ACME lifecycle
|
||||
|
||||
Выбран webroot Certbot/ACME client с общими named volumes:
|
||||
Выбран webroot Certbot/ACME client с host-каталогами:
|
||||
|
||||
```text
|
||||
nginx-certs -> /etc/letsencrypt (rw у certbot, ro у nginx)
|
||||
nginx-acme-webroot -> /var/www/certbot
|
||||
/etc/letsencrypt root-only ACME state; rw только у root/ACME client
|
||||
/var/lib/han-chat/public-tls staged fullchain.pem/privkey.pem; ro bind в nginx
|
||||
/var/lib/han-chat/acme webroot; bind в nginx и ACME client
|
||||
```
|
||||
|
||||
Каждая VM выпускает **свой** сертификат на свой public host. Секреты и volumes двух projects не общие.
|
||||
Named volume для public certificate/key запрещён. Non-root nginx никогда не
|
||||
монтирует `/etc/letsencrypt`: после успешного issuance/renewal root hook
|
||||
проверяет certificate/key и атомарно копирует только нужные PEM в
|
||||
`/var/lib/han-chat/public-tls` с `root:<dedicated-tls-group>`, directory `0750`
|
||||
и files `0640`. Каждая VM выпускает **свой** сертификат на свой public host;
|
||||
host-каталоги двух VM не общие.
|
||||
|
||||
Bootstrap:
|
||||
|
||||
1. DNS указывает на VM; 80/443 разрешены.
|
||||
2. Запустить временный HTTP config с `/.well-known/acme-challenge/`.
|
||||
3. Выпустить certificate без остановки nginx.
|
||||
4. Проверить `nginx -t`, атомарно активировать TLS config, reload.
|
||||
2. Подготовить root-owned webroot `/var/lib/han-chat/acme` и временный HTTP config с `/.well-known/acme-challenge/`.
|
||||
3. Выпустить certificate в root-only `/etc/letsencrypt` без остановки nginx.
|
||||
4. Проверить certificate/key, атомарно обновить `/var/lib/han-chat/public-tls`, выполнить `nginx -t`, активировать TLS config и reload.
|
||||
|
||||
Renew container/host timer выполняет `certbot renew` минимум дважды в сутки;
|
||||
после фактического renewal проверяет рабочую конфигурацию командой
|
||||
Root-owned host timer выполняет `certbot renew` минимум дважды в сутки; ACME
|
||||
client может быть контейнеризован, но только он получает rw bind
|
||||
`/etc/letsencrypt`, а public certificate остаётся host bind, не named volume.
|
||||
После фактического renewal hook проверяет пару certificate/key, атомарно
|
||||
обновляет staging и проверяет рабочую конфигурацию командой
|
||||
`docker compose exec -T nginx nginx -t -c /tmp/nginx.conf` и отправляет
|
||||
master-процессу `docker compose kill -s HUP nginx`. Bare-команды `nginx -t` и
|
||||
`nginx -s reload` запрещены: контейнер read-only, а рабочие config/PID находятся
|
||||
@@ -82,7 +92,8 @@ success path считается дефектом интеграции с Certbot
|
||||
Контролируются expiry days и последняя успешная попытка. Staging CA используется
|
||||
в rehearsal, чтобы не исчерпать лимиты.
|
||||
|
||||
Non-root nginx не монтирует root-only дерево Let's Encrypt целиком: только необходимые cert/key files по arch-03/arch-06.
|
||||
Non-root nginx получает только read-only staging
|
||||
`/var/lib/han-chat/public-tls`; root-only `/etc/letsencrypt` ему недоступен.
|
||||
|
||||
## 5. Request ID и forwarded headers
|
||||
|
||||
@@ -176,7 +187,7 @@ nginx/
|
||||
|
||||
## 11. Docker Compose
|
||||
|
||||
`nginx` подключён к `public` и `backend` (или эквивалентным сетям своей VM). Публикация host ports разрешена только nginx. Filesystem read-only, tmpfs для cache/run/temp/`/etc/nginx/conf.d` по arch-03, non-root где позволяет bind ports/capabilities. Cert volumes read-only для nginx. ACME client имеет только необходимые volumes/network.
|
||||
`nginx` подключён к `public` и `backend` (или эквивалентным сетям своей VM). Публикация host ports разрешена только nginx. Filesystem read-only, tmpfs для cache/run/temp/`/etc/nginx/conf.d` по arch-03, non-root где позволяет bind ports/capabilities. Host staging public TLS и ACME webroot монтируются с минимальными правами; named volume сертификатов запрещён. ACME client имеет только необходимые bind mounts/network.
|
||||
|
||||
Non-root nginx получает writable tmpfs только для `/etc/nginx/conf.d`, `/var/cache/nginx`, `/var/run` и `/tmp`; tmpfs задаёт явные UID/GID/mode. Основной `nginx.conf` подключает конкретный rendered include, не неограниченный wildcard, который позволил бы обойти `nginx -t`.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user