Files
reverse-proxy/docs/security/haproxy-host.md
T
PTah ade8e4cafa fix(haproxy): Autodiscover на :80 и точный fail2ban для Zabbix
Outlook при настройке ext.kalinamall.ru слал GET /autodiscover/autodiscover.xml на порт 80; старый fe_http_zabbix отвечал 403 всем не-zabbix Host, fail2ban банил клиента на сутки. fe_http проксирует Autodiscover на Exchange :80, 403 только для zabbix вне allowlist, ignoreregex для /autodiscover/.
2026-06-20 16:58:32 +10:00

124 lines
4.6 KiB
Markdown
Raw 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.
# HAProxy: UFW и hardening
Хост: **haproxy.kalinamall.ru**, **192.168.160.117**, Ubuntu 24.04, HAProxy 2.8.x.
## Порты на хосте
| Порт | Служба | С интернета (MikroTik) | UFW (текущий план) |
|------|--------|------------------------|---------------------|
| 22 | sshd | нет DNAT | только `SSH_ALLOWED` |
| 25 | fe_smtp → KSMG | **нет** (25 → `.57`) | **закрыт** |
| 80 | fe_http (Autodiscover + Zabbix) | да | все |
| 443 | fe_https_sni | да | все |
| 8404 | stats (закомментирован) | нет | только `SSH_ALLOWED` |
## UFW — правила
Скрипт: [haproxy-ufw-apply.sh](../../scripts/security/haproxy-ufw-apply.sh).
```
default incoming: deny
default outgoing: allow
22/tcp from 5.100.81.121, 192.168.128.0/17
8404/tcp from 5.100.81.121, 192.168.128.0/17 # если включите fe_stats
80/tcp from anywhere
443/tcp from anywhere
```
`192.168.128.0/17` покрывает офисную/VPN-подсеть (в т.ч. `192.168.160.0/24`).
Ответный трафик с бэкендов (`.42`, `.129` → высокие порты на `.117`):
```
ufw allow from 192.168.160.0/24 comment 'LAN backends return'
```
(в [haproxy-ufw-apply.sh](../../scripts/security/haproxy-ufw-apply.sh) — `LAN_BACKENDS_CIDR`).
### Env
`/etc/haproxy/security/haproxy-ufw.env` (из [haproxy-ufw.env.example](../../scripts/security/haproxy-ufw.env.example)):
```bash
SSH_ALLOWED="5.100.81.121 192.168.128.0/17"
INBOUND_TCP="80 443"
STATS_TCP="8404"
UFW_IPV6=no
```
### Внедрение
```bash
sudo mkdir -p /etc/haproxy/security
sudo cp ~/reverse-proxy/scripts/security/haproxy-ufw.env.example /etc/haproxy/security/haproxy-ufw.env
sudo bash ~/reverse-proxy/scripts/security/haproxy-ufw-apply.sh
# вторая SSH-сессия:
sudo bash ~/reverse-proxy/scripts/security/haproxy-ufw-apply.sh --apply
sudo ufw status numbered
```
**Откат:** `sudo ufw disable` (временно).
### Проверка
- SSH с `5.100.81.121` или из `192.168.128.0/17` — OK.
- SSH с другого IP — timeout/refused.
- `curl -I http://zabbix.kalinamall.ru` / HTTPS на allowlist-сервис — OK.
- `ss -tlnp | grep :25` — слушает HAProxy, но UFW + MikroTik не пускают с периметра.
## fe_smtp (:25)
Inbound-почта с интернета идёт на **KSMG `.57`**, не на HAProxy. `fe_smtp` в `haproxy.cfg` можно оставить для LAN или **отключить**, если не используется — UFW его не открывает.
## stats (:8404)
В `haproxy.cfg` закомментирован. Если включите — UFW уже ограничит доступ списком `SSH_ALLOWED`; обязательно `stats auth` и не `0.0.0.0` без нужды.
## Рекомендуется дополнительно (не блокирует UFW)
| Мера | Зачем |
|------|--------|
| SSH: ключи, `PermitRootLogin no`, `PasswordAuthentication no` | до/вместе с UFW |
| fail2ban на sshd | подстраховка SSH |
| fail2ban на HAProxy JSON | бан сканеров / reject SNI / Zabbix 403 |
| `unattended-upgrades` | патчи |
| Не открывать лишние listen | `ss -tlnp` |
Опционально позже: sysctl syncookies, rate-limit на frontend, allowlist для Exchange/sac-api.
## fail2ban (HAProxy JSON)
Скрипт: [fail2ban-install.sh](../../scripts/security/fail2ban-install.sh), конфиги в `scripts/security/fail2ban/`.
| Jail | Что ловит |
|------|-----------|
| `haproxy-reject` | JSON: `"be":"fe_https_sni","srv":"<NOSRV>"` — сканеры, чужой SNI, allowlist reject |
| `haproxy-zabbix-403` | httplog: `fe_http` + **403** только при доступе к Zabbix с IP вне `zabbix-allowed` (не Autodiscover) |
```bash
sudo apt install -y fail2ban
sudo bash ~/reverse-proxy/scripts/security/fail2ban-install.sh
sudo fail2ban-client status haproxy-reject
```
Порог: **15** reject за **10 мин** → бан **24 ч** через UFW. `ignoreip`: LAN, VPN, admin.
**sshd:** `jail.d/sshd.local``banaction = ufw`, те же `ignoreip` (не банить admin/VPN/LAN).
После `systemctl restart fail2ban` подождите 1–2 с перед `fail2ban-client status` (сокет).
### SSH (пример)
`/etc/ssh/sshd_config.d/99-hardening.conf`:
```
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
AllowUsers papatramp
```
`sshd -t && systemctl reload sshd`