# SOLVED: How to configure basic DDOS protection when behind AWS ELB (X-Forwarded-For)?

**URL:** <https://discourse.haproxy.org/t/solved-how-to-configure-basic-ddos-protection-when-behind-aws-elb-x-forwarded-for/932>\
**Category:** Help!\
**Created:** [January 11, 2017, 12:45pm UTC](https://discourse.haproxy.org/t/solved-how-to-configure-basic-ddos-protection-when-behind-aws-elb-x-forwarded-for/932 "2017-01-11T12:45:48Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![bvoros](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.haproxy.org/bvoros/32/154_2.png) [@bvoros](https://discourse.haproxy.org/u/bvoros)\
**Post date:** [January 11, 2017, 12:45pm UTC](https://discourse.haproxy.org/t/solved-how-to-configure-basic-ddos-protection-when-behind-aws-elb-x-forwarded-for/932/1 "2017-01-11T12:45:48Z")

</div>

Hello All,

I would like to configure basic DDOS protection measures on a pair of HAProxy 1.5 servers that are behind an AWS ELB.  
The ELB is in tcp mode with proxy-protocol enabled.

I have read through the internet and came accross several examples but none of them seemed to have worked.

In my current config I can finally see entries in the relevant stick-table but having problems taking action based on them.  
I can see the counters go up in the table when generating loads using “ab”, but there are no denied sessions when looking at the HAProxy status page.

What am I doing wrong?

Any help would be appreciated.

frontend bits:  
tcp-request connection reject if { src\_conn\_rate(Logger) ge 20 }  
tcp-request connection reject if { src\_conn\_cur(Logger) ge 10 }  
tcp-request connection reject if { src\_get\_gpc0(Logger) gt 0 }  
tcp-request connection expect-proxy layer4  
tcp-request content track-sc0 src table Logger

Application backend:  
acl abuse src\_http\_req\_rate(Logger) ge 10  
acl flag\_abuser src\_inc\_gpc0(Logger)  
tcp-request content reject if abuse flag\_abuser

Logger backend for the stick table:  
backend Logger  
stick-table type ip size 100k expire 3m store conn\_rate(3s),gpc0,conn\_cur,http\_req\_rate(10s),http\_err\_rate(10s)

Example entries in the table:  
0x85302c: key=1xx.2xx.2xx.2xx use=0 exp=169083 gpc0=91 conn\_rate(3000)=0 conn\_cur=0 http\_req\_rate(10000)=93 http\_err\_rate(10000)=9  
0x85302c: key=1xx.2xx.2xx.2xx use=2 exp=179997 gpc0=5483 conn\_rate(3000)=456 conn\_cur=2 http\_req\_rate(10000)=1543 http\_err\_rate(10000)=0

---

<div class="post-metadata">

**Author:** ![bvoros](https://sea2.discourse-cdn.com/flex016/user_avatar/discourse.haproxy.org/bvoros/32/154_2.png) [@bvoros](https://discourse.haproxy.org/u/bvoros)\
**Post date:** [January 11, 2017, 5:16pm UTC](https://discourse.haproxy.org/t/solved-how-to-configure-basic-ddos-protection-when-behind-aws-elb-x-forwarded-for/932/2 "2017-01-11T17:16:33Z")

</div>

Figured out in the end, here is my working config that behaved as expected when using ab and browsers by hand.  
The solution is to use tcp-request content instead of tcp-request connection as the latter uses the actual ip, in thi scase the ip of the ELB instead of the forwarded one.

frontend http-listener  
mode http  
option forwardfor  
option httplog  
bind \*:80 accept-proxy

```
    # Abuse protection.

    # Sources that are not filtered.
    tcp-request content accept if { src -f /etc/haproxy/whitelist.lst }

    # Sources rejected immeditely.
    tcp-request content reject if { src -f /etc/haproxy/blacklist.lst }

    # Limiting the connection rate per client. No more than 10 connections over 3 seconds.
    tcp-request content reject if { src_conn_rate(Logger) ge 10 }

    # Reject if more than 50 connections from client.
    # This is to accommodate clients behind a NAT.
    tcp-request content reject if { src_conn_cur(Logger) ge 50 }

    # Block based on backend.
    tcp-request content reject if { src_get_gpc0(Logger) gt 0 }

    # Track counters based on forwarded ip.
    tcp-request content track-sc1 src table Logger

```

backend Logger  
# Table.  
stick-table type ip size 100k expire 3m store conn\_rate(3s),gpc0,conn\_cur,http\_req\_rate(10s),http\_err\_rate(10s)

backend App  
balance roundrobin  
cookie SERVERID insert indirect nocache  
mode http  
option httplog  
acl abuse src\_http\_req\_rate(Logger) ge 100  
acl flag\_abuser src\_inc\_gpc0(Logger) ge 0  
tcp-request content reject if abuse flag\_abuser
