111 lines
5.2 KiB
INI
111 lines
5.2 KiB
INI
#---------------------------------------------------------------------
|
||
# 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 }
|
||
|
||
# Путь вида /<adminusergroup>/<resource>/... считаем "ресурсным"
|
||
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
|