#--------------------------------------------------------------------- # HAProxy: единая точка входа для портала администрирования # Устанавливается штатно из пакета дистрибутива, этот файл заменяет # /etc/haproxy/haproxy.cfg (см. README.md, шаг 6). #--------------------------------------------------------------------- global log /dev/log local0 info maxconn 20000 user haproxy group haproxy tune.ssl.default-dh-param 2048 ssl-default-bind-options no-sslv3 no-tlsv10 no-tlsv11 ssl-default-bind-ciphers ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM defaults log global mode http option httplog option dontlognull option forwardfor timeout connect 5s timeout client 30s timeout server 30s timeout http-request 10s errorfile 400 /etc/haproxy/errors/400.http errorfile 403 /etc/haproxy/errors/403.http errorfile 500 /etc/haproxy/errors/500.http errorfile 502 /etc/haproxy/errors/502.http errorfile 503 /etc/haproxy/errors/503.http errorfile 504 /etc/haproxy/errors/504.http #--------------------------------------------------------------------- # Статистика (в проде — ограничить отдельным ACL по внутренней сети) #--------------------------------------------------------------------- listen stats bind 127.0.0.1:8404 stats enable stats uri /haproxy?stats stats refresh 15s #--------------------------------------------------------------------- # HTTP -> HTTPS редирект #--------------------------------------------------------------------- frontend fe_http bind *:80 http-request redirect scheme https unless { ssl_fc } #--------------------------------------------------------------------- # Основной вход #--------------------------------------------------------------------- frontend fe_https bind *:443 ssl crt /etc/haproxy/certs/fqdn.pem alpn h2,http/1.1 http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains" # Простейшая защита от брутфорса логина stick-table type ip size 100k expire 10m store http_req_rate(1m) http-request track-sc0 src http-request deny deny_status 429 if { path_beg /login/ } { sc_http_req_rate(0) gt 20 } # Путь вида ///... считаем "ресурсным" acl is_resource_path path_reg ^/[a-zA-Z0-9_-]+/[a-zA-Z0-9_-]+(/.*)?$ # Служебные префиксы портала — всегда на Django, даже если совпали с regex выше acl is_portal_path path_beg /login/ /logout/ /static/ /django-admin/ /healthz # Признак для роутинга на реальный backend — короткоживущий resource_token, # который Django выпускает ПОСЛЕ проверки прав на конкретный ресурс # (см. docs/architecture.md, раздел 5). Сессия портала (sessionid) в # backend'ы никогда не передаётся. acl has_resource_token cook(resource_token) -m found use_backend be_django if !is_resource_path use_backend be_django if is_portal_path use_backend be_django if is_resource_path !has_resource_token !is_portal_path use_backend %[path,map_beg(/etc/haproxy/group_map.cfg,be_django)] \ if is_resource_path has_resource_token !is_portal_path #--------------------------------------------------------------------- # Backend: Django frontend (портал), работает через Gunicorn на localhost #--------------------------------------------------------------------- backend be_django balance roundrobin option httpchk GET /healthz http-check expect status 200 http-request set-header X-Forwarded-Proto https server django1 127.0.0.1:8000 check # server django2 10.0.0.11:8000 check # вторая ВМ с Django — для горизонтального масштабирования #--------------------------------------------------------------------- # Backends реальных admin panel — по одной секции на систему. # Ниже — 2 демонстрационных backend'а (см. backend_demo/, работают на # localhost через Nginx на отдельных портах). По этому шаблону добавляются # последующие продуктовые системы (обычно они на других хостах в сети). #--------------------------------------------------------------------- backend be_admin_resource1 balance roundrobin option httpchk GET / http-request set-header X-Forwarded-Proto https http-request set-header X-Resource-Token %[cook(resource_token)] http-request del-header Cookie server resource1 127.0.0.1:8081 check backend be_admin_resource2 balance roundrobin option httpchk GET / http-request set-header X-Forwarded-Proto https http-request set-header X-Resource-Token %[cook(resource_token)] http-request del-header Cookie server resource2 127.0.0.1:8082 check