# 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