Timeout http-request for https


#1

I have been trying to add the following configuration as suggested by many to prevent slowloris type ddos attacks:

timeout http-request 5s.

But it only seems to work when I use http instead of https:

For example:
frontend
bind *: 80
works

but,
frontend
bind *:443 ssl crt certificate_path does not.

Any insights would be appreciated , Thanks


#2

This should work fine with https as well.

Can you post a more complete configuration and the output of haproxy -vv?

Also, how are you testing this?


#3

frontend application_ssl
bind *:443 ssl crt /etc/ssl/private/shrey.staging.myservices.com.pem

Abuse protection

    timeout http-request 5s

I am using http-slowloris-check(nmap) script to detect the vulnerabilites
in terms of slowloris attacks. When I use the above configuration, slowloris attacks succeed. The timeout works fine when I remove the highlighted part i.e not use ssl crt part(In bold).
I was also trying to test this using telnet and specified the 443 port, the results were similar.

I have also put some other DDOS protections , pasting the configuration for the same:

   #Reject new TCP connection if the number of TCP connections exceeds 10
    tcp-request connection reject if { src_conn_cur(abusers) ge 10 }

    #Reject connection from a user if numbers of connections in 3s exceeds 20
    tcp-request connection reject if { src_conn_rate(abusers) ge 20 }

    #Track table abuser     
    tcp-request connection track-sc1 src table abusers

These seem to work fine.

Also, I wanted to know how to use the parameter maxconnrate to limit the total incoming connection rate to the load balancer.

Pasting the haproxy --vv output

HA-Proxy version 1.5.15 2015/11/01
Copyright 2000-2015 Willy Tarreau willy@haproxy.org

Build options :
TARGET = linux2628
CPU = generic
CC = gcc
CFLAGS = -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2
OPTIONS = USE_ZLIB=1 USE_OPENSSL=1 USE_PCRE=1

Default settings :
maxconn = 2000, bufsize = 16384, maxrewrite = 8192, maxpollevents = 200

Encrypted password support via crypt(3): yes
Built with zlib version : 1.2.8
Compression algorithms supported : identity, deflate, gzip
Built with OpenSSL version : OpenSSL 1.0.1f 6 Jan 2014
Running on OpenSSL version : OpenSSL 1.0.1f 6 Jan 2014
OpenSSL library supports TLS extensions : yes
OpenSSL library supports SNI : yes
OpenSSL library supports prefer-server-ciphers : yes
Built with PCRE version : 8.31 2012-07-06
PCRE library supports JIT : no (USE_PCRE_JIT not set)
Built with transparent proxy support using: IP_TRANSPARENT IPV6_TRANSPARENT IP_FREEBIND

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.
Thanks in anticipation


#4

Attaching the complete configuration for reference, the configuration timeout http-request does not work here. It works when I replace the line:
bind *:443 ssl crt /etc/ssl/private/shrey.staging.myservices.com.pem with bind *:443.

I am testing using nmap --script http-slowloris-check and by using telnet. telnet 127.0.0.1 443 does not timeout after 5 seconds on https, but it does in the second case i.e bind *:443

global
log 127.0.0.1 local0
#log loghost local0 info
maxconn 4096
#debug
#quiet
user haproxy
group haproxy
tune.ssl.default-dh-param 2048

nbproc 32

defaults
log global
mode http
option httplog
option dontlognull
stats enable
option forwardfor
option httpclose
retries 3
option redispatch
maxconn 2000
timeout connect 5000
timeout client 50000
timeout server 50000
timeout http-request 5s

frontend application_server
bind *:443 ssl crt /etc/ssl/private/shrey.staging.myservices.com.pem
# Abuse protection
timeout http-request 5s
tcp-request connection reject if { src_conn_cur(abusers) ge 10 }
tcp-request connection reject if { src_conn_rate(abusers) ge 20 }
tcp-request connection track-sc1 src table abusers
default_backend backend_app1_ssl

backend backend_app1_ssl
balance roundrobin
server mon3 xx.xx.xx.xx:443 ssl verify none
server mon4 xx.xx.xx.xx:443 ssl verify none

backend abusers
# Sticky Table.
stick-table type ip size 200k expire 30s store conn_rate(3s),conn_cur


#5

You are testing incorrectly. telnet is not TLS capable and the http-slowloris-check script in nmap probably isn’t neiter.

Try:
openssl s_client -connect 127.0.0.1:443

This should timeout after 5 seconds. timeout http-request is about the timeout of a HTTP request, not the timeout of the TLS handshake.


#6

Thanks a lot , the timeout works fine.
Another query is what configuration should I use to limit the total connection rate on haproxy instead of per ip? I tried using maxconnrate but that did not seem to work correctly.

Thanks again


#7

To limit the maximum amount of open connections (and therefor, memory usage), configure maxconn.

Notice that you have per process [1], per section [2], per bind [3] and per server [4] maxconn limits.

[1] https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#3.2-maxconn
[2] https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#4.2-maxconn
[3] https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#5.1-maxconn
[4] https://cbonte.github.io/haproxy-dconv/1.7/configuration.html#5.2-maxconn