Files
reverse-proxy/haproxy.cfg
T
PTah 088eec369f fix(haproxy): ACL 404 для HAProxy 2.8 и deploy-скрипт
Исправлен синтаксис !(host_ext path_autodiscover) и порядок http-request/use_backend. Скрипт deploy сохраняет stats auth с сервера.
2026-06-20 17:06:09 +10:00

185 lines
8.6 KiB
INI
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 — периметровый reverse-proxy для kalinamall.ru
# Config version: 0.7.8
# Режим: TCP + SNI на 443 (TLS end-to-end, сертификаты на бэкендах)
# HTTP на 80: Exchange Autodiscover (ext/autodiscover) + zabbix.kalinamall.ru (allowlist)
#
# Проверка синтаксиса: haproxy -c -f haproxy.cfg
# Установка: скопируйте в /etc/haproxy/haproxy.cfg
# Allowlist: git-sac-allowed, 1c-allowed, zabbix-allowed, syno-allowed, rds-allowed → /etc/haproxy/
# rds-allowed: ежедневно scripts/haproxy-rds-allowed-deploy.sh (ipdeny RU + rds-allowed-static)
# sac-api.kalinamall.ru — без IP-фильтра (Seaca с любого адреса, auth на SAC)
global
log stdout format raw local0
maxconn 50000
# Раскомментируйте на Linux с syslog:
# log /dev/log local0
defaults
log global
mode tcp
option dontlognull
option tcplog
timeout connect 10s
timeout client 3600s
timeout server 3600s
# Для ActiveSync / больших вложений Exchange при необходимости увеличьте client/server
# -----------------------------------------------------------------------------
# HTTPS (443): маршрутизация по SNI → внутренние серверы
# ext, autodiscover (Exchange) / rds / erp / git / sac / sac-api / heap, exchange (Synology)
# Git и sac.kalinamall.ru (веб) — allowlist git-sac-allowed
# rds.kalinamall.ru — allowlist rds-allowed (RU ipdeny + static)
# heap.kalinamall.ru, exchange.kalinamall.ru (Synology DSM) — syno-allowed
# sac-api.kalinamall.ru (мобильное API) — без allowlist
# См. docs/sac-access.md — connection coalescing (git + sac на одном IP)
# -----------------------------------------------------------------------------
frontend fe_https_sni
bind *:443
mode tcp
option tcplog
log-format '{"time":"%t","client":"%ci","port":%cp,"fe":"%f","be":"%b","srv":"%s","sni":%{+Q}[capture.req.hdr(0)],"bytes":%B,"term":"%tsc","tw":%Tw,"tc":%Tc,"tt":%Tt}'
tcp-request inspect-delay 5s
tcp-request content capture req.ssl_sni len 128
tcp-request content accept if { req_ssl_hello_type 1 }
# SNI должен быть из списка (несколько acl с одним именем — логическое ИЛИ)
acl sni_known req_ssl_sni -i ext.kalinamall.ru
acl sni_known req_ssl_sni -i autodiscover.kalinamall.ru
acl sni_known req_ssl_sni -i rds.kalinamall.ru
acl sni_known req_ssl_sni -i erp.kalinamall.ru
acl sni_known req_ssl_sni -i git.kalinamall.ru
acl sni_known req_ssl_sni -i sac.kalinamall.ru
acl sni_known req_ssl_sni -i sac-api.kalinamall.ru
acl sni_known req_ssl_sni -i heap.kalinamall.ru
acl sni_known req_ssl_sni -i exchange.kalinamall.ru
acl sni_git req_ssl_sni -i git.kalinamall.ru
acl sni_sac_web req_ssl_sni -i sac.kalinamall.ru
acl sni_rds req_ssl_sni -i rds.kalinamall.ru
acl sni_erp req_ssl_sni -i erp.kalinamall.ru
acl sni_syno req_ssl_sni -i heap.kalinamall.ru
acl sni_syno req_ssl_sni -i exchange.kalinamall.ru
acl src_git_sac_allowed src -f /etc/haproxy/git-sac-allowed
acl src_rds_allowed src -f /etc/haproxy/rds-allowed
acl src_1c_allowed src -f /etc/haproxy/1c-allowed
acl src_syno_allowed src -f /etc/haproxy/syno-allowed
# tcp-request обрабатываются до use_backend — reject ставим ДО use_backend
tcp-request content reject if !sni_known
tcp-request content reject if sni_git !src_git_sac_allowed
tcp-request content reject if sni_sac_web !src_git_sac_allowed
tcp-request content reject if sni_rds !src_rds_allowed
tcp-request content reject if sni_erp !src_1c_allowed
tcp-request content reject if sni_syno !src_syno_allowed
use_backend be_exchange if { req_ssl_sni -i ext.kalinamall.ru }
use_backend be_exchange if { req_ssl_sni -i autodiscover.kalinamall.ru }
use_backend be_rds if { req_ssl_sni -i rds.kalinamall.ru }
use_backend be_erp if { req_ssl_sni -i erp.kalinamall.ru }
use_backend be_git if { req_ssl_sni -i git.kalinamall.ru }
use_backend be_sac if { req_ssl_sni -i sac.kalinamall.ru }
use_backend be_sac if { req_ssl_sni -i sac-api.kalinamall.ru }
use_backend be_syno_heap if { req_ssl_sni -i heap.kalinamall.ru }
use_backend be_syno_exchange if { req_ssl_sni -i exchange.kalinamall.ru }
backend be_exchange
# fifth.kalinamall.ru (192.168.160.42)
server exch 192.168.160.42:443 check check-ssl check-sni ext.kalinamall.ru verify none
backend be_rds
# k6a-dc3.b26.kalinamall.ru (192.168.160.40), TLS на 4430; снаружи только IP из rds-allowed
server rds 192.168.160.40:4430 check check-ssl check-sni rds.kalinamall.ru verify none
backend be_erp
# hp-serv.b26.kalinamall.ru (192.168.160.150)
server erp 192.168.160.150:443 check check-ssl check-sni erp.kalinamall.ru verify none
backend be_git
# git.kalinamall.ru (192.168.160.129); снаружи только IP из git-sac-allowed
server git 192.168.160.129:443 check check-ssl check-sni git.kalinamall.ru verify none
backend be_sac
# sac.kalinamall.ru + sac-api.kalinamall.ru → 192.168.160.145
# веб sac.kalinamall.ru — только IP из git-sac-allowed; sac-api — без фильтра на frontend
server sac 192.168.160.145:443 check check-ssl check-sni sac.kalinamall.ru verify none
backend be_syno_heap
# heap.kalinamall.ru → Synology DSM (192.168.160.185:5001); allowlist syno-allowed
# TLS на NAS: wildcard *.kalinamall.ru (GlobalSign); check-sni heap.kalinamall.ru
server syno_heap 192.168.160.185:5001 check check-ssl check-sni heap.kalinamall.ru verify none
backend be_syno_exchange
# exchange.kalinamall.ru → Synology DSM (192.168.160.35:5001); не путать с ext (OWA)
server syno_exch 192.168.160.35:5001 check check-ssl check-sni exchange.kalinamall.ru verify none
# -----------------------------------------------------------------------------
# HTTP (80): Exchange Autodiscover (Outlook) + Zabbix UI
# Autodiscover: autodiscover.kalinamall.ru, ext.kalinamall.ru/autodiscover/* → Exchange :80
# Zabbix: только Host zabbix.kalinamall.ru + allowlist /etc/haproxy/zabbix-allowed
# Прочие Host на :80 → 404 (не 403), чтобы fail2ban не путал с атакой на Zabbix
# -----------------------------------------------------------------------------
frontend fe_http
bind *:80
mode http
option httplog
option forwardfor except 127.0.0.0/8
acl host_zabbix hdr(host) -i zabbix.kalinamall.ru
acl host_autodiscover hdr(host) -i autodiscover.kalinamall.ru
acl host_ext hdr(host) -i ext.kalinamall.ru
acl path_autodiscover path_beg /autodiscover
acl src_zabbix_allowed src -f /etc/haproxy/zabbix-allowed
# Zabbix: 403 только при неверном IP (fail2ban haproxy-zabbix-403)
http-request deny deny_status 403 if host_zabbix !src_zabbix_allowed
http-request deny deny_status 404 if host_ext !path_autodiscover
http-request deny deny_status 404 if !host_zabbix !host_autodiscover !host_ext
use_backend be_exchange_http if host_autodiscover
use_backend be_exchange_http if host_ext path_autodiscover
use_backend be_zabbix if host_zabbix
backend be_exchange_http
mode http
option forwardfor
# fifth.kalinamall.ru (192.168.160.42) — IIS Autodiscover / редирект на HTTPS OWA
server exch 192.168.160.42:80 check
backend be_zabbix
mode http
option forwardfor
# zabbix.kalinamall.ru (192.168.160.53), веб только HTTP
server zabbix 192.168.160.53:80 check
# -----------------------------------------------------------------------------
# SMTP (25): почтовый шлюз KSMG — ksmg.kalinamall.ru
# -----------------------------------------------------------------------------
frontend fe_smtp
bind *:25
default_backend be_ksmg_smtp
backend be_ksmg_smtp
server ksmg 192.168.160.57:25 check
# -----------------------------------------------------------------------------
# Статистика HAProxy — только LAN/admin (allowlist stats-allowed)
# Пароль stats auth задаётся на сервере (/etc/haproxy/haproxy.cfg), не в GitHub.
# -----------------------------------------------------------------------------
frontend fe_stats
bind 192.168.160.117:8404
mode http
option httplog
acl src_stats_allowed src -f /etc/haproxy/stats-allowed
http-request deny deny_status 403 if !src_stats_allowed
stats enable
stats uri /stats
stats refresh 10s
stats auth admin:CHANGEME
# stats hide-version