Pure-ftpd. Блокируем по ip фтп-роботов.
Добавлено: 2009-04-19 2:48:09
Ничего нового и необычного за тем, пожалуй исключением, что это awk скрипт.
Скрипт реагирует на строчки вида
В процессе участвуют:
pure-ftpd
syslogd
newsyslog
crontab
ipfw
awk
Теперь директивы для каждого из упомянутых бинарников.
Обратите внимание. Добавляем ftp.none; в строчку:
Комментируем строчку про ftp.info
И добавляем в конец файла
Скрипт реагирует на строчки вида
Код: Выделить всё
Mar 28 16:29:15 mail pure-ftpd: (?@218.62.29.118) [ERROR] Too many authentication failurespure-ftpd
syslogd
newsyslog
crontab
ipfw
awk
Теперь директивы для каждого из упомянутых бинарников.
Код: Выделить всё
grep Syslog /usr/local/etc/pure-ftpd.conf
SyslogFacility ftpКод: Выделить всё
cat /etc/syslog.confКод: Выделить всё
*.notice;authpriv.none;ftp.none;kern.debug;lpr.info;mail.crit;news.err /var/log/messagesКод: Выделить всё
#ftp.info /var/log/xferlogКод: Выделить всё
!pure-ftpd
*.* /var/log/ftp.logКод: Выделить всё
grep ftp /etc/newsyslog.conf
/var/log/ftp.log 644 5 100 * JCКод: Выделить всё
grep block /etc/crontab
*/10 * * * * root /usr/local/service/blockftp.awkКод: Выделить всё
ipfw show | grep 'dst-port 21'
00025 96 4305 reset tcp from table(3) to me dst-port 21 inКод: Выделить всё
cat /usr/local/service/blockftp.awk
#!/usr/bin/awk -f
BEGIN {
# Пользовательские переменные:
#
# ftp_log - полный путь к файлу лога ftp сервера pure-ftpd
# reject_count - число встречаемости строчки "...[ERROR] Too many authentication failures" для ip адреса.
# При превышении этого значения ip будет добавлен в таблицу, номер которой указан в переменной tbl_nr
#
#
ftp_log = ("/var/log/ftp.log")
reject_count = 2
tbl_nr = 3
patt_IPbe = ("^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$")
chkid_cmd = ("/usr/bin/id -u")
fwt_cmd = ("/sbin/ipfw -q table")
list_cmd = (fwt_cmd" "tbl_nr" list")
add_cmd = (fwt_cmd" "tbl_nr" add")
# Проверяем id пользователя.
while((chkid_cmd | getline id_is) > 0) {
if (id_is != "0") {
print "ABORTED: You are not root."
break
}
}
close (chkid_cmd)
exit
} END {
# Если id пользователя не 0, заканчиваем работу.
if (id_is != "0") {
exit 1
}
# Читаем ftp лог.
while ((getline line_in < ftp_log) > 0) {
# Нужная строчка содержит 11 элементов
if (split(line_in,TMPLINE) == 11) {
# Если содержимое удовлетворяет условию
if (TMPLINE[7] == "[ERROR]" && TMPLINE[8] == "Too" && TMPLINE[9] == "many") {
if (split(TMPLINE[6],TMPIP,"@") == 2) {
gsub(/\)/,"",TMPIP[2])
# Если после чистки значение удовлетворяет паттерну ip адреса
if (TMPIP[2] ~ patt_IPbe) {
# Если количество срабатываний с участием этого ip превышает заданый лимит
if ((TMPLOGIP[TMPIP[2]]++) > reject_count) {
# Если в массиве ip адресов из лога есть элементы
if (logrejips_cn > 0) {
it_in_log = 0
for (i=1; i<=logrejips_cn; i++) {
# Если этот ip уже есть в массиве ip адресов из лога, ничего не делаем
if (TMPIP[2] == LOGREJ[i]) {
it_in_log = 1
break
}
}
# Если этот ip не найден в массиве ip адресов из лога, добавляем его туда
if (it_in_log == 0) {
LOGREJ[++logrejips_cn] = TMPIP[2]
}
# Если в массиве ip адресов из лога нет элементов, добавляем туда текущий ip
} else {
LOGREJ[++logrejips_cn] = TMPIP[2]
}
}
}
}
split("",TMPIP)
}
}
split("",TMPLINE)
}
split("",TMPLOGIP)
close (ftp_log)
# Если у нас есть кандидаты из лога, продолжаем.
if (logrejips_cn > 0) {
# Получаем список ip адресов из таблицы фиревола в массив.
# Индексация - по ip адреcу. Пригодится в дальнейшем для поиска в массиве.
while ((list_cmd | getline line_in) > 0) {
if (split(line_in,TMPIP,"/") == 2) {
FWREJ[TMPIP[1]]
fwrejips_cn++
split("",TMPIP)
}
}
close (list_cmd)
# Если в таблице фиревола есть элементы
if (fwrejips_cn > 0 ) {
for (i=1; i<=logrejips_cn; i++) {
# Вот тут нам пригодится индексация по ip.
if ((LOGREJ[i] in FWREJ) == 0) {
# Добавляем кандидатов из лога в таблицу фиревола.
system(add_cmd" "LOGREJ[i])
}
}
# Если в таблице фиревола нет элементов
} else {
for (i=1; i<=logrejips_cn; i++) {
# Добавляем кандидатов из лога в таблицу фиревола.
system(add_cmd" "LOGREJ[i])
}
}
split("",FWREJ)
}
split("",LOGREJ)
}
# Ver 0.3
#