docs: периметр MikroTik — на HAProxy только 80/443

Уточнено: порт 25 с интернета не проброшен; inbound-почта не через HAProxy.
This commit is contained in:
Andrey Lutsenko
2026-06-13 22:24:48 +10:00
parent a337bbdda1
commit e3201ae41b
11 changed files with 47 additions and 34 deletions
+1 -1
View File
@@ -63,7 +63,7 @@ sudo haproxy -c -f /etc/haproxy/haproxy.cfg
## Порты на фаерволе
На хосте с HAProxy с интернета обычно открывают только то, что слушает конфиг: **25**, **80** (Zabbix HTTP), **443** (и при использовании — **8404** для stats). Остальной трафик — по политике безопасности.
На хосте с HAProxy с **интернета** (MikroTik DNAT) доступны только **80** (Zabbix HTTP) и **443**. Порт **25** в конфиге есть, но с периметра **не проброшен**. Остальной трафик — по политике безопасности.
**Полный план:** [docs/security/README.md](security/README.md) — UFW, бэкенды, чеклист, скрипты `scripts/security/`.
+5 -5
View File
@@ -1,13 +1,13 @@
# Безопасность периметра HAProxy (kalinamall.ru)
# Безопасность периметра HAProxy (kalinamall.ru)
План защиты хоста **haproxy.kalinamall.ru** и **бэкендов** за ним. HAProxy слушает **25**, **80**, **443**; фильтрация по SNI/Host и allowlist уже в `haproxy.cfg`, но **UFW на хосте inactive** — ниже поэтапное включение **defense in depth**.
План защиты хоста **haproxy.kalinamall.ru** и **бэкендов** за ним. HAProxy слушает **25**, **80**, **443**; с **интернета** (MikroTik DNAT) доступны только **80** и **443**. Фильтрация по SNI/Host и allowlist уже в `haproxy.cfg`, но **UFW на хосте inactive** — ниже поэтапное включение **defense in depth**.
## Модель угроз (кратко)
| Уровень | Что закрывает |
|---------|----------------|
| **MikroTik / провайдер** | DDoS, geo, лишние порты до DMZ |
| **UFW на HAProxy** | Вход только 25/80/443 + SSH с доверенных IP |
| **MikroTik / провайдер** | DDoS, geo; DNAT на HAProxy только **80/443** |
| **UFW на HAProxy** | SSH с доверенных IP; **80/443****25** только если нужен с LAN) |
| **HAProxy ACL** | Неизвестный SNI, allowlist по сервисам |
| **UFW на бэкендах** | Сервисы доступны **только с IP HAProxy** (`192.168.160.117`) |
| **Приложение** | Auth OWA, RD Gateway, Gitea, SAC, 1С |
@@ -51,4 +51,4 @@ Allowlist-файлы в `/etc/haproxy/` (**не** заменяют UFW):
- `git-sac-allowed`, `rds-allowed`, `1c-allowed`, `zabbix-allowed`, `syno-allowed`
Сервисы **без** allowlist на 443: **Exchange** (`ext`, `autodiscover`), **sac-api**, **SMTP 25** — усилить на уровне приложения и мониторинга; при необходимости добавить allowlist или rate-limit (см. [haproxy-host.md](haproxy-host.md)).
Сервисы **без** allowlist на 443: **Exchange** (`ext`, `autodiscover`), **sac-api**. **SMTP 25** с интернета на HAProxy **не проброшен** (см. [architecture.md](architecture.md)); `fe_smtp` — для LAN/внутреннего использования.
+1 -1
View File
@@ -23,7 +23,7 @@
<text class="edge-label" x="150" y="136">DNAT публичный IP</text>
<rect class="box" x="20" y="146" width="260" height="40" rx="6"/>
<text class="text" x="150" y="171">HAProxy 192.168.160.117 (25 80 443)</text>
<text class="text" x="150" y="171">HAProxy 192.168.160.117 (80 443)</text>
<line class="edge" x1="150" y1="186" x2="150" y2="214"/>

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

+8 -5
View File
@@ -9,20 +9,23 @@
Та же схема текстом:
```text
Интернет → MikroTik (DNAT) → HAProxy .117 (25/80/443) → ACL (SNI/Host) → бэкенды .160.0/24
Интернет → MikroTik (DNAT 80/443) → HAProxy .117 → ACL (SNI/Host) → бэкенды .160.0/24
```
**Периметр MikroTik:** с интернета на HAProxy проброшены только **80** и **443**. Порт **25** (и прочие) на HAProxy снаружи **недоступны** — DNAT не настроен.
## Два контура
### 1. Публичный вход (через HAProxy)
Клиент → публичный IP → **HAProxy** → (проверки) → один бэкенд.
Клиент → публичный IP → **MikroTik (DNAT 80/443)****HAProxy** → (проверки) → один бэкенд.
На HAProxy уже есть:
На HAProxy с интернета доступны только:
- **443/TCP**: отклонение неизвестного SNI; allowlist для git, sac-web, rds, erp, syno.
- **80/HTTP**: только `Host: zabbix.kalinamall.ru` + `zabbix-allowed`.
- **25/SMTP**: passthrough на KSMG без IP-фильтра на frontend.
**25/SMTP** в `haproxy.cfg` слушает на хосте, но **с интернета не проброшен** (MikroTik DNAT только 80/443). Inbound-почта на KSMG идёт **не через** HAProxy:25 с периметра.
### 2. Внутренняя сеть (LAN / VPN)
@@ -58,7 +61,7 @@ Health-check HAProxy и прокси идут **с этого IP**. Правил
## Принципы
1. **Default deny** на вход (UFW `incoming deny`, бэкенды — только HAProxy + admin).
2. **Минимум открытых портов** с интернета: 25, 80, 443 на одном хосте.
2. **Минимум открытых портов** с интернета на HAProxy: **80** и **443** (DNAT на MikroTik).
3. **Не дублировать** смысл правил без нужды: allowlist в HAProxy для HTTP/SNI; UFW — транспорт и админ.
4. **Сначала dry-run**, потом `--apply`; для SSH — **console/IPMI** или сессия, которую UFW не оборвёт.
5. **Логи**: HAProxy + UFW + fail2ban; алерты на аномалии (Zabbix уже в инфраструктуре).
+4 -2
View File
@@ -1,4 +1,4 @@
# Firewall на бэкендах
# Firewall на бэкендах
Цель: сервисный порт доступен **с HAProxy** (`192.168.160.117`) и при необходимости с **admin**-подсетей; **не** с произвольного LAN/Internet напрямую.
@@ -40,7 +40,9 @@ UFW_EXTRA_SERVICES="2222/tcp" # если Gitea SSH с admin LAN
### KSMG (192.168.160.57:25)
Почта с интернета приходит на **HAProxy:25** → KSMG. На KSMG в `EXTRA_ALLOWED` укажите **192.168.160.117**. Если другие MTA шлют **напрямую** на `.57` (минуя HAProxy), их IP тоже нужно явно разрешить — иначе после UFW почта встанет.
С **интернета** на HAProxy проброшены только **80/443** — inbound SMTP **не** приходит на **HAProxy:25**. Почта с периметра идёт **напрямую на KSMG** (или иным маршрутом), минуя HAProxy.
`fe_smtp` в `haproxy.cfg` — для **LAN** (прокси на KSMG с `.117`). На KSMG в `EXTRA_ALLOWED` укажите **192.168.160.117**, если этот путь используется. IP внешних MTA, шлющих **напрямую** на `.57`, тоже нужно явно разрешить — иначе после UFW почта встанет.
### RDS (192.168.160.40)
+5 -5
View File
@@ -1,8 +1,8 @@
# Чеклист после внедрения защиты
# Чеклист после внедрения защиты
## HAProxy (192.168.160.117)
- [ ] `ufw status verbose` — active; есть 22 из admin, 25/80/443 open
- [ ] `ufw status verbose` — active; есть 22 из admin, **80/443** open (25 — только если явно включён для LAN)
- [ ] SSH с admin-IP работает; с random IP — **нет** (или только ключ + fail2ban)
- [ ] `ss -tlnp` — нет лишних listen (8404, 3000, …)
- [ ] `haproxy -c -f /etc/haproxy/haproxy.cfg` — OK
@@ -13,7 +13,7 @@
## MikroTik / периметр
- [ ] С интернета на публичный IP: открыты только **25, 80, 443**
- [ ] С интернета на публичный IP: открыты только **80, 443**
- [ ] Нет DNAT 3389, 5001, 4430 на внутренние хосты
- [ ] HAProxy health-check не блокируется
@@ -27,8 +27,8 @@
## KSMG (.57)
- [ ] Почта inbound через HAProxy:25 — OK
- [ ] Прямые отправители (если есть) — в `EXTRA_ALLOWED`
- [ ] Inbound-почта с интернета **не** идёт через HAProxy:25 (DNAT на MikroTik только 80/443)
- [ ] На KSMG в `EXTRA_ALLOWED`**192.168.160.117** (если используется `fe_smtp` из LAN) и прямые MTA
## Документация и runbook
+4 -4
View File
@@ -1,10 +1,10 @@
# План развёртывания защиты
# План развёртывания защиты
Оценка: **24 рабочих дня** с окнами обслуживания на бэкендах (по одному хосту).
## Фаза 0 — Подготовка (без изменений на проде)
- [ ] Зафиксировать **публичный IP** HAProxy и правила DNAT на MikroTik.
- [ ] Зафиксировать **публичный IP** HAProxy и правила DNAT на MikroTik (**только 80/443**).
- [ ] Убедиться, что **SSH** на `192.168.160.117` доступен с admin-IP (не только с одного ноутбука).
- [ ] Снимок/backup: `haproxy.cfg`, allowlist, `/etc/ssh/sshd_config`.
- [ ] Клонировать репозиторий на HAProxy: `git pull kalinamall main`.
@@ -36,7 +36,7 @@
- [ ] Dry-run: `bash scripts/security/haproxy-ufw-apply.sh`
- [ ] **Не закрывая SSH-сессию**, в second tab: `bash scripts/security/haproxy-ufw-apply.sh --apply`
- [ ] Проверить с admin-IP: `ssh haproxy.kalinamall.ru`, `curl` на 80/443 с allowlist.
- [ ] Проверить SMTP 25 с внешнего MTA (если используется).
- [ ] Убедиться, что **25** с интернета на HAProxy **не** доступен (ожидаемо: DNAT не настроен).
**Откат:** `ufw disable` (временно) или `ufw delete` по номерам правил; env-файл сохранить.
@@ -68,7 +68,7 @@
## Фаза 4 — MikroTik и мониторинг
- [ ] На MikroTik: с интернета на HAProxy только **25, 80, 443** (не пробрасывать 3389, 5001, 4430 на внутренние IP).
- [ ] На MikroTik: с интернета на HAProxy только **80, 443** (не пробрасывать 25, 3389, 5001, 4430 на внутренние IP).
- [ ] Raw/firewall: опционально drop obvious scanners (согласовать с `rds-allowed` / RU geo).
- [ ] Zabbix: триггеры на `ufw status`, `fail2ban`, рост `fe_https_sni` reject, backend DOWN.
- [ ] Ротация логов `/var/log/haproxy.log`.
+8 -3
View File
@@ -1,4 +1,4 @@
# Hardening хоста HAProxy
# Hardening хоста HAProxy
Хост: **haproxy.kalinamall.ru**, **192.168.160.117**, Ubuntu 24.04, HAProxy 2.8.x.
@@ -7,12 +7,16 @@
| Порт | Frontend | Назначение |
|------|----------|------------|
| 22 | sshd | Администрирование (не в haproxy.cfg) |
| 25 | fe_smtp | SMTP → KSMG |
| 25 | fe_smtp | SMTP → KSMG (**LAN**; с интернета не проброшен) |
| 80 | fe_http_zabbix | HTTP Zabbix |
| 443 | fe_https_sni | TLS passthrough по SNI |
Не включать **8404/stats** на `0.0.0.0` без VPN и пароля.
## Периметр (MikroTik)
С **интернета** на публичный IP HAProxy проброшены только **TCP 80** и **443**. Остальные порты HAProxy (в т.ч. **25**) снаружи **недоступны** — DNAT не настроен.
## UFW
Скрипт: [haproxy-ufw-apply.sh](../../scripts/security/haproxy-ufw-apply.sh).
@@ -23,7 +27,8 @@
default incoming: deny
default outgoing: allow
allow 22/tcp from SSH_ALLOWED
allow 25, 80, 443/tcp from anywhere # сервисы периметра
allow 80, 443/tcp from anywhere # сервисы периметра (MikroTik DNAT)
# allow 25/tcp from LAN_CIDR # только если нужен SMTP через HAProxy изнутри сети
```
**SSH_ALLOWED** — несколько CIDR/ IP через пробел в env. Минимум: