Anti-SYN script blocking some packets from my own website
############################################################################
# SCRIPT SYN-FLOOD
############################################################################
#!/bin/sh
# A simple shell to build a Firewall anti SYN Flood
# Under CentOS, Fedora and RHEL / Redhat Enterprise Linux
# servers.
# ----------------------------------------------------------------------------
# Written by LongVNIT
# (c) 2009 lifeLinux under GNU GPL v2.0+
IPT="iptables --verbose"
MODPROBE="modprobe"
IF="eth0"
IP="SERVER_ADDRESS"
PORT="22 3306 5121 6121 6800"
CHECK_TIME=60
BAN_TIME=120
HITCOUNT=20
MOD="ip_tables ip_conntrack iptable_filter ipt_state"
# Load Module
for M in $MOD
do
$MODPROBE $M
done
# Flush IPTables
$IPT -F
$IPT -X
$IPT -P INPUT DROP
$IPT -P OUTPUT ACCEPT
$IPT -P FORWARD ACCEPT
# ACCEPT FROM WEBSITE
$IPT -I INPUT -i eth0 -s WEB_ADDRESS -j ACCEPT
$IPT -I FORWARD -i eth0 -s WEB_ADDRESS -j ACCEPT
# Define SYN_CHECK CHAIN
$IPT -N SYN_CHECK
# BAN IP IN
$IPT -t mangle -A PREROUTING -p TCP -d $IP -m recent --name SYN --update --seconds $BAN_TIME --hitcount $HITCOUNT -j DROP
# DROP INVALID PACKET
$IPT -A INPUT -p TCP ! --syn -m state --state NEW -j DROP
# ACCPET ALL ESTABLISHED PACKET
$IPT -A INPUT -i $IF -m state --state ESTABLISHED -j ACCEPT
# CHECK SYN
for P in $PORT
do
$IPT -A INPUT -i $IF -p TCP -d $IP --dport $P -m state --state NEW -j SYN_CHECK
done
# ACCEPT
for P in $PORT
do
$IPT -A INPUT -i $IF -p TCP -d $IP --dport $P -m state --state NEW -j ACCEPT
done
# ACCEPT EVERYTHING FROM LOCAL
$IPT -A INPUT -i lo -j ACCEPT
# SYN_CHECK CHAIN
$IPT -A SYN_CHECK -m recent --set --name SYN
$IPT -A SYN_CHECK -m recent --name SYN --update --seconds $CHECK_TIME --hitcount $HITCOUNT -j LOG --log-level 5 --log-prefix "SYN_FLOOD"
$IPT -A SYN_CHECK -m recent --name SYN --update --seconds $CHECK_TIME --hitcount $HITCOUNT -j DROP
It works fine, however this detects my website ip as an attacker, for which I added these two rules:
# ACCEPT FROM WEBSITE
$IPT -I INPUT -i eth0 -s WEB_ADDRESS -j ACCEPT
$IPT -I FORWARD -i eth0 -s WEB_ADDRESS -j ACCEPT
Which enable my ip website, but it's blocking some packets.
In my website I've got a status checker which checks the status of the server (if it's up or down) and how many users are connected. This status checker has two versions: one which update status and users online everytime I visit the page and the second one which updates it every 60 seconds, saving the status in a cache file. The second one is which fails sometimes, and it was working fine with other hosts, so it has to be a problem with the script.
Is there any way I could make the script ignore all rules and chains for this IP?
5 Replies
$IPT -t mangle -A PREROUTING -p TCP -d $IP -m recent --name SYN --update --seconds $BAN_TIME --hitcount $HITCOUNT -j DROP
does that line allow 20 connections per minute total? seems pretty low
it might mean 20 connections per source ip address, but I'm not sure.
$IPT -I INPUT -i eth0 -s WEBADDRESS -j ACCEPT
$IPT -I FORWARD -i eth0 -s WEBADDRESS -j ACCEPT
````
the lines above are in the filter table, but the rule dropping your packets is in the mangle table
anyway, you script is only useful for very small and lame attacks.
It's 20 hits per second. What's the exact rule dropping my packets, the "DROP INVALID PACKET" one?
$IPT -t mangle -A PREROUTING -p TCP -d $IP -m recent --name SYN --update --seconds $BAN_TIME --hitcount $HITCOUNT -j DROP
you'll want something like
$IPT -t mangle -I PREROUTING -i eth0 -s WEB_ADDRESS -j ACCEPT
also, I'm assuming WEB_ADDRESS is an ip address, if you need to redact your top secret public ip address, it's best to use something that looks like an ip address, x.x.x.x or whatever
also, it's just an educated guess, you need to add iptables logging to find out for sure if it doesn't fix the problem
Oh and the "top secret public ip address" irony was not necessary, thanks.