I have attempted to configure the HAProxy Bouncer to work with my configuration but it is not working as expected. I believe the issue is related to the fact that I have a loop in my HAProxy for managing internal vs external connections.
The reason I believe it is causing an issue is because the requests are all coming from localhost.
This is a sanitized copy of my configuration:
global
log /dev/log local0
log /dev/log local1 notice
chroot /var/lib/haproxy
stats socket /run/haproxy/admin.sock mode 660 level admin expose-fd listeners
user haproxy
group haproxy
daemon
maxconn 40000
ulimit-n 81000
crt-base /etc/haproxy/certificates/
# Crowdsec bouncer
lua-prepend-path /usr/lib/crowdsec/lua/haproxy/?.lua
lua-load /usr/lib/crowdsec/lua/haproxy/crowdsec.lua
setenv CROWDSEC_CONFIG /etc/crowdsec/bouncers/crowdsec-haproxy-bouncer.conf
defaults
mode http
option httplog
option dontlognull
option forwardfor
log global
timeout client 30s
timeout server 30s
timeout connect 5s
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.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
listen stats
bind *:8404
stats enable
stats hide-version
stats realm Haproxy\ Statistics
stats uri /haproxy_stats
stats auth HAProxy:HAProxy
# Frontend to redirect HTTP to HTTP with code 301
frontend fe_http
bind *:80
http-request redirect scheme https code 301
# Frontend for redirecting traffic to the required frontend
frontend fe_redirect
bind *:443
mode tcp
option tcplog
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
acl int_net src 192.168.88.0/24
use_backend be_int if int_net
default_backend be_ext
# Frontend for external users connecting through Cloudflare
frontend fe_ext
bind *:7000 ssl crt domain.com.pem
acl bookstack ssl_fc_sni bookstack.domain.com
acl phpmyadmin ssl_fc_sni phpmyadmin.domain.com
acl guac ssl_fc_sni guac.domain.com
acl recipes ssl_fc_sni recipes.domain.com
acl keycloak ssl_fc_sni accounts.domain.com
acl pgadmin ssl_fc_sni pgadmin.domain.com
acl paperless ssl_fc_sni paperless.domain.com
acl jellyfin ssl_fc_sni media.domain.com
acl wiki ssl_fc_sni wiki.domain.com
use_backend be_bookstack if bookstack
use_backend be_phpmyadmin if phpmyadmin
use_backend be_guac if guac
use_backend be_recipes if recipes
use_backend be_keycloak if keycloak
use_backend be_pgadmin if pgadmin
use_backend be_paperless if paperless
use_backend be_jellyfin if jellyfin
use_backend be_wiki if wiki
# Crowdsec bouncer
stick-table type ip size 10k expire 30m # declare a stick table to cache captcha verifications
http-request lua.crowdsec_allow # action to identify crowdsec remediation
http-request track-sc0 src if { var(req.remediation) -m str "captcha-allow" } # cache captcha allow decision
http-request redirect location %[var(req.redirect_uri)] if { var(req.remediation) -m str "captcha-allow" } # redirect to initial url
http-request use-service lua.reply_captcha if { var(req.remediation) -m str "captcha" } # serve captcha template if remediation is captcha
http-request use-service lua.reply_ban if { var(req.remediation) -m str "ban" } # serve ban template if remediation is ban
# This redirects to a failure page
default_backend be_no-match
# Frontend for internal users connecting directly to HAProxy
frontend fe_int
bind *:7001 ssl crt int.domain.com.pem
acl jellyfin ssl_fc_sni media.domain.com
use_backend be_jellyfin if jellyfin
# This redirects to a failure page
default_backend be_no-match
# Redirect to frontend based on internal or external connections
backend be_ext
mode tcp
server localhost 127.0.0.1:7000 check
backend be_int
mode tcp
server localhost 127.0.0.1:7001 check
# Normal Backends
backend be_no-match
http-request deny deny_status 403
backend be_recipes
server recipes recipes.lxd:8002 check
backend be_keycloak
server keycloak identity.lxd:8080 check
backend be_guac
server guac guacamole.lxd:8080 check
backend be_phpmyadmin
# Set root path for redirect
acl path_root path /
# Redirect to phpmyadmin subdirectory
redirect location https://phpmyadmin.domain.com/phpmyadmin if path_root
server mariadb phpmyadmin.lxd:80 check
backend be_bookstack
server bookstack bookstack.lxd:80 check
backend be_pgadmin
# Set root path for redirect
acl path_root path /
# Redirect to pgadmin4 subdirectory
redirect location https://pgadmin.domain.com/pgadmin4 if path_root
server pgadmin pgadmin.lxd:80 check
backend be_paperless
server paperless paperless.lxd:8000 check
backend be_jellyfin
server jellyfin jellyfin.lxd:8096 check
backend be_wiki
server wiki wiki.lxd:3000 check
# Backend for google to allow DNS resolution if using reCAPTCHA
backend captcha_verifier
server captcha_verifier www.google.com:443 check
# Backend for crowdsec to allow DNS resolution
backend crowdsec
server crowdsec localhost:8080 check
I have tried to figure out how CrowdSec detects the IP but am having no luck.
Here is a write-up about my configuration.