When haproxy logs the error, “SSL handshake failure”, I would like to add that client ip address to a stick-table. I wanted to know if it is possible to define an ACL that triggers the addition of the client ip to the stick-table even because TLS negotiation fails.
Our test server forces TLSv1.3 using “ssl-default-bind-options force-tlsv13” . The result is TLSv1.2 and earlier clients fail to connect logging “SSL handshake failure”, as is expected. Since the TLSv1.2 and earlier clients never negotiate the TLS connection, the standard ACL methods to look for TLS details like client ciphers do not work as far as I understand.
For example, the following “SSL handshake failure” log line was triggered by a TLSv1.2 cURL client connecting to a TLSv1.3 only server. The cURL client is immediately dropped and the server side TCP connection goes to a TIME_WAIT state for 60 seconds (Linux).
May 10 10:00:00 local0.info haproxy: 126.96.36.199 :12345 [10/May/2022:10:00:00.000] fe_https/1: SSL handshake failure
The problem we are seeing is the client(s) can connect repeatedly putting each TCP connection into a TIME_WAIT state. If the ip address was in a stick-table we could rate limit or even silent-drop to avoid TIME_WAIT states.
haproxy.conf simplified test configuration
global daemon ssl-default-bind-ciphersuites TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256 ssl-default-bind-options force-tlsv13 prefer-client-ciphers no-tls-tickets backend gatekeeper stick-table type ipv6 size 1m expire 75m store gpc0,conn_cnt,conn_rate(75m),conn_cur,http_req_cnt,http_req_rate(75m),http_err_rate(75m) frontend gateway mode tcp option tcplog bind :443 tcp-request inspect-delay 5s # # ACL - "SSL handshake failure" ?? acl handerror < TBD "SSL handshake failure" check > acl trigger src_inc_gpc0(gatekeeper) gt 0 tcp-request connection reject if handerror trigger # # ACL - https://example.com acl example_sni req.ssl_sni example.com use_backend rt_https if example_sni backend rt_https server fe_https unix@/var/lib/haproxy/haproxy_https.sock send-proxy-v2 frontend fe_https bind unix@/var/lib/haproxy/haproxy_https.sock ssl alpn h2,http/1.1 strict-sni crt /ssl/example.com.pem accept-proxy user haproxy mode 600 # # Track requests keyed by client ip once the https session is negotiated tcp-request session track-sc0 src table gatekeeper # # ACL acl uncivilized method !METH_GET http-request reject if uncivilized trigger http-request reject if banned backend bk_https mode http server .nginx. unix@/var/lib/haproxy/nginx.sock
Thank you for your time. Any tips or pointers to the configuration manual are welcome.
# haproxy -V HAProxy version 2.4.16-9d532c4 2022/04/29