Files
PTah f802a5ac46 HAProxy 0.7.2: sac-api для Seaca, check-ssl на всех HTTPS-бэкендах.
Веб-SAC остаётся за allowlist; sac-api.kalinamall.ru открыт для мобильных клиентов. Документация по connection coalescing Git+SAC.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-06-13 12:01:06 +10:00

94 lines
4.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# SAC: веб, Seaca (sac-api) и HAProxy
## Два имени — один сервер
| Имя | Клиенты | IP-allowlist HAProxy | Бэкенд |
|-----|---------|----------------------|--------|
| **`sac.kalinamall.ru`** | Веб-интерфейс SAC (браузер) | **Да** (`git-sac-allowed`) | 192.168.160.145:443 |
| **`sac-api.kalinamall.ru`** | Seaca (Android), mobile API | **Нет** (доступ с любого IP) | тот же 192.168.160.145:443 |
Защита `sac-api`: код регистрации `sacmob_…`, JWT, отзыв устройств в веб-SAC.
### DNS
Добавьте **A**-запись:
```text
sac-api.kalinamall.ru → тот же публичный IP, что у sac / ext / git (хост HAProxy)
```
### nginx на 192.168.160.145
В `server_name` должны быть **оба** имени (wildcard `*.kalinamall.ru` в сертификате это покрывает):
```nginx
server_name sac.kalinamall.ru sac-api.kalinamall.ru;
```
Для чужих имён (например `ext.kalinamall.ru`) — отдельный default или `return 444`, иначе SAC ответит на любой Host.
### Seaca
В приложении указывают **`https://sac-api.kalinamall.ru`**, не `sac.kalinamall.ru`.
---
## Git → SAC в одном браузере: «Page Not Found — Gitea»
### Симптом
1. Открыли **`git.kalinamall.ru`** — Gitea работает.
2. В **той же вкладке/браузере** перешли на **`sac.kalinamall.ru`**.
3. В адресной строке SAC, на экране — **Gitea 404** («Page Not Found - Gitea»).
В логах HAProxy при этом может быть **`be_git`**, хотя URL — sac.
### Причина: HTTP/2 connection coalescing
Git и SAC снаружи идут на **один IP:443** HAProxy. В режиме **TCP passthrough** backend выбирается **один раз** при ClientHello (SNI) на **TCP-соединение**.
Современные браузеры (Chrome, Firefox) при **HTTP/2** могут **объединять** несколько hostname на одном IP в **одно TLS-соединение**, если сертификаты «совместимы» (часто так с `*.kalinamall.ru`).
Тогда:
1. Первое соединение: SNI `git.kalinamall.ru` → HAProxy → **Gitea**.
2. Запрос к `sac.kalinamall.ru` идёт **по тому же TCP** (без нового SNI для HAProxy).
3. Gitea получает `Host: sac.kalinamall.ru` → отдаёт **404 Gitea**.
Это **не ошибка маршрутизации ACL** и **не баг SAC** — ограничение схемы «несколько HTTPS-имён на одном IP + TCP passthrough».
### Обходные пути (без смены архитектуры)
| Способ | Комментарий |
|--------|-------------|
| **Новая вкладка / приватное окно** для SAC после Git | Новое TCP-соединение, свой SNI |
| **Закрыть вкладку с Git** перед SAC | Сброс keep-alive / H2 coalescing |
| **Разные публичные IP** в DNS: `git.*` → IP1, `sac.*` → IP2 | Надёжное решение для passthrough |
| **`http2 off;`** в nginx Gitea и SAC | Часто уменьшает coalescing (на серверах .129 и .145) |
| **`Connection: close`** в ответах Git | Жёстче рвёт keep-alive (на .129) |
### Долгосрочно
- Отдельный WAN IP для Git и для SAC, **или**
- TLS-терминация на HAProxy с маршрутизацией по Host (больше изменений).
---
## Деплой изменений HAProxy
```bash
sudo cp ~/reverse-proxy/haproxy.cfg /etc/haproxy/haproxy.cfg
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
sudo systemctl reload haproxy
```
Проверка:
```bash
# веб SAC — только с allowlist IP
curl -sI --resolve sac.kalinamall.ru:443:ПУБЛИЧНЫЙ_IP https://sac.kalinamall.ru/dashboard
# mobile API — с любого IP
curl -s --resolve sac-api.kalinamall.ru:443:ПУБЛИЧНЫЙ_IP https://sac-api.kalinamall.ru/health
```