iptables vs ssh brute force/http DDoS

Tracy Reed treed at ultraviolet.org
Tue May 19 00:49:59 PDT 2009


For a long time I have avoided having to deal with iptables directly
by using Shorewall instead. Having learned ipfwadm and then ipchains I
have been loathe to learn a new system lest they change it yet
again. But iptables been with us for years now and in the last few
months I have run into a couple of situations where it was handy to
learn some iptables and implement some rules on my servers which did
not run shorewall. iptables can do an awful lot these days. There is a
kernel module called ipt_recent which gets loaded when you use the -m
recent option to iptables. This thing can implement tracking of state
such as how many times a certain ip has tried to establish a TCP
connection within a certain amount of time.

The first place this came in handy was in defeating ssh brute force
attacks. Ever since I implemented it the amount of ssh brute force
messages in my system logs has gone way down. I just copied these ssh
rules from someone else's recipe.

Then yesterday I took on the hosting of a website which turned out to
be under a DDoS attack from some script kiddies. This was the reason
they were moving away from their previous provider: they just couldn't
provide the needed support or mitigate the attack. I just threw the
following HTTP related iptables rules on the new server hosting the
site and the problem went away immediately. I also modified
/etc/syslog.conf with the following:

kern.*							/var/log/firewall.log
kern.none;*.info;mail.none;authpriv.none;cron.none	/var/log/messages

so that the firewall related stuff (and possibly other kernel related
stuff but I don't care that much) gets logged to a special logfile
which I can now tail -f and watch the miscreant's traffic rejected
with satisfaction.

From a grep of /var/log/firewall.log I can see that in the past 13
hours I have rejected 24 SSH brute force attack connections and
27913 HTTP DDoS attack connections. Not half bad.

And now for the iptables script I use:

#!/bin/sh

export PATH=$PATH:/sbin

# Clear out all existing rules. You may not want this part if you are
# going to paste the rest into your own existing rules.
iptables -F
iptables -t nat -F
iptables -t mangle -F
iptables -X

# Deal with SSH brute force attacks
iptables -N SSH_WHITELIST
iptables -A SSH_WHITELIST -s 68.15.4.0/24 -m recent --remove --name SSH -j ACCEPT
iptables -A SSH_WHITELIST -s 70.164.113.0/24 -m recent --remove --name SSH -j ACCEPT
iptables -A SSH_WHITELIST -s 207.167.89.0/24 -m recent --remove --name SSH -j ACCEPT
iptables -A SSH_WHITELIST -s 76.199.182.0/24 -m recent --remove --name SSH -j ACCEPT

iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --set --name SSH
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -j SSH_WHITELIST
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --rttl --name SSH -j LOG 
iptables -A INPUT -p tcp --dport 22 -m state --state NEW -m recent --update --seconds 60 --hitcount 4 --rttl --name SSH -j DROP


# Deal with HTTP DOS attacks
iptables -N HTTP_WHITELIST
iptables -A HTTP_WHITELIST -s 151.80.197.217 -m recent --remove --name HTTP -j ACCEPT
iptables -A HTTP_WHITELIST -s 216.105.40.113 -m recent --remove --name HTTP -j ACCEPT
iptables -A HTTP_WHITELIST -s 76.199.182.169 -m recent --remove --name HTTP -j ACCEPT

iptables -N HTTP_DOS
iptables -A HTTP_DOS -m recent --set --name HTTP
iptables -A HTTP_DOS -p tcp --dport 80 -m state --state NEW -j HTTP_WHITELIST
iptables -A HTTP_DOS -m recent --update --seconds 30 --hitcount 15 --name HTTP -j LOG
iptables -A HTTP_DOS -m recent --update --seconds 30 --hitcount 15 --name HTTP -j DROP

iptables -A INPUT -p tcp --dport 80 -m state --state NEW -j HTTP_DOS


Note that the WHITELIST rules are to prevent me from somehow
accidentally locking myself out of my own server via http or ssh.

I will probably eventually clean up the SSH whitelist to be called its
own chain instead of INPUT to remove all of the extra use of "-p tcp
--dport 22 -m state --state NEW" just like the HTTP_DOS chain but
right now it all works and don't want to touch anything.

Note to self: Configure cfengine to distribute these SSH rules around
to all of my servers.

I just thought I would post this both to get it into the archives in
case I ever lose track of it and in case someone else here finds
themselves in a similar situation.

-- 
Tracy Reed
http://tracyreed.org
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://www.kernel-panic.org/pipermail/kplug-list/attachments/20090519/3451589e/attachment.pgp


More information about the KPLUG-List mailing list