ENABLED=true
API_KEY=<deleted>
MAP_PATH=/var/lib/crowdsec/lua/haproxy/community_blocklist.map
# bounce for all type of remediation that the bouncer can receive from the local API
BOUNCING_ON_TYPE=all
# when the bouncer receive an unknown remediation, fallback to this remediation
FALLBACK_REMEDIATION=ban
MODE=stream
REQUEST_TIMEOUT=1000
# exclude the bouncing on those location
EXCLUDE_LOCATION=
# Update frequency in stream mode, in second
UPDATE_FREQUENCY=10
#those apply for "ban" action
# /!\ REDIRECT_LOCATION and BAN_TEMPLATE_PATH/RET_CODE can't be used together. REDIRECT_LOCATION take priority over RET_CODE AND BAN_TEMPLATE_PATH
BAN_TEMPLATE_PATH=/var/lib/crowdsec/lua/haproxy/templates/ban.html
REDIRECT_LOCATION=
RET_CODE=
#those apply for "captcha" action
# reCAPTCHA Secret Key
SECRET_KEY=<deleted>
# reCAPTCHA Site key
SITE_KEY=<deleted>
CAPTCHA_TEMPLATE_PATH=/var/lib/crowdsec/lua/haproxy/templates/captcha.html
CAPTCHA_EXPIRATION=3600
/etc/haproxy/haproxy.cfg
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
stats timeout 2ms
user haproxy
group haproxy
daemon
# 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 # path to crowdsec bouncer configuration file
# Crowdsec bouncer <<<
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 60s
timeout client 600s
timeout server 600s
timeout http-keep-alive 3600s
timeout tunnel 10m
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
frontend sni-front
bind 192.168.101.80:443
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
default_backend sni-back
backend sni-back
mode tcp
acl mc-sni req_ssl_sni -i meshcentral.domain.net
acl gl-sni req_ssl_sni -i gitlab.domain.net
use-server mc-SNI if mc-sni
use-server gl-SNI if gl-sni
server mc-SNI 192.168.101.80:1443 send-proxy-v2-ssl-cn
server gl-SNI 192.168.101.80:1444 send-proxy-v2-ssl-cn
frontend mc-front-HTTPS
mode http
bind 192.168.101.80:1443 ssl crt /etc/haproxy/host.domain.net.pem accept-proxy
http-request set-header X-Forwarded-Proto https
http-response set-header Strict-Transport-Security "max-age=16000000; includeSubDomains; preload;"
option tcpka
# 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
# Crowdsec bouncer <<<
option forwardfor
http-request set-header X-Forwarded-Proto https
default_backend mc-back-HTTPS
frontend gl-front-HTTPS
mode http
bind 192.168.101.80:1444 ssl crt /etc/haproxy/host.domain.net.pem accept-proxy
http-request set-header X-Forwarded-Proto https
http-response set-header Strict-Transport-Security "max-age=16000000; includeSubDomains; preload;"
option tcpka
# 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
# Crowdsec bouncer <<<
option forwardfor
http-request set-header X-Forwarded-Proto https
default_backend gl-back-HTTPS
backend mc-back-HTTPS
mode http
http-request add-header X-Forwarded-Host %[req.hdr(Host)]
option http-server-close
server mc-01 192.168.101.20:443 ssl check port 443
backend gl-back-HTTPS
mode http
http-request set-header X-Forwarded-Host %[req.hdr(Host)]
option http-server-close
server gl-01 192.168.101.30:443 ssl check port 443
# Crowdsec bouncer >>>
# define a backend for google to allow DNS resolution if using reCAPTCHA
backend captcha_verifier
server captcha_verifier www.google.com:443 check
# define a backend for crowdsec to allow DNS resolution
backend crowdsec
server crowdsec 127.0.0.1:8080 check
# Crowdsec bouncer <<<
HAProxy version
haproxy -vv
HAProxy version 2.6.6-1ppa1~jammy 2022/09/22 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2027.
Known bugs: http://www.haproxy.org/bugs/bugs-2.6.6.html
Running on: Linux 5.15.0-53-generic #59-Ubuntu SMP Mon Oct 17 18:53:30 UTC 2022 x86_64
Build options :
TARGET = linux-glibc
CPU = generic
CC = cc
CFLAGS = -O2 -g -O2 -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 -Wall -Wextra -Wundef -Wdeclaration-after-statement -Wfatal-errors -Wtype-limits -Wshift-negative-value -Wshift-overflow=2 -Wduplicated-cond -Wnull-dereference -fwrapv -Wno-address-of-packed-member -Wno-unused-label -Wno-sign-compare -Wno-unused-parameter -Wno-clobbered -Wno-missing-field-initializers -Wno-cast-function-type -Wno-string-plus-int -Wno-atomic-alignment
OPTIONS = USE_PCRE2=1 USE_PCRE2_JIT=1 USE_OPENSSL=1 USE_LUA=1 USE_SLZ=1 USE_SYSTEMD=1 USE_OT=1 USE_PROMEX=1
DEBUG = -DDEBUG_STRICT -DDEBUG_MEMORY_POOLS
Feature list : +EPOLL -KQUEUE +NETFILTER -PCRE -PCRE_JIT +PCRE2 +PCRE2_JIT +POLL +THREAD +BACKTRACE -STATIC_PCRE -STATIC_PCRE2 +TPROXY +LINUX_TPROXY +LINUX_SPLICE +LIBCRYPT +CRYPT_H -ENGINE +GETADDRINFO +OPENSSL +LUA +ACCEPT4 -CLOSEFROM -ZLIB +SLZ +CPU_AFFINITY +TFO +NS +DL +RT -DEVICEATLAS -51DEGREES -WURFL +SYSTEMD -OBSOLETE_LINKER +PRCTL -PROCCTL +THREAD_DUMP -EVPORTS +OT -QUIC +PROMEX -MEMORY_PROFILING
Default settings :
bufsize = 16384, maxrewrite = 1024, maxpollevents = 200
Built with multi-threading support (MAX_THREADS=64, default=2).
Built with OpenSSL version : OpenSSL 3.0.2 15 Mar 2022
Running on OpenSSL version : OpenSSL 3.0.2 15 Mar 2022
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3
OpenSSL providers loaded : default
Built with Lua version : Lua 5.3.6
Built with the Prometheus exporter as a service
Built with network namespace support.
Built with OpenTracing support.
Support for malloc_trim() is enabled.
Built with libslz for stateless compression.
Compression algorithms supported : identity("identity"), deflate("deflate"), raw-deflate("deflate"), gzip("gzip")
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND
Built with PCRE2 version : 10.39 2021-10-29
PCRE2 library supports JIT : yes
Encrypted password support via crypt(3): yes
Built with gcc compiler version 11.2.0
Available polling systems :
epoll : pref=300, test result OK
poll : pref=200, test result OK
select : pref=150, test result OK
Total: 3 (3 usable), will use epoll.
Available multiplexer protocols :
(protocols marked as <default> cannot be specified using 'proto' keyword)
h2 : mode=HTTP side=FE|BE mux=H2 flags=HTX|HOL_RISK|NO_UPG
fcgi : mode=HTTP side=BE mux=FCGI flags=HTX|HOL_RISK|NO_UPG
h1 : mode=HTTP side=FE|BE mux=H1 flags=HTX|NO_UPG
<default> : mode=HTTP side=FE|BE mux=H1 flags=HTX
none : mode=TCP side=FE|BE mux=PASS flags=NO_UPG
<default> : mode=TCP side=FE|BE mux=PASS flags=
Available services : prometheus-exporter
Available filters :
[CACHE] cache
[COMP] compression
[FCGI] fcgi-app
[ OT] opentracing
[SPOE] spoe
[TRACE] trace
Saw the announcement https://www.crowdsec.net/blog/the-haproxy-bouncer-is-out and the docs page https://doc.crowdsec.net/docs/next/bouncers/haproxy/
Installed via crowdsec repo on Ubuntu 22.04.1 LTS (GNU/Linux 5.15.0-53-generic x86_64)
A few small changes were required to the provided files for paths etc. which have been mildly obsfuscated below.
The haproxy log (journalctl -u haproxy) log shows that "many" decisions are added.
for testing, decisions were added manually
sudo cscli decisions add -i
sudo cscli decisions add -i -t captcha
either "decisions" show from "sudo cscli decisions list", but there is no impact to traffic.
I presume that I'm missing something quite basic, but have hit "can't see the wood for the trees"...
/etc/crowdsec/bouncers/crowdsec-haproxy-bouncer.conf
/etc/haproxy/haproxy.cfg
HAProxy version