Initial infrastructure configuration

This commit is contained in:
root
2026-09-28 19:14:40 +03:00
commit 78c5ad051b
4 changed files with 881 additions and 0 deletions
+369
View File
@@ -0,0 +1,369 @@
global
log stdout format raw local0
maxconn 100000
tune.http.logurilen 4096
tune.ssl.default-dh-param 2048
ssl-default-bind-options no-tlsv10 no-tlsv11
ssl-default-server-options no-tlsv10 no-tlsv11
# --- CROWDSEC SPOA START ---
tune.bufsize 65536
lua-prepend-path /usr/lib/crowdsec-haproxy-spoa-bouncer/lua/?.lua
tune.lua.bool-sample-conversion normal
lua-load /usr/lib/crowdsec-haproxy-spoa-bouncer/lua/crowdsec.lua
setenv CROWDSEC_BAN_TEMPLATE_PATH /var/lib/crowdsec-haproxy-spoa-bouncer/html/ban.html
setenv CROWDSEC_CAPTCHA_TEMPLATE_PATH /var/lib/crowdsec-haproxy-spoa-bouncer/html/captcha.html
# --- CROWDSEC SPOA END ---
defaults
log global
mode http
option httplog
timeout client 300s
timeout server 300s
timeout connect 5s
default-server init-addr libc,none resolvers docker resolve-prefer ipv4
# --- CROWDSEC SPOA START ---
option http-buffer-request
# --- CROWDSEC SPOA END ---
resolvers docker
parse-resolv-conf
resolve_retries 3
timeout resolve 1s
timeout retry 1s
hold valid 10s
# -------- HTTP -> HTTPS --------
frontend fe_http
bind :80
mode http
# --- CROWDSEC SPOA START ---
filter spoe engine crowdsec config /usr/local/etc/haproxy/crowdsec.cfg
acl body_within_limit req.body_size -m int le 51200
http-request send-spoe-group crowdsec crowdsec-http-body if body_within_limit || !{ req.body_size -m found }
http-request send-spoe-group crowdsec crowdsec-http-no-body if !body_within_limit { req.body_size -m found }
# --- CROWDSEC SPOA END ---
http-request redirect scheme https code 301 unless { ssl_fc }
# -------- HTTPS (SNI) ----------
frontend fe_https
bind :443 ssl crt /etc/haproxy/certs alpn h2,http/1.1
mode http
option forwardfor header X-Forwarded-For if-none
# Сохраняем request-phase поля в txn.*, потому что log-format выполняется на response-phase
http-request set-var(txn.host) req.hdr(Host),lower
http-request set-var(txn.path) path
http-request set-var(txn.method) method
log-format "%{+json}o %(client_ip)ci %(client_port)cp %(frontend_name)ft %(backend_name)b %(server_name)s %(host)[var(txn.host)] %(method)[var(txn.method)] %(path)[var(txn.path)] %(status_code)ST %(bytes_read)B %(time_to_receive)TR %(time_waiting)Tw %(time_to_connect)Tc %(time_server_response)Tr %(time_active)Ta %(termination_state)tsc %(request_line)r %(sni)[ssl_fc_sni]"
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-For %[src]
http-request set-header X-Forwarded-Port 443
http-request set-header X-Forwarded-Host %[req.hdr(host)]
http-request set-header Host %[req.hdr(host)]
http-response set-header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
http-response set-header X-Content-Type-Options "nosniff"
http-response set-header X-Frame-Options "SAMEORIGIN"
http-response set-header Referrer-Policy "strict-origin-when-cross-origin"
# --- CROWDSEC SPOA START ---
filter spoe engine crowdsec config /usr/local/etc/haproxy/crowdsec.cfg
acl body_within_limit req.body_size -m int le 51200
http-request send-spoe-group crowdsec crowdsec-http-body if body_within_limit || !{ req.body_size -m found }
http-request send-spoe-group crowdsec crowdsec-http-no-body if !body_within_limit { req.body_size -m found }
http-request set-header X-Crowdsec-Remediation %[var(txn.crowdsec.remediation)]
http-request redirect code 302 location %[url] if { var(txn.crowdsec.remediation) -m str "allow" } { var(txn.crowdsec.redirect) -m found }
http-request lua.crowdsec_handle if { var(txn.crowdsec.remediation) -m str "captcha" }
http-request lua.crowdsec_handle if { var(txn.crowdsec.remediation) -m str "ban" }
http-after-response set-header Set-Cookie %[var(txn.crowdsec.captcha_cookie)] if { var(txn.crowdsec.captcha_status) -m found } { var(txn.crowdsec.captcha_cookie) -m found }
http-after-response set-header Set-Cookie %[var(txn.crowdsec.captcha_cookie)] if { var(txn.crowdsec.captcha_cookie) -m found } !{ var(txn.crowdsec.captcha_status) -m found }
# --- CROWDSEC SPOA END ---
# Keycloak passthrough
acl host_sso hdr(host) -i sso.zk-tech.info
# OnlyOffice engine
acl host_of hdr(host) -i of.zk-tech.info
# Jellyfin
acl host_jellyfin hdr(host) -i jf.zk-tech.info
# NextCloud
acl host_nc hdr(host) -i nc.zk-tech.info
# Immich
acl host_immich hdr(host) -i im.zk-tech.info
# Firefly III
acl host_firefly hdr(host) -i ff.zk-tech.info
# Obsidian + CouchDB
acl host_obsidian hdr(host) -i ob.zk-tech.info
# Speedtest
acl host_speedtest hdr(host) -i st.zk-tech.info
# WUD + docker-socket-proxy
acl host_wud hdr(host) -i wud.zk-tech.info
acl allowed_wud src 172.19.0.0/16
# Arr stack (media server)
acl host_sonarr hdr(host) -i sr.zk-tech.info
acl host_radarr hdr(host) -i rr.zk-tech.info
acl host_qb hdr(host) -i qb.zk-tech.info
acl host_prowl hdr(host) -i pr.zk-tech.info
# Torrserver
acl host_torrserv hdr(host) -i ts.zk-tech.info
# Matrix (synapse, elements
acl host_matrix hdr(host) -i mr.zk-tech.info
acl path_synapse path_beg -i /_matrix /_synapse/client
acl path_wellknown path_beg -i /.well-known/matrix
# MAS
acl host_mas hdr(host) -i ms.zk-tech.info
# Rackula SSO
acl host_rk hdr(host) -i rk.zk-tech.info
# Zabbix SSO
acl host_zb hdr(host) -i zb.zk-tech.info
# WikiJS
acl host_wiki hdr(host) -i wiki.zk-tech.info
# mailcow web + sogo + EAS
acl host_mailcow hdr(host) -i mail.zk-tech.info autodiscover.zk-tech.info autoconfig.zk-tech.info
# Enable admin from home network
acl mc_admin_path path_beg -i /admin
acl mc_admin_allowed src 172.19.0.0/16
http-request deny if host_mailcow mc_admin_path !mc_admin_allowed
# Grafana local
acl host_grafana hdr(host) -i gr.zk-tech.info
# Gitea
acl host_gitea hdr(host) -i git.zk-tech.info
# Deny access to WUD
http-request deny if host_wud !allowed_wud
# Immich backend
use_backend bk_immich if host_immich
# Keycloak backend
use_backend bk_keycloak if host_sso
use_backend bk_jellyfin if host_jellyfin
use_backend bk_nextcloud if host_nc
use_backend bk_onlyoffice if host_of
use_backend bk_firefly if host_firefly
use_backend bk_obsidian if host_obsidian
use_backend bk_speedtest if host_speedtest
use_backend bk_wud if host_wud
# Arr stack backends
use_backend be_sonarr if host_sonarr
use_backend be_radarr if host_radarr
use_backend be_qb if host_qb
use_backend be_prowl if host_prowl
# Torrserver backend
use_backend bk_torr if host_torrserv
# MAS redirection
# Matrix Auth (MAS compat) - ОБЯЗАТЕЛЬНО ПЕРЕД path_synapse
acl path_matrix_auth path_reg -i ^/_matrix/client/(v1|v3|r0)/(login|logout|refresh)(/.*)?$
# (опционально) если хочешь, чтобы запросы регистрации тоже обрабатывал MAS (иначе будут 403/404 от Synapse)
# acl path_matrix_register path_reg -i ^/_matrix/client/(v1|v3|r0)/register(/.*)?$
use_backend bk_matrix_mas if host_matrix path_matrix_auth
# use_backend bk_matrix_mas if host_matrix path_matrix_register
# Matrix (Synapse, Element)
use_backend bk_matrix_synapse if host_matrix path_synapse
use_backend bk_matrix_synapse if host_matrix path_wellknown
use_backend bk_matrix_element if host_matrix
#MAS
use_backend bk_matrix_mas if host_mas
# Rackula Backend
use_backend bk_rackula_sso if host_rk
# Zabbix Backend
use_backend bk_zabbix if host_zb
# Wiki backend
use_backend bk_wiki if host_wiki
# mailcow backend
use_backend bk_mailcow if host_mailcow
# Grafana Backend
use_backend be_grafana if host_grafana
# Gitea backend
use_backend bk_gitea if host_gitea
default_backend bk_404
# -------- HTTP backends --------
backend bk_keycloak
mode http
option httpchk GET /realms/zk-tech/.well-known/openid-configuration
http-request set-header X-Forwarded-Proto https
server keycloak keycloak:8080 check resolvers docker resolve-prefer ipv4 inter 5s fall 4 rise 2
# OnlyOffice
backend bk_onlyoffice
option httpchk
http-check send meth GET uri /healthcheck ver HTTP/1.1 hdr Host of.zk-tech.info
http-check expect status 200
http-check expect string true
http-response del-header X-Frame-Options
http-response set-header Content-Security-Policy "frame-ancestors 'self' https://nc.zk-tech.info"
timeout connect 5s
timeout server 1h
server oods onlyoffice-docs:80 check resolvers docker resolve-prefer ipv4 inter 5s fall 4 rise 2
# Jellyfin
backend bk_jellyfin
option httpchk GET /health
http-check expect string Healthy
http-request set-header X-Forwarded-Host %[req.hdr(host)]
http-request set-header X-Forwarded-Server %[req.hdr(host)]
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Port %[dst_port]
http-request set-header X-Real-IP %[src]
server jellyfin-server 172.19.0.16:8096 check inter 5s fall 4 rise 2
# --- Бэкенд Immich ---
backend bk_immich
mode http
balance roundrobin
option httpchk GET /.well-known/immich
http-check expect status 200
timeout check 5s
server immich01 172.19.0.16:2283 check resolvers docker resolve-prefer ipv4 inter 5s fall 4 rise 2
#Nextcloud
backend bk_nextcloud
balance uri
option httpchk GET /status.php
http-check expect status 200
timeout connect 5s
timeout server 600s
server nc1 nextcloud:80 check resolvers docker resolve-prefer ipv4 init-addr libc,none inter 5s fall 4 rise 2
# Firefly III
backend bk_firefly
mode http
# option httplog
option httpclose
option forwardfor except 127.0.0.1
# заголовки для корректной работы за прокси
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
http-request set-header X-Forwarded-Host %[req.hdr(Host)]
# при желании можно добавить health-check:
# option httpchk GET /login
server firefly_iii 172.19.0.15:8051 check
# Obsidian + CouchDB
backend bk_obsidian
mode http
# option httplog
option httpclose
option forwardfor except 127.0.0.1
# option httpchk GET /
# http-check expect status 200
server couchdb-obsidian couchdb-obsidian:5984 check
# Speedtest
backend bk_speedtest
mode http
# option httplog
option httpclose
option forwardfor except 127.0.0.1
# option httpchk GET /
# http-check expect status 200
server openspeedtest openspeedtest:3000 check
# WUD
backend bk_wud
mode http
option httpchk GET /
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Host %[req.hdr(Host)]
server wud wud:3000 check
# Arr stack Sonarr
backend be_sonarr
mode http
option httpclose
option forwardfor except 127.0.0.1
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
http-request set-header X-Forwarded-Host %[req.hdr(Host)]
option httpchk GET /
server sonarr 172.19.0.16:8989 check
# Arr stack Radarr
backend be_radarr
mode http
option httpclose
option forwardfor except 127.0.0.1
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
http-request set-header X-Forwarded-Host %[req.hdr(Host)]
option httpchk GET /
server radarr 172.19.0.16:7878 check
# Arr stack qbittorrent
backend be_qb
mode http
option httpclose
option forwardfor except 127.0.0.1
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
http-request set-header X-Forwarded-Host %[req.hdr(Host)]
#option httpchk GET /
server qbittorrent 172.19.0.16:8085 check
# Arr stack Prowlarr
backend be_prowl
mode http
option httpclose
option forwardfor except 127.0.0.1
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
http-request set-header X-Forwarded-Host %[req.hdr(Host)]
option httpchk GET /
server prowlarr 172.19.0.16:9696 check
# Torrserver for multimedia
backend bk_torr
mode http
option httpclose
option forwardfor except 127.0.0.1
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
http-request set-header X-Forwarded-Host %[req.hdr(Host)]
option httpchk GET /
server prowlarr 172.19.0.16:8090 check
# Matrix (synapse, Element, MAS)
backend bk_matrix_synapse
server synapse matrix-synapse:8008 check
backend bk_matrix_element
server element matrix-element-web:80 check
backend bk_matrix_mas
server mas matrix-mas:8080 check
backend bk_404
mode http
http-request deny deny_status 404
# Rackula with auth
backend bk_rackula_sso
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Host %[req.hdr(Host)]
http-request set-header X-Forwarded-Port 443
server oauth2proxy oauth2-proxy-rackula:4180 check
# Zabbix backend
backend bk_zabbix
mode http
option httpchk GET /index.php
http-check expect status 200
server zabbix-web zabbix-web-nginx-pgsql:8080 check
# WikiJS backend
backend bk_wiki
mode http
server wikijs wikijs:3000 check
# Crowdsec Backend
backend crowdsec-spoa
mode tcp
server spoa crowdsec-spoa-bouncer:9000 check
# mailcow web + sogo + EAS
backend bk_mailcow
option forwardfor
http-request set-header X-Forwarded-Proto https if { ssl_fc }
http-request set-header X-Forwarded-Proto http if !{ ssl_fc }
server mailcow 172.19.0.15:8085 check
# Grafana
backend be_grafana
mode http
option httpchk GET /api/health
http-check expect status 200
http-request set-header X-Forwarded-Proto https
http-request set-header X-Forwarded-Port 443
http-request set-header X-Forwarded-Host %[req.hdr(Host)]
server grafana grafana:3000 check resolvers docker resolve-prefer ipv4 init-addr libc,none
# Gitea
backend bk_gitea
mode http
option httpchk GET /api/healthz
http-check expect status 200
http-request set-header Host %[req.hdr(Host)]
http-request set-header X-Forwarded-Proto https
http-request set-header X-Forwarded-For %[src]
http-request set-header X-Real-IP %[src]
server gitea gitea:3000 check