I wrote a simple blacklisting script with port scan detection.

Requires:
microperl

Recommended to have:
ipt_limit module (unless you want to log EVERY packet)

package includes:
blacklistd.pl   - the daemon that reads logread -f output and analyzes it for dropped packets
blacklist.pl     - script to read firewall.blacklist_addresses file when the firewall starts
blacklistd_ctl.sh   - script to control blacklistd.pl (can be symlinked to /etc/init.d/)

http://lappi.skai.fi/~mikkoko/misc/blac … 1.1.tar.gz

I'm probably going to rewrite it for ash because microperl is quite big for a 2MB writable partition. Also, the logging does not currently seem to work.

Note that the daemon script will think EVERY packet it receives is a dropped one, so log just the dropped packets or use some --log-prefix & grep it (modify blacklistd_ctl.sh if needed). blacklistd.pl contains some settings too if you want to adjust the sensitivity:

#sensitivity settings
my $max_points                  = 2000; #points needed for host to be blacklisted
my $new_port_points             = 200;  #points for trying to access an untried port/proto combination
my $old_port_points             = 30;   #points for trying to access a port/proto combination that was tried already



INSTALL:

blacklist script 0.1.1 quick installation guide - try at your own risk!!

1. Extract the tarball in /tmp/

2. cp /tmp/blacklistd-0.1.1/*blacklist* /etc/

3. cp /tmp/blacklistd-0.1.1/firewall.blacklist-addresses /etc/

4. cp /etc/init.d/S45firewall /etc/firewall.test

5. Make necessary changes to your test firewall.
By default, the blacklist script will use the chain blacklist_check_in for
INPUT checking, blacklist_check_fw for FORWARD checking and blacklist_check_out
for OUTPUT checking. You must set your firewall to FIRST move all packets to the
blacklist_check chains for checking of blacklisted hosts. You also must set
correct logging for the script to work. Check firewall.example for more information.

6. TEST your new firewall setup BEFORE adding it to /etc/init.d, in case you
screw up and can't connect to the router (so you can always just reboot it)
by running /etc/init.d/S45firewall

7. /etc/blacklistd_ctl.sh start

8. Try simulating dropped packets somehow (telnetting to forbidden ports
from WAN etc) - if the script receives a syslog
line, a file should appear to /tmp/blacklistd.data (file name = ip address).
When the host has enough counts, it should be automatically blacklisted with
iptables -A blacklist_check_xx -s IP_ADDR -j blacklist_end, and the IP will
be added to /etc/firewall.blacklist-addresses

9. ln -s /etc/blacklistd_ctl.sh /etc/init.d/S46blacklistd

10. cp /etc/init.d/S45firewall /etc/firewall.old

11. mv /etc/firewall.test /etc/init.d/S45firewall

firewall.example:

#!/bin/sh

## Please make changes in /etc/firewall.user
${FAILSAFE:+exit}

. /etc/functions.sh
WAN=$(nvram get wan_ifname)
LAN=$(nvram get lan_ifname)

echo -n "Loading iptables modules... "
insmod ipt_limit

echo "Flushing tables... "
for T in filter nat mangle; do
  iptables -t $T -F
  iptables -t $T -X
done

iptables -N u_in
iptables -N u_out
iptables -N u_fw

iptables -t nat -N u_pre
iptables -t nat -N u_post

iptables -N log_warn
iptables -A log_warn -m limit --limit 5/minute -j LOG --log-level warn

#this is where the packets from blacklisted addresses will end to
iptables -N blacklist_end
iptables -F blacklist_end
iptables -A blacklist_end -j DROP

echo "Reading blacklisted addresses from /etc/firewall.blacklist-addresses..."
/etc/blacklist.pl \
    --read=/etc/firewall.blacklist-addresses \
    --end-chain=blacklist_end\
    --check-chain-prefix=blacklist_check_\
    --apply

echo -n "INPUT... "
    iptables -P INPUT DROP
    
    # checking for blacklisted addresses
    iptables -A INPUT -i $WAN -j blacklist_check_in
    
    iptables -A INPUT -i lo -j ACCEPT
    
    iptables -A INPUT -i \! $WAN -m state --state INVALID -m limit --limit 5/second -j LOG --log-level crit --log-prefix "invalid-input-lan"
    iptables -A INPUT -i $WAN -m state --state INVALID -m limit --limit 5/second -j LOG --log-level crit --log-prefix "invalid-input-wan"
    iptables -A INPUT -m state --state INVALID -m limit --limit 5/second -j DROP
    iptables -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
    iptables -A INPUT -p tcp --tcp-flags SYN SYN --tcp-option \! 2 -j  DROP
    
    # user rules - should be placed in firewall.user (to keep the firewall more readable)
    iptables -A INPUT -j u_in
    
    # allow
    iptables -A INPUT -i \! $WAN    -j ACCEPT
    
    iptables -A INPUT -j log_warn
    iptables -A INPUT -j DROP

echo -n "OUTPUT... "
    iptables -P OUTPUT DROP
    
    iptables -A OUTPUT -o lo -j ACCEPT
    
    #everything going out on wan -> checking for blacklisted addresses
    iptables -A OUTPUT -o $WAN -j blacklist_check_out
    
    iptables -A OUTPUT -m state --state INVALID -m limit --limit 5/second -j LOG --log-level crit --log-prefix "invalid-output"
    iptables -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT

    #user rules
    iptables -A OUTPUT -j u_out

    # allow
    iptables -A OUTPUT -j ACCEPT        #allow everything out

echo -n "FORWARD... "
    iptables -P FORWARD DROP
    
    #everything coming in from WAN trying to access other networks -> checking for blacklisted addresses
    iptables -A FORWARD -i $WAN -j blacklist_check_fw
    
    #wan invalid
    iptables -A FORWARD -i $WAN -m state --state INVALID -m limit --limit 5/second -j LOG --log-level crit --log-prefix "invalid-fw-wan"
    iptables -A FORWARD -i \! $WAN -m state --state INVALID -m limit --limit 5/second -j LOG --log-level crit --log-prefix "invalid-fw-lan"
    iptables -A FORWARD -m state --state INVALID -j DROP
    
    # known connections / return traffic
    iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
    
    # user rules
    iptables -A FORWARD -j u_fw
        
        #trying to access lan from wan
        iptables -A FORWARD -i $WAN -o $LAN -m limit --limit 5/second -j LOG --log-level crit --log-prefix "wan-to-lan"
        iptables -A FORWARD -i $WAN -o $LAN -j DROP
    
    # allow
    iptables -A FORWARD -i br0 -o br0 -j ACCEPT
    iptables -A FORWARD -i $LAN -o $WAN -j ACCEPT
    
    iptables -A FORWARD -j log_warn
    iptables -A FORWARD -j DROP
    
echo -n "NAT... "
    iptables -t nat -A PREROUTING -j u_pre
    iptables -t nat -A POSTROUTING -j u_post
    iptables -t nat -A POSTROUTING -o $WAN -j MASQUERADE

echo -n "User rules... "
[ -f /etc/firewall.user ] && . /etc/firewall.user

echo "Done."

Seems to work for me. Hope someone else finds it useful too.