Я пытаюсь создать несколько простых правил защиты iptables DOS для своего веб-сервера. Я проводил тестирование по следующим правилам:
iptables -N LOGDROP > /dev/null 2> /dev/null
iptables -F LOGDROP
iptables -A LOGDROP -j LOG --log-prefix "LOGDROP "
iptables -A LOGDROP -j DROP
iptables -I INPUT -p tcp --dport 8000 -i eth0 -m state --state NEW -m recent --set
iptables -I INPUT -p tcp --dport 8001 -i eth0 -m state --state NEW -m recent --set
iptables -I INPUT -p tcp --dport 8000 -i eth0 -m state --state NEW -m recent --update --seconds 1 --hitcount 4 -j LOGDROP
iptables -I INPUT -p tcp --dport 8001 -i eth0 -m state --state NEW -m recent --update --seconds 1 --hitcount 4 -j LOGDROP
Я создал простой скрипт на отдельной машине, чтобы выполнить wget, а затем засыпать на 0,2 секунды. Я запустил этот скрипт на портах 8000 и 8001, и, как и ожидалось, я увидел, что в моем / var / log / messages начали появляться сообщения о сбросе:
Jul 30 20:03:57 Server kernel: LOGDROP IN=eth0 OUT= MAC=08:00:27:d5:52:24:08:00:27:6d:cf:2f:08:00 SRC=192.168.56.102 DST=192.168.56.101 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=31049 DF PROTO=TCP SPT=44071 DPT=8000 WINDOW=14600 RES=0x00 SYN URGP=0
Jul 30 20:04:00 Server kernel: LOGDROP IN=eth0 OUT= MAC=08:00:27:d5:52:24:08:00:27:6d:cf:2f:08:00 SRC=192.168.56.102 DST=192.168.56.101 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=63571 DF PROTO=TCP SPT=38876 DPT=8001 WINDOW=14600 RES=0x00 SYN URGP=0
Jul 30 20:04:00 Server kernel: LOGDROP IN=eth0 OUT= MAC=08:00:27:d5:52:24:08:00:27:6d:cf:2f:08:00 SRC=192.168.56.102 DST=192.168.56.101 LEN=60 TOS=0x00 PREC=0x00 TTL=64 ID=63984 DF PROTO=TCP SPT=44075 DPT=8000 WINDOW=14600 RES=0x00 SYN URGP=0
Все выглядит отлично, за исключением того, что когда я проверил wirehark, я обнаружил, что соединение с исходным портом 44071 было успешным, то есть я видел полное рукопожатие tcp, HTTP GET и закрытие сокета. Две другие записи в журнале были успешно отброшены, то есть я видел только SYN-пакет в wirehark.
Кто-нибудь знает, почему соединение на исходном порте 38876 регистрируется как отклоненное, но не разрывается?
Я заметил, глядя на wirehark, что действительно видел заблокированный трафик, мой скрипт просто повторно использовал сокеты. В результате для любой заблокированной записи сокета в моем журнале я бы увидел несколько начальных SYN.
Кроме того, чтобы эти правила работали, мне нужно было добавить атрибут --name к каждой строке iptable. Без --name все соединения с одного и того же IP-адреса применяются к счетчику обращений независимо от того, на какой порт он поступил.
В общем, проблема решена.
Ваше правило сначала переходит из таблицы INPUT в таблицу LOGDROP, а затем в таблицу LOG, поэтому последняя запись в таблице LOGDROP никогда не вызывается, поскольку вы уже переместили выполнение в таблицу LOG.