Однажды отсортировав лог веб-сервера увидел over 1k запросов вида:
642 187.45.214.10 "GET /w00tw00t.at.ISC.SANS.DFind:) HTTP/1.1" 400 349 "-" "-"
342 189.126.109.215 "GET /w00tw00t.at.ISC.SANS.DFind:) HTTP/1.1" 400 349 "-" "-"
80 187.45.224.218 "GET /w00tw00t.at.ISC.SANS.DFind:) HTTP/1.1" 400 349 "-" "-"
в гугле говорят что это веб-сканер уязвимостей, который сканирует все сервера с открытым 80 портом, хотя, едва ли это поделие можно назвать сканером, он то и делает только один и тот же GET запрос к серверу.
Но в логи веб-сервера всё же флудит, поэтому я подумал, что лучше всего будет дропать его с помощью iptables.
I. дропаем GET запросы w00tw00t.at.ISC.SANS.DFind
Для этого надо добавить следующее правило:
iptables -I INPUT -d 178.63.227.44 -p tcp --dport 80 -m string --to 70 --algo bm --string 'GET /w00tw00t.at.ISC.SANS.' -j DROP
* где 178.63.227.44 – ip вашего сервера
Теперь эти запросы будут блокироваться и в логах веб-сервера не будет флуда.
Это можно легко проверить, попробовав зайти на один из ваших хостов в браузере с таким запросом:
http://ваш.домен/w00tw00t.at.ISC.SANS.DFind:)
Вроде бы всё.. ааа нет (=
II. логирование в iptables
Захотелось логировать ip таких запросов в iptables, для статистики или just for fun.
чтобы логировать нужно добавить следущее правило:
iptables -I INPUT -d 178.63.227.44 -p tcp --dport 80 -m string --to 70 --algo bm --string 'GET /w00tw00t.at.ISC.SANS.' -j LOG --log-level debug --log-prefix "#w00tw00t**"
Правило логирования должно стоять выше/первее правила блокировки запросов “w00tw00t.at.ISC.SANS”, иначе в лог ничего не упадёт.
Теперь история таких запросов будет складываться в /var/log/debug ..хм, а также в /var/log/syslog & /var/log/messages & /var/log/kern.log
Как-то не камильфо, да?
Чтобы iptables скидывался в отдельный лог нужно настроить syslog и изменить правило логирования в iptables.
1. меняем правило логирования в iptables
iptables -I INPUT -d 178.63.227.44 -p tcp --dport 80 -m string --to 70 --algo bm --string 'GET /w00tw00t.at.ISC.SANS.' -j LOG --log-level 4 --log-prefix "#w00tw00t "
* где 178.63.227.44 – ip вашего сервера
* –log-level 4 – уровень важности сообщений warning в syslog
2. нужно добавить следущую строку в /etc/syslog.conf
kern.warning /var/log/iptables.log
перезапускаем syslog от рута:
root@ilab:~$ /etc/init.d/sysklogd restart
* Restarting system log daemon... [ OK ]
теперь лог iptables будет скидываться в /var/log/iptables.log
Dec 22 16:34:32 ilab kernel: #w00tw00t IN=eth0 OUT= MAC=00:16:3e:c2:cd:a5:0a:c4:93:62:b6:09:08:00 SRC=62.141.46.80 DST=178.63.227.44 LEN=86 TOS=0x00 PREC=0x00 TTL=122 ID=27853 DF PROTO=TCP SPT=65180 DPT=80 WINDOW=64240 RES=0x00 ACK PSH URGP=0
Dec 22 16:34:37 ilab kernel: #w00tw00t IN=eth0 OUT= MAC=00:16:3e:c2:cd:a5:0a:c4:93:62:b6:09:08:00 SRC=62.141.46.80 DST=178.63.227.44 LEN=86 TOS=0x00 PREC=0x00 TTL=122 ID=32669 DF PROTO=TCP SPT=65180 DPT=80 WINDOW=64240 RES=0x00 ACK PSH FIN URGP=0
Dec 22 18:11:38 ilab kernel: #w00tw00t IN=eth0 OUT= MAC=00:16:3e:c2:cd:a5:0a:c4:93:62:b6:09:08:00 SRC=69.59.188.212 DST=178.63.227.44 LEN=86 TOS=0x00 PREC=0x00 TTL=110 ID=23760 DF PROTO=TCP SPT=1107 DPT=80 WINDOW=65535 RES=0x00 ACK PSH URGP=0
Dec 22 18:11:47 ilab kernel: #w00tw00t IN=eth0 OUT= MAC=00:16:3e:c2:cd:a5:0a:c4:93:62:b6:09:08:00 SRC=69.59.188.212 DST=178.63.227.44 LEN=86 TOS=0x00 PREC=0x00 TTL=110 ID=31969 DF PROTO=TCP SPT=1107 DPT=80 WINDOW=65535 RES=0x00 ACK PSH FIN URGP=0
3. Не смотря на то, что kern.warning вывели в отдельный лог, в /var/log/syslog & /var/log/messages & /var/log/kern.log всё равно будет параллельно логироваться iptables.
Это я исправил следующим образом в /etc/syslog.conf, строки:
*.*;auth,authpriv.none -/var/log/syslog
kern.* -/var/log/kern.log
*.=info;*.=notice;*.=warning;
auth,authpriv.none;
cron,daemon.none;
mail,news.none -/var/log/messages
изменил на:
*.*;kern.!=warning;auth,authpriv.none -/var/log/syslog
kern.*;kern.!=warning; -/var/log/kern.log
*.=info;*.=notice;*.=warning;kern.!=warning;
auth,authpriv.none;
cron,daemon.none;
mail,news.none -/var/log/messages
опять перезапускаем syslog от рута:
/etc/init.d/sysklogd restart
Всё, теперь лог с нашего правила в iptables будет скидываться только в /var/log/iptables.log
Фактически мы все сообщения от ядра уровня warning перенаправили в /var/log/iptables.log
Но при нормальном ходе дел кроме iptables туда ничего попадать не будет.
При необходимости можно повысить/изменить уровень важности с warning на другой, более удобный вам.
Если вдруг пакеты с запросами w00tw00t.at.ISC.SAN дропаются, но логирования нет, то следует проверить порядок правил в iptables:
root@ilab:~$ iptables -L -n --line-numbers
Chain INPUT (policy ACCEPT)
num target prot opt source destination
1 LOG tcp -- 0.0.0.0/0 178.63.227.44 tcp dpt:80 STRING match "GET /w00tw00t.at.ISC.SANS." ALGO name bm TO 70 LOG flags 0 level 4 prefix `#w00tw00t '
2 DROP tcp -- 0.0.0.0/0 178.63.227.44 tcp dpt:80 STRING match "GET /w00tw00t.at.ISC.SANS." ALGO name bm TO 70
3 ACCEPT all -- 127.0.0.1 0.0.0.0/0
...
мы видим, что правило логирования идёт первее правила блокировки, как и должно быть.
III. ограничение и сортировка лога iptables
Также наверно будет актуально выставить лимит логирования, особенно если на сервере сильно ограничено дисковое пространство, это можно сделать так:
iptables -I INPUT -d 178.63.227.44 -p tcp --dport 80 -m string --to 70 --algo bm --string 'GET /w00tw00t.at.ISC.SANS.' -m limit --limit 5/m --limit-burst 7 -j LOG --log-level 4 --log-prefix "#w00tw00t "
где:
Максимальная средняя частота совпадений/пакетов в минуту, которые запишутся в лог.
Максимальное число совпадений/пакетов, при котором условие ещё считается выполненным.
Это число увеличивается на единицу каждый раз когда условие выполняется.
По истечению интервала –limit 5/m значение –limit-burst уменьшается на единицу.
IV. отлючаем ротацию syslog’ом файла /var/log/iptables.log
По умолчанию syslog будет ротировать наш iptables.log раз в неделю, возможно вас это не устроит, как и меня.
За ротацию отвечают несколько скриптов: /etc/cron.daily/sysklogd и /etc/cron.weekly/sysklogd
Открываем /etc/cron.weekly/sysklogd и находим строки:
logs=$(syslogd-listfiles --weekly)
ага, вот и список файлов, которые будут ротироваться:
root@ilab:~$ syslogd-listfiles --weekly
/var/log/mail.warn
/var/log/user.log
/var/log/daemon.log
/var/log/messages
/var/log/debug
/var/log/auth.log
/var/log/mail.err
/var/log/iptables.log
/var/log/mail.log
/var/log/kern.log
/var/log/lpr.log
/var/log/mail.info
ну что, традиционно grep?
syslogd-listfiles --weekly | grep -v -i 'iptables'
хотя.. постойте:
root@ilab:~$ syslogd-listfiles -h
Usage: syslogd-listfiles <options>
Options: -f file specifies another syslog.conf file
-a | --all list all files (including news)
--auth list all files containing auth.<some prio>
--ignore-size don't rotate files which got too large
--large nnn define what is large in bytes (default: 1MB)
--news include news logfiles, too
-w | --weekly use weekly pattern instead of daily
-s pattern skip files matching pattern
ага, как видем есть специальынй ключ “-s”, поэтому будет правильнее воспользоваться именно им:
root@ilab:~$ syslogd-listfiles --weekly -s "iptables"
/var/log/mail.warn
/var/log/user.log
/var/log/daemon.log
/var/log/messages
/var/log/debug
/var/log/auth.log
/var/log/mail.err
/var/log/mail.log
/var/log/kern.log
/var/log/lpr.log
/var/log/mail.info
Итак, заменяем в /etc/cron.weekly/sysklogd
logs=$(syslogd-listfiles --weekly)
на
logs=$(syslogd-listfiles --weekly -s "iptables")
сохраняем файл, всё, теперь sysklogd не будет ротировать наш iptables.log
Как видим ежедневный /etc/cron.daily/sysklogd я не изменял, так как он не трогал мой iptables.log, но если что мысль думаю ясна.
—-
Ну и напоследок, смотрим результаты в /var/log/iptables.log:
# смотрим последнюю запись в логе
root@ilab:~$ tail -1 /var/log/iptables.log
Dec 22 21:27:31 ilab kernel: #w00tw00t IN=eth0 OUT= MAC=00:16:3e:c2:cd:a5:0a:c4:93:62:b6:09:08:00 SRC=69.162.104.136 DST=178.63.227.44 LEN=86 TOS=0x00 PREC=0x00 TTL=108 ID=1024 DF PROTO=TCP SPT=1316 DPT=80 WINDOW=65535 RES=0x00 ACK PSH FIN URGP=0
#
# выводим список всех ip w00tw00t и сортируем по кол-ву совпадений
root@ilab:~$ grep "#w00tw00t" /var/log/iptables.log | sed 's/ / //g' | cut -f 10 -d " " | sort | uniq -c| sort -r -n | sed -e s/SRC=//g
18 67.212.82.3
14 69.162.104.136
12 62.141.46.80
9 94.136.45.55
# или так с использованием awk
root@ilab:~$ grep "#w00tw00t" /var/log/iptables.log |awk '{print $10}' | sort | uniq -c| sort -r -n | sed -e s/SRC=//g
18 67.212.82.3
14 69.162.104.136
12 62.141.46.80
9 94.136.45.55
#тестировалось на Ubuntu 9.04 Jaunty
User
January 23rd, 2014 at 12:29 pm
Зато сколько полезного в описании работы iptables
Tango
June 21st, 2013 at 8:05 am
Столько мороки из за одного дропа.