# 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_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":""` — сканеры, чужой SNI, allowlist reject | | `haproxy-zabbix-403` | httplog: `fe_http_zabbix` + `403` | ```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. После `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`