All pastes #736880 Raw Edit

Anonymous

public text v1 · immutable
·published 2007-10-14 22:12 UTC
rendered paste body
### Safety net
iptables -A INPUT -s 74.120.219.79 -j ACCEPT
iptables -A OUTPUT -s 74.120.219.79 -j ACCEPT
iptables -A FORWARD -s 74.120.219.79 -j ACCEPT

###
# Lists of IP addresses:
#	ips		used whenever a flood is detected. if an IP in this list sends too many packets...
#	banned	used to block packets from listed IPs for a period of time.  after that...
#	unbanned	used to keep recently unbanned IPs from getting back in if the flood is still going
###

###
# Chains:
#	flood-detected	triggered if the token bucket empties
#	ban-flooder		if an IP in the ips list sends too many packets
#	check-unban		triggered when we get a packet from someone in the banned list
###

###
# init
###
iptables -N flood-detected
iptables -N ban-flooder
iptables -P ban-flooder DROP
iptables -N check-unban

###
# CHAIN INPUT:  main flood-protect rules
###

# See if our IP is banned (should be the first rule in the INPUT chain after the ACCEPTs for admin IPs)
iptables -A INPUT -m recent --name banned --check -j check-unban

# Check for single-host floods (on all ports, why not?).  Dumps a file in /proc/net/ipt_hashlimit/lolichan.
#	Reaps unused buckets once per second (-gcinterval).  This means on average an unused bucket will
#		go 500ms before being reaped.
#	Assume: 500 max httpd processes, 1 per bucket (-size).
#	Assume: 2.5 seconds maximum to complete an http transaction.
#	Calculate: max # buckets = 500 * 2.5 = 1250 (-max).  If the site starts slowing down, this will limit
#		the number of new connections allowed, since they won't be able to find buckets.
#	Calculate: expire time = 2500ms (page wait) - 500ms (delay before reaping) = 2000ms (-expire).  If
#		someone hasn't connected in 2 seconds, expire their bucket and give another IP a chance.
iptables -A INPUT -p tcp -m hashlimit --hashlimit-name lolichan --hashlimit-mode srcip --hashlimit-htable-size 500 --hashlimit-htable-max 1250 --hashlimit-htable-expire 2000 --hashlimit-htable-gcinterval 1000 ! --hashlimit 20/sec -j ban-flooder

# Install the token bucket on port 80 and detect DDOS floods
iptables -A INPUT -p tcp --dport 80 -m limit --limit-burst 500 ! --limit 200/second -j flood-detected

# We're under the limit, clear the unban list on this guy.  NO JUMP TARGET: this will never match
iptables -A INPUT -m recent --name unbanned --check ! --remove

###
# CHAIN check-unban:  see if this IP hasn't contacted us in awhile
###

# If it hasn't been an hour, DROP.  Note that there are only 2 rules to run for banned IPs!
iptables -A check-unban -m recent --name banned --check ! --seconds 3600 -j DROP

# OK, let him out of the shitcan and RETURN to the INPUT chain (where he still might get a DROP)
iptables -A check-unban -m recent --name unbanned --set --name banned --remove -j RETURN

###
# CHAIN ban-flooder:  b& this IP.
###

# Move this loser from ips to banned.  NO JUMP TARGET, use the chain policy (DROP)
iptables -A ban-flooder -m recent --name banned --set --name ips --remove

###
# CHAIN flood-detected:  this chain activated only when a flood is encountered. IPs are tracked and b&.
###

# If this IP was just recently unbanned, DROP.  This prevents just-unbanned IPs from getting
#	back in while a flood is still going on.
iptables -A flood-detected -m recent --name unbanned --check -j DROP

# If we've seen this same IP X times in the last Y seconds, ban him
iptables -A flood-detected -m recent --name ips --check --hitcount X --seconds Y -j ban-flooder

# OK we haven't, update the guy in our list and RETURN
iptables -A flood-detected -m recent --name ips --update -j RETURN

# If we get here, this is the first packet we've seen from him.  Create an entry in the list
iptables -A flood-detected -m recent --name ips --set -j RETURN


########## Rest of iptables script goes beneath here ##########