DDoS Linux Protection

Posted on January 11, 2017

When hitten by a DDoS attack generating 50.000 pps and your old firewall/webserver can’t handle it, it’s easy to create a linux firewall, that can easy handle 500.000 pps with minimal CPU usage.

The following examples are for Ubuntu 16.

If it’s a synflood, we can use Linux SYNPROXY to protect agains that, and haproxy the trafic to the protected servers, in this example it’s a simple TCP forward for port 80 and 443 to 192.168.1.2:

(HAProxy can also proxy http and https requests)

sudo apt install haproxy hatop haproxyctl vim-haproxy ipset -y
#ubuntu haproxy bug fix
sudo touch /var/loghaproxy.log
sudo chown syslog.adm /var/log/haproxy.log
#configure the TCP stack to SYNPROXY and many connections
sudo tee /etc/sysctl.conf \<\<EOF
net.ipv4.tcp_syncookies=1
net.ipv4.tcp_timestamps=1
net.ipv4.tcp_mem = 786432 1697152 1945728
net.ipv4.tcp_rmem = 4096 4096 16777216
net.ipv4.tcp_wmem = 4096 4096 16777216
net.ipv4.tcp_timestamps = 0
net.ipv4.ip_local_port_range = 1000 65535
fs.file-max = 10000000 
fs.nr_open = 10000000
EOF

sudo tee /etc/haproxy/haproxy.cfg \<\<EOF
global
    log /dev/log    local0
    log /dev/log    local1 notice
    chroot /var/lib/haproxy
    stats socket /run/haproxy/admin.sock mode 660 level admin
    stats timeout 30s
    user haproxy
    group haproxy
    daemon

defaults
    log      global
    mode     tcp
    option   tcplog
    option   dontlognull
    timeout  connect 5000
    timeout  client  50000
    timeout  server  50000
    maxconn  1000
    balance  roundrobin

frontend local80
    log     global
    bind    *:80
    default_backend backendserver80


frontend local443
    log    global
    bind   *:443
    default_backend backendserver443


backend backendserver80
        server server80 192.168.1.2:80

backend skolearena443
        server server443 192.168.1.2:443
EOF

If we need Geoblocking, allowing only Sweden, Norway and Denmark, this can be implemted in a bridge scenario … the protected host is 192.168.1.2:

#create bridge between eth0 and eth1
sudo brctl addbr br0
sudo brctl addif br0 eth0
sudo brctl addif br0 eth1

#enable geo blocking
ipset create geoblock hash:net
sudo iptables -A FORWARD -m set --set !geoblock src -d 192.168.1.2 -j DROP

#download geo list every night
countries="{se,no,dk}"
sudo ipset flush geoblock
#get se,no,dk ip networks
wget -q http://www.ipdeny.com/ipblocks/data/countries/${countries}.zone -O - | awk '{print "add geoblock " $1 }' | sudo ipset restore

And rate limits is not really a solution to this problem, but can be a help in some attacks.

An example of ratelimit trafic to port 80:

#create bridge between eth0 and eth1
sudo brctl addbr br0
sudo brctl addif br0 eth0
sudo brctl addif br0 eth1

iptable bridge ... limit rates for tcp syn port 80 and icmp request:
# Handling TCP port 80
iptables -A FORWARD -d $web-ip/32 -i br0 -p tcp -m physdev --physdev-is-bridged -m tcp --dport 80 -m state --state NEW -m limit --limit 60/sec --limit-burst 200 -j ACCEPT
iptables -A FORWARD -d $web-ip/32 -i br0 -p tcp -m physdev --physdev-is-bridged -m tcp --dport 80 -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -d $web-ip/32 -i br0 -p tcp -m physdev --physdev-is-bridged -m tcp --dport 80 -j DROP
# Handling ICMP
iptables -A FORWARD -d $web-ip/32 -i br0 -p icmp -m physdev --physdev-is-bridged -m icmp --icmp-type 8 -m limit --limit 60/sec -j ACCEPT
iptables -A FORWARD -d $web-ip/32 -i br0 -p icmp -m physdev --physdev-is-bridged -j DROP

The withstand even more traffic read https://javapipe.com/blog/iptables-ddos-protection/