110 lines
5.2 KiB
INI
110 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
|