How to protect server from simple DoS attack
You can use a firewall to limit the number of concurrent connections and the rate of new connections coming from a network (e.g. a /32 for IPv4 and a /64 for IPv6). Example of what it may look like using iptables
:
# Limit number of concurrent connections
-A INPUT -i eth0 -p tcp --syn -m connlimit --connlimit-above 50 -j DROP
# Limit rate of new connections
-A INPUT -i eth0 -p tcp --syn -m hashlimit --hashlimit-name tcp --hashlimit-mode srcip --hashlimit-above 3/sec --hashlimit-burst 7 --hashlimit-srcmask 32 -j DROP
(Same thing for ip6tables
except adding --connlimit-mask 64
to the first and changing --hashlimit-srcmask
to 64
in the second.)
You can also limit the rate of HTTP requests, for example with the limit_req module of nginx.
Source: serverfault.com
Aside from some basic firewalling, we rely on haproxy to do the heavy TCP lifting. We have found that it runs circles around an out of the box Apache HTTPd instance as far as any kind of slowdos attack goes.
-A INPUT -p tcp -m tcp -m state –state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp –tcp-flags FIN,SYN,RST,ACK SYN -j SYNFLOOD
-A INPUT -p tcp -m tcp –dport 80 -m state –state NEW -j HTTPDGUARD
-A INPUT -p tcp -m tcp –dport 443 -m state –state NEW -j HTTPDGUARD
-A HTTPDGUARD -m connlimit –connlimit-above 25 –connlimit-mask 32 -j HTTPDENY
-A HTTPDENY -j LOG –log-prefix “HTTP Flood: ”
-A HTTPDENY -p tcp -m tcp -j REJECT –reject-with tcp-reset
-A SYNFLOOD -m state –state NEW -m recent –set –name SYNRATE –rsource
-A SYNFLOOD ! -s 150.156.24.0/24 -m state –state NEW -m recent –update \
–seconds 5 –hitcount 200 –name SYNRATE –rsource -j DROP
-A INPUT -p tcp -m tcp –dport 80 -m state –state NEW -j ACCEPT
-A INPUT -p tcp -m tcp –dport 443 -m state –state NEW -j ACCEPT
Just to make it absolutely clear, please make sure to use the DROP target and not REJECT for this. DROP will drop the packets and a sane TCP/IP implementation on a legitimate host will retry after some short delay, whereas REJECT will cause a connection reset on the remote end and cause a large “the web server refused the connection” to be displayed to the user (almost certainly not what you want).