Есть dedicated server под FreeBSD 7.2 + ipfw + Apache. С недавних пор некое мурло повадилось
досить его при помощи DC++ ботнета. Трафик получается небольшой, но у апача исчерпываются свободные соединения, и работать он перестаёт. Можно крутить его настройки (разрешить keepalive, увеличить количество child'ов апача, увеличить число подключений к ним, уменьшить таймаут) и правила ipfw, ставя лимит на количество одновременных подключений на порт 80, но это малоэффективно. mod_evasive тоже не помогает. Если запустить tcpdump, видно, что при каждом коннекте машина из ботнета пытается передавать сообщения своего протокола:
Код: Выделить всё
IP xx.xx.xx.xx.56724 > yy.yy.yy.yy.80: P 0:79(79) ack 1 win 65340
0x0000: 4500 0077 4f52 4000 7606 bd07 588d d0fa E..wOR@.v...X...
0x0010: 5776 7729 dd94 0050 5bcf e776 904c 5659 Wvw)...P[..v.LVY
0x0020: 5018 ff3c f851 0000 244d 794e 6963 6b20 P..<.Q..$MyNick.
0x0030: 494d 4552 7c24 4c6f 636b 2045 5854 454e IMER|$Lock.EXTEN
0x0040: 4445 4450 524f 544f 434f 4c41 4243 4142 DEDPROTOCOLABCAB
0x0050: 4341 CA
Строка "$MyNick" в пакете присутствует обязательно. Написал скрипт, который парсит вывод tcpdump'а и добавляет хосты ботнета в таблицу ipfw, которой запрещено коннектиться к серверу.
Код: Выделить всё
tcpdump -n -i re0 -l -X -t -s 61 "tcp and dst host not yy.yy.yy.yy and src host not yy.yy.yy.yy" | \
awk '/^IP/ { split($2, ip, "\."); getline; getline; getline; is_botnet = match($0, "MyNick"); if(is_botnet) system("ipfw table 3 add " ip[1] "." ip[2] "." ip[3] "." ip[4]); }'
При условии того, что в ipfw разрешено максимум два коннекта в секунду с одного и того же ip, при той силе атаки, что есть сейчас, всё более-менее работает. Нет, правда, гарантии, что она не усилится. В связи с этим вопрос: можно ли как-то оптимизировать и повысить производительность процесса, исключив из него tcpdump и/или парсинг его вывода? Возможно есть какой-то способ парсить содержимое пакетов прямо файерволлом?