У меня в результате получился такой вариант начальной части post-firewall, который делает следующее:
1) Все действия по ssh порту вынесены в отдельный SSH_EVAL chain (насколько я понимаю так снижается количество проверок выполняемых iptables при выполнении _каждого_ соединения. Если запрос приходит на ssh порт, то на здоровье пусть хоть 100 правил проверяет...)
2) Созданы "белый" и "черный" списки адресов (какая польза от черного не знаю, но сделал для полноты картины). По тем IP которые находятся в этих списках решение принимается до проверки ipt_recent
3) Первое обновление recent перенесено из PREROUTING в тот же SSH_EVAL chain. Теперь оно выполняется только на тех соединениях, которые идут на ssh и не были отфильтрованы двумя вышеуказанными списками.
PHP Code:
#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:usr/bin:/opt/sbin:/opt/bin:/opt/local/bin
logger "post-firewall started"
#this rule can be uncommented for the testing period
#iptables -A INPUT -p tcp --syn --dport 2222 -j ACCEPT
# set default policy
iptables -P INPUT DROP
# remove last default rule
iptables -D INPUT -j DROP
# ***ssh subsection begin***
SSH_PORT=22
SSH_ALLOW=/usr/local/etc/ssh.allow
SSH_DENY=/usr/local/etc/ssh.deny
# Create a new SSH_EVAL chain which will evaluate incoming connections to ssh server from WAN
iptables -N SSH_EVAL
# Transfer all ssh connections to the SSH_EVAL chain
iptables -A INPUT -p tcp --dport $SSH_PORT -j SSH_EVAL
# Evaluate incoming ssh connections through ssh.allow and ssh.deny lists
for i in `awk '{print $1}' $SSH_ALLOW`
do
iptables -A SSH_EVAL -p tcp --syn -s $i --dport $SSH_PORT -j ACCEPT
done
for i in `awk '{print $1}' $SSH_DENY`
do
iptables -A SSH_EVAL -p tcp --syn -s $i --dport $SSH_PORT -j DROP
done
# Block annoying intruder's attemtps (after --hitcount connections occured, wait --seconds after the last connection attempt)
# Remember, that both successful and unsuccessful connections are counted
iptables -A SSH_EVAL -i ! $3 -p tcp -m state --state NEW --dport $SSH_PORT -m recent --set --name SSH_ATTACKER --rsource
iptables -A SSH_EVAL -i ! $3 -p tcp -m state --state NEW --dport $SSH_PORT -m recent --update --seconds 600 --hitcount 4 --name SSH_ATTACKER --rsource -j DROP
# Accept the rest of ssh connections which were able to pass through the filtering
iptables -A SSH_EVAL -p tcp --syn --dport $SSH_PORT -j ACCEPT
# ***ssh subsection end***
...
Остальные правила post-firewall
Файлы /usr/local/etc/ssh.allow & /usr/local/etc/ssh.deny содержат следующиее (сам адрес стоит в начале строки, потом пробел, потом любой комментарий):
PHP Code:
12.34.56.78 разрешить/запретить доступ с одиночного IP
87.65.43.0/24 разрешить/запретить доступ с подсетки
P.S. Напоминаю, что модуль ipt_recent.o должен быть загружен в файле /usr/local/sbin/pre-boot
Так что в файле pre-boot должно стоять либо ( для использования встроенного в прошивку ipt_recent ):
PHP Code:
insmod ipt_recent
либо ( для использования ipt_recent от Mam(o)n : http://wl500g.info/showpost.php?p=69660&postcount=53 )
PHP Code:
date 010101012000
insmod /usr/local/lib/ipt_recent.o