Веб-SAC остаётся за allowlist; sac-api.kalinamall.ru открыт для мобильных клиентов. Документация по connection coalescing Git+SAC. Co-authored-by: Cursor <cursoragent@cursor.com>
4.2 KiB
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-запись:
sac-api.kalinamall.ru → тот же публичный IP, что у sac / ext / git (хост HAProxy)
nginx на 192.168.160.145
В server_name должны быть оба имени (wildcard *.kalinamall.ru в сертификате это покрывает):
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»
Симптом
- Открыли
git.kalinamall.ru— Gitea работает. - В той же вкладке/браузере перешли на
sac.kalinamall.ru. - В адресной строке 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).
Тогда:
- Первое соединение: SNI
git.kalinamall.ru→ HAProxy → Gitea. - Запрос к
sac.kalinamall.ruидёт по тому же TCP (без нового SNI для HAProxy). - 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
sudo cp ~/reverse-proxy/haproxy.cfg /etc/haproxy/haproxy.cfg
sudo haproxy -c -f /etc/haproxy/haproxy.cfg
sudo systemctl reload haproxy
Проверка:
# веб 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