A transparent firewall for Intrusion Prevention and dDOS-Mitigation
A customer was under heavy dDOS-Attack, specifically SYN-Flood.The service has become unavailable because his (stateful) firewall cannot handle more then 128k concurrent sessions and began dropping legitimate ones.
We configured his Juniper Firewall to protect the network from SYN-Flood by limiting the maximum amount of SYN-Packets per IP per second, the maximum number of open sessions per IP and by enabling SYN-proxying.
At first, the Juniper-Firewall handled the load easily, and service was restored. The amount of illegitimate SYN Packets hit a ceiling at about 40MBit/second. The number of sessions dropped down to a more manageable value, but the CPU Usage was rising because of the work involved in tracking the connections to mitigate the SYN Flood.
But the attack volume was increasing. At some point about 60MBit/second, the Juniper reached its limits again, this time the CPU usage peaked.
I wanted to put another system in front of the firewall to relieve the firewall of the cumbersome load. This is difficult without provoking downtime and cumbersome with a normal Layer 3-Firewall, because you need another routing hop and so you will be forced to renumber your network range. But after some recherche, i discovered that Linux iptables can filter at the bridge level, so this appliance doesn’t even need an IP address (only for management).
All you need to do to take this appliance productive is putting it physically in line with the uplink and the ordinary (routing) firewall.
Setting up the system
install debian
apt-get install iptables ebtables bridge-utils
/etc/network/interfaces:
auto lo eth0 eth1 # Loopback Interface iface lo inet loopback # eth0: Uplink connection (incoming) iface eth0 inet manual mtu 1500 # eth1: cleaned Traffic (outgoing) iface eth1 inet manual mtu 1500 post-up ifup br0 #br0: Ethernet bridge uplink <-> firewall iface br0 inet static bridge_ports eth0 eth1 bridge_stp off bridge_fd 0 bridge_maxwait 0 # iptables restore, bevor bridge hochgefahren wird pre-up iptables-restore < /etc/iptables.up.rules # IP for management address 192.168.142.2 gateway 192.168.142.1 #uplink netmask 255.255.255.0
You can add trunking/vlans any way you want, iptables filtering will work.
/etc/sysctl.conf:
net.netfilter.nf_conntrack_max=1048576 net.ipv4.tcp_syncookies=1
Load the sysctl.conf while booting:
update-rc.d procps defaults
/etc/iptables.up.rules:
*filter :INPUT ACCEPT [0:0] :FORWARD ACCEPT [0:0] :OUTPUT ACCEPT [0:0] :nominal-syn - [0:0] :syn-flood - [0:0] :non-syn - [0:0] -A FORWARD -p tcp --syn -m hashlimit --hashlimit-above 50/sec --hashlimit-burst 100 --hashlimit-htable-expire 300000 --hashlimit-mode srcip --hashlimit-name synstop -j syn-flood -A FORWARD -p tcp --syn -j nominal-syn -A FORWARD -j non-syn -A syn-flood -m recent --name blacklist --set -A syn-flood -m limit --limit 3/minute --limit-burst 20 -j LOG --log-level 4 --log-prefix "SYN Flood: " -A syn-flood -j DROP -A nominal-syn -j ACCEPT -A non-syn -j ACCEPT COMMIT
Getting Information about the filtering process
#watch -n 1 “iptables -v -L FORWARD ”
gets you some information, including the number of dropped and passed packets/bytes per defined chain (see above):
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 18M 935M syn-flood tcp -- any any anywhere anywhere tcp flags:FIN,SYN,RST,ACK/SYN limit: above 50/sec burst 100 mode srcip htable-expire 300000 1067K 56M nominal-syn tcp -- any any anywhere anywhere tcp flags:FIN,SYN,RST,ACK/SYN 20M 17G non-syn all -- any any anywhere anywhere
List of “Bad Guys”:
In the blacklist you can see all IPs that violated the syn-flood limit:
cat /proc/net/xt_recent/blacklist
More Information
http://wodny.org/special/hashlimit.html
http://www.linuxmantra.com/2010/11/iptables-hashlimit.html