# 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 ```