Hi friends,
I have a setup with Haproxy as a reverse proxy on the host to a containerized Apache server and Nginx server. We have been getting some DDOS type of attacks and our site will start showing 429 too many requests error. But whenever we would restart Apache the site would be back up. But recently, we got hit so hard that the maxconn in Haproxy got breached. Thereafter, despite restarting Apache, Haproxy and Nginx and even rebooting the server we see that Haproxy fails for this site with Layer 6 Timeout error and shows the backend to be DOWN.
I believe Layer 6 indicates issue with SSL. We are using Proxy Protocol and SSL pass through mode. I tried creating another containerized Apache server as a backup, but it just wonât work
Haproxy is version 2.8.3. I did try downgrading Haproxy (i.e installed lower versions) but it still wonât work. We are using Letsencrypt certificates. So, I even renewed them to see if that fixes it, but no luck.
I have a couple more containerized Apaches running on the same host which work perfectly fine but they do not get attacked as much.
Wondering how I can go about fixing this issue. Any help will be greatly appreciated.
Thanks in advance.
Output of haproxy -vv:
HAProxy version 2.8.3-86e043a 2023/09/07 - https://haproxy.org/
Status: long-term supported branch - will stop receiving fixes around Q2 2028.
Known bugs: http://www.haproxy.org/bugs/bugs-2.8.3.html
Running on: FreeBSD 13.2-RELEASE-p3 FreeBSD 13.2-RELEASE-p3 GENERIC amd64
Build options :
TARGET = freebsd
CPU = generic
CC = cc
CFLAGS = -O2 -pipe -fstack-protector-strong -fno-strict-aliasing -Wall -Wextra -Wundef -Wdeclaration-after-statement -Wfatal-errors -Wtype-limits -Wshift-negative-value -Wnull-dereference -fwrapv -Wno-unknown-warning-option -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 -DFREEBSD_PORTS
OPTIONS = USE_GETADDRINFO=1 USE_OPENSSL=1 USE_ACCEPT4=1 USE_ZLIB=1 USE_CPU_AFFINITY=1 USE_PCRE2=1 USE_PCRE2_JIT=1
DEBUG = -DDEBUG_STRICT -DDEBUG_MEMORY_POOLS
Feature list : -51DEGREES +ACCEPT4 -BACKTRACE +CLOSEFROM +CPU_AFFINITY -CRYPT_H -DEVICEATLAS -DL -ENGINE -EPOLL -EVPORTS +GETADDRINFO +KQUEUE -LIBATOMIC +LIBCRYPT -LINUX_CAP -LINUX_SPLICE -LINUX_TPROXY -LUA -MATH -MEMORY_PROFILING -NETFILTER -NS -OBSOLETE_LINKER +OPENSSL -OPENSSL_WOLFSSL -OT -PCRE +PCRE2 +PCRE2_JIT -PCRE_JIT +POLL -PRCTL +PROCCTL -PROMEX -PTHREAD_EMULATION -QUIC -RT +SHM_OPEN -SLZ +SSL -STATIC_PCRE -STATIC_PCRE2 -SYSTEMD -TFO +THREAD -THREAD_DUMP +TPROXY -WURFL +ZLIB
Default settings :
bufsize = 16384, maxrewrite = 1024, maxpollevents = 200
Built with multi-threading support (MAX_TGROUPS=16, MAX_THREADS=256, default=8).
Built with OpenSSL version : OpenSSL 1.1.1w 11 Sep 2023
Running on OpenSSL version : OpenSSL 1.1.1w 11 Sep 2023
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports : SSLv3 TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3
Built with zlib version : 1.2.13
Running on zlib version : 1.2.13
Compression algorithms supported : identity(âidentityâ), deflate(âdeflateâ), raw-deflate(âdeflateâ), gzip(âgzipâ)
Built with transparent proxy support using: IP_BINDANY IPV6_BINDANY
Built with PCRE2 version : 10.42 2022-12-11
PCRE2 library supports JIT : yes
Encrypted password support via crypt(3): yes
Built with clang compiler version 14.0.5 (GitHub - llvm/llvm-project: The LLVM Project is a collection of modular and reusable compiler and toolchain technologies. llvmorg-14.0.5-0-gc12386ae247c)
Available polling systems :
kqueue : pref=300, test result OK
poll : pref=200, test result OK
select : pref=150, test result OK
Total: 3 (3 usable), will use kqueue.
Available multiplexer protocols :
(protocols marked as 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
: mode=HTTP side=FE|BE mux=H1 flags=HTX
none : mode=TCP side=FE|BE mux=PASS flags=NO_UPG
: mode=TCP side=FE|BE mux=PASS flags=
Available services : none
Available filters :
[BWLIM] bwlim-in
[BWLIM] bwlim-out
[CACHE] cache
[COMP] compression
[FCGI] fcgi-app
[SPOE] spoe
[TRACE] trace
Relevant Config:
global
daemon
maxconn 60000
log /dev/log local2 notice
stats socket /run/haproxy/admin.sock mode 600 level admin
defaults
mode tcp
option dontlognull
timeout http-request 10s
timeout queue 1m
timeout connect 5s
timeout client 10s
timeout server 30s
timeout http-keep-alive 10s
timeout check 10s
timeout tarpit 1m
backlog 10000
frontend http
bind *:80
mode http
redirect scheme https if !{ ssl_fc }
frontend https
bind *:443
mode tcp
tcp-request inspect-delay 5s
option http-server-close
maxconn 20000
tcp-request connection track-sc1 src
tcp-request connection reject if { src_get_gpc0 gt 0 }
stick-table type ip size 200k expire 30s store gpc0
acl source_is_abuser src_get_gpc0 gt 0
tcp-request connection track-sc0 src if !source_is_abuser
tcp-request content accept if { req_ssl_hello_type 1 }
use_backend bak_429 if source_is_abuser
acl cluster1 req.ssl_sni -i XXX.com
acl cluster1 req.ssl_sni -i www.XXX.com
acl cluster2 req.ssl_sni -i abc.XXX.com
use_backend cluster1_bak if cluster1
use_backend cluster2_bak if cluster2
default_backend cluster1_bak
backend cluster1_bak
mode tcp
option tcplog
option log-health-checks
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
balance roundrobin
option ssl-hello-chk
http-check connect ssl alpn h2,http/1.1
#server webserver 10.10.3.2:443 send-proxy check inter 2000 rise 2 fall 5
server apacheserver01 10.10.3.2:443 send-proxy check ssl verify none force-tlsv13
server apacheserver02 10.10.3.19:443 send-proxy check ssl verify none force-tlsv13 weight 2
backend cluster2_bak
mode tcp
tcp-request inspect-delay 5s
tcp-request content accept if { req_ssl_hello_type 1 }
option ssl-hello-chk
server nginxserver01 10.10.3.7:4443 send-proxy check verify none inter 2000 rise 2 fall 5
backend bak_429
mode http
timeout tarpit 2s
http-request tarpit deny_status 429