[oclug] Apache anti-abuse
Tim Hosking
tim at trhosking.com
Fri Aug 23 08:49:41 EDT 2002
Cool. Also take a look at the iptables pathc-o-matic stuff:
Forgive the amount of pasted docs, but this really is interesting shit :)
----
The base/iplimit patch:
Author: Gerd Knorr <kraxel at bytesex.org>
Status: ItWorksForMe[tm]
This adds CONFIG_IP_NF_MATCH_IPLIMIT match allows you to restrict the
number of parallel TCP connections to a server per client IP address
(or address block).
Examples:
# allow 2 telnet connections per client host
iptables -p tcp --syn --dport 23 -m iplimit --iplimit-above 2 -j REJECT
# you can also match the other way around:
iptables -p tcp --syn --dport 23 -m iplimit ! --iplimit-above 2 -j ACCEPT
# limit the nr of parallel http requests to 16 per class C sized
# network (24 bit netmask)
iptables -p tcp --syn --dport 80 -m iplimit --iplimit-above 16
--iplimit-mask 24 -j REJECT
----
The extra/recent patch:
Author: Stephen Frost <sfrost at snowman.net>
Status: Tested locally, no problems so far.
This module is used for creating one or many list(s) of recently seen IP
addresses and then matching against that/those list(s).
--name Specify the list to use for the commands. If no name is given
then 'DEFAULT' will be used.
--set followed by an optional `!'
This will add the source address of the packet to the list.
If the source address is already in the list, this will update
the existing entry. This will always return success.
--rcheck followed by an optional `!'
This will check if the source address of the packet is currently
in the list and return true if it is, and false otherwise.
--update followed by an optional `!'
This will check if the source address of the packet is currently
in the list. If it is then that entry will be updated and the
rule will return true. If the source address is not in the list
then the rule will return false.
--remove followed by an optional `!'
This will check if the source address of the packet is currently
in the list and if so that address will be removed from the list.
--seconds followed by an optional `!', then the value
This option must be used in conjunction with one of 'rcheck' or
'update'. When used, this will narrow the match to only happen
when the address is in the list and was seen within the last
given number of seconds.
--hitcount followed by an optional `!', then the value
This option must be used in conjunction with one of 'rcheck' or
'update'. When used, this will narrow the match to only happen
when the address is in the list and packets had been received
greater than or equal to the given value. This option may be
used along with 'seconds' to create an even narrower match
requiring a certain number of hits within a specific time frame.
--rttl This option must be used in conjunction with one of 'rcheck'
or
'update'. When used, this will narrow the match to only happen
when the address is in the list and the TTL of the current packet
matches that of the packet which hit the --set rule. This may be
useful if you have problems with people faking their source
address in order to DoS you via this module by disallowing others
access to your site by sending bogus packets to you.
/proc/net/ipt_recent is a directory which contains the currently active
lists.
/proc/net/ipt_recent/* are the current lists of addresses and information
about each entry of each list.
Each file in /proc/net/ipt_recent/ can be read from to see the current
list
or written two using the following commands to modify the list:
'echo xx.xx.xx.xx > /proc/net/ipt_recent/DEFAULT' to Add to the DEFAULT
list
or 'echo +xx.xx.xx.xx > /proc/net/ipt_recent/DEFAULT' for the same
result.
'echo -xx.xx.xx.xx > /proc/net/ipt_recent/DEFAULT' to Remove from the
DEFAULT list
'echo -0.0.0.0 > /proc/net/ipt_recent/DEFAULT' to empty the DEFAULT list.
The module itself accepts two parameters:
ip_list_tot=40
ip_pkt_list_tot=10
Shown are the defaults.
ip_list_tot is the total number of addresses which will be remembered,
note
that the list is searched in-order for every attempted match and so you
do
not want to increase this value too much or alot of time will be spent
traversing the list.
ip_pkt_list_tot is the total number of packets which will be remembered
for
each address. This list is only used by '--hitcount' and so the default
will probably suffice unless you make extensive use of that option.
Example #1:
# iptables -A FORWARD -m recent --rcheck --seconds 60 -j DROP
# iptables -A FORWARD -i eth0 -d 127.0.0.0/8 -m recent --set -j DROP
Here we are making a 'bad guy' out of anyone who tries to send data to
127.0.0.0/8 on our eth0 interface (which should never legitimately
happen). The first packet will make it past the first rule and then
be caught by the second rule and that address will be put into the
recent list and the packet dropped.
Any subsequent packets for the next 60 seconds that show up from that
address will be dropped, regardless of destination address, destiation
port, etc.
Example #2:
# iptables -A FORWARD -m recent --update --seconds 60 -j DROP
# iptables -A FORWARD -i eth0 -d 127.0.0.0/8 -m recent --set -j DROP
(The author's favorite method)
This is identical to example #1 except that for every subsequent packet
received from this source address the 'last seen' status will be updated
in the table. Therefore there must be a 'quiet time' of 60 seconds
before another packet from this address will even be considered.
It is the author's intent that all 'DROP' rules be replaced by:
'-m recent --set -j DROP'
and that a:
'-m recent --update --seconds 60 -j DROP'
rule be added very early on in the rule set, though following any:
'--match state --state ! NEW,INVALID -j ACCEPT'
rules. If the '--update' rule is before this check for ! NEW,INVALID
packets then ESTABLISHED connection or those in the process of becoming
ESTABLISHED could be disrupted by a malicious person who can modify
his/her source address.
----
There are some other really nice iptables patches available too. The PSD
Match (port scan detection) is a beaut.
--
Tim Hosking
On 8/23/02 8:20 AM, "David F. Skoll" <dfs at roaringpenguin.com> wrote:
> Hi,
>
> My Web server was attacked on the 21st and 22nd August, with some
> bozo at Ottawa-HSE-ppp262070.sympatico.ca hitting me over 480,000
> times with ApacheBench.
>
> This is the second time something like this has happened, so I wrote
> this little protection script. Run it every 5 minutes from cron, feeding
> it your Apache log file as input. It firewalls off hosts who hit you
> too often (default is if 250 hits of the last 1000 are from the same host,
> you're out.)
>
> Invoke: watch-apache-abuse < /path/to/access_log
>
> It creates an iptables chain called web_abusers which you should call
> from INPUT like this:
>
> iptables -A INPUT --proto tcp --dport 80 -j web_abusers
>
> You also need a web_abusers_log chain, which you can create
> as follows:
>
> iptables -N web_abusers_log > /dev/null 2>&1
> iptables -A web_abusers_log -j LOG --log-prefix "FW: Web Abuser "
> iptables -A web_abusers_log -j DROP
>
> Regards,
>
> David.
>
> #!/bin/sh
> #
> # Usage: watch-apache-abuse < LOGFILE
> #
> # Copyright 2002 Roaring Penguin Software Inc.
> # This file may be distributed under the terms of the GNU General
> # Public License, version 2.
>
> # Sample size
> SAMPLE=1000
>
> # Number of samples from same host to be considered abuse
> ABUSE=250
>
> # Output firewall file
> FWFILE=/root/web-abusers
>
> # Back up firewall file
> mv -f $FWFILE $FWFILE.ORIG > /dev/null 2>&1 || touch $FWFILE.ORIG
>
> # Create firewall file
> cat <<EOF > $FWFILE
> #!/bin/sh
>
> iptables -F web_abusers > /dev/null 2>&1
> EOF
> # Get list of abusive hosts
>
>
> ABUSERS=""
> tail -$SAMPLE | awk '{print $1}' | sort | uniq -c | awk "{if (\$1 > $ABUSE) {
> print \$0 }}" | while read count host ; do
> fgrep $host $FWFILE.ORIG > /dev/null || echo "`date`: Host $host marked as
> abusive ($count hits)"
> echo "iptables -A web_abusers --source $host -j web_abusers_log" >> $FWFILE
> done
>
> . $FWFILE
>
>
>
>
>
> _______________________________________________
> oclug mailing list
> oclug at lists.oclug.on.ca
> http://www.oclug.on.ca/mailman/listinfo/oclug
>
More information about the OCLUG
mailing list