HAproxy ACL . Block all connection to Haproxy By default and allow only Specific IP

8.5k views Asked by At

I am trying to solving a scenario now using haproxy. The scenario as below

  • Block all IP by default
  • Allow only connection from a specific IP address
  • If any connections come from a whilelist IP, if should reject if it exceed more than 10 concurrent connection in 30 sec

I want to do this to reduce number of API calls into my server. Could any one please help me with this?

Thanks

1

There are 1 answers

0
kwarunek On

First two things are easy, simply allow only whitelisted IP

acl whitelist src 10.12.12.23
use_backend SOMESERVER if whitelist

The third - throttling - requires to use stick-tables (there are many data type - counters conn, sess, http, rates...) as a rate counter:

#                    max entries              count request in 60s periods
stick-table type ip   size 200k   expire 100s store http_req_rate(60s) 

next you have to fill the table, by tracking each request eg. by IP

tcp-request content track-sc0 src 
# more info at http://cbonte.github.io/haproxy-dconv/1.5/configuration.html#4.2-tcp-request%20connection

and finally the acl:

# is there more than 5req/1min from IP
acl http_rate_abuse sc0_http_req_rate gt 5

# update use_backend condition
use_backend SOMESERVER if whitelisted !http_rate_abuse

For example some working config file with customized errors:

global
    log /dev/log    local1 debug

defaults
    log     global
    mode    http
    option  httplog
    retries 3
    option redispatch
    maxconn 2000
    contimeout      5000
    clitimeout      50000
    srvtimeout      50000

frontend http
    bind *:8181

    stick-table type ip   size 200k   expire 100s store http_req_rate(60s)
    tcp-request content track-sc0 src

    acl whitelist src 127.0.0.1
    acl http_rate_abuse sc0_http_req_rate gt 5 
    use_backend error401 if !whitelist
    use_backend error429 if http_rate_abuse
    use_backend realone

backend realone
    server local stackoverflow.com:80

# too many requests
backend error429
    mode http
    errorfile 503 /etc/haproxy/errors/429.http

# unauthenticated
backend error401
    mode http
    errorfile 503 /etc/haproxy/errors/401.http

Note: the error handling is a bit tricky. Because above error backends are missing server entries, haproxy will throw HTTP 503, errorfile catch them and send different errors (with different codes).

Example /etc/haproxy/errors/401.http content:

HTTP/1.0 401 Unauthenticated
Cache-Control: no-cache
Connection: close
Content-Type: text/html

<html><body><h1>401 Unauthenticated</h1>
</body></html>

Example /etc/haproxy/errors/429.http content:

HTTP/1.0 429 Too many requests
Cache-Control: no-cache
Connection: close
Content-Type: text/html

<html><body><h1>429 Too many requests</h1>
</body></html>