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>
This commit is contained in:
@@ -63,3 +63,11 @@ sudo haproxy -c -f /etc/haproxy/haproxy.cfg
|
||||
На хосте с HAProxy с интернета обычно открывают только то, что слушает конфиг: **25**, **443** (и при использовании — **8404** для stats). Остальной трафик — по политике безопасности.
|
||||
|
||||
Если позже добавите фронтенд на **80** для ACME (см. [letsencrypt-acme.md](letsencrypt-acme.md)), откройте и **TCP 80**.
|
||||
|
||||
## SAC и Seaca (sac-api)
|
||||
|
||||
- Веб-SAC: **`sac.kalinamall.ru`** — IP из **`git-sac-allowed`**
|
||||
- Seaca (Android): **`sac-api.kalinamall.ru`** — без allowlist; добавьте **A**-запись на тот же IP HAProxy
|
||||
- На nginx SAC (**192.168.160.145**): `server_name sac.kalinamall.ru sac-api.kalinamall.ru;`
|
||||
|
||||
Подробнее: [sac-access.md](sac-access.md).
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
# 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
|
||||
```
|
||||
Reference in New Issue
Block a user