Сценарий оболочки для запрета IP

8

Некоторые из IP открывают тысячи соединений моего сервера. У меня есть сервер Ubuntu 14. Я проверяю общее количество соединений, используя следующую команду:

netstat -an | grep tcp | awk '{print $ 5}' | cut -f 1 -d: | сортировать | uniq -c | сортировать -n

Затем я использую следующее правило iptables, чтобы заблокировать IP-адрес преступника.

iptables -I INPUT 1 -s xxxx -j DROP

Все работает нормально и блокирует IP-адрес. Тем не менее, я не могу оставаться в сети 24/7 для мониторинга сервера. Мне было интересно, есть ли сценарий Shell, который я могу использовать, чтобы сделать это автоматически? Например, если IP-адрес открывает более X соединений в любое время, он должен автоматически быть заблокирован по вышеуказанному правилу iptables.

user3404047
источник
6
Вы смотрели, чтобы увидеть, соответствует ли fail2ban вашим потребностям?
Джон1024
Извините за мои ограниченные знания. Разве не fail2ban для проверки подлинности SSH? Я не уверен, использовать его на порту 80. Кроме того, мой сервер является сервером чата, поэтому пользователь может пытаться подключиться / пинговать несколько раз. В этом случае fail2ban вызовет много ложных срабатываний и заблокирует законный трафик. Есть мысли?
user3404047 10.10.15

Ответы:

10

Прежде всего, не изобретайте велосипед. Это именно то, что denyhostsдля:

   DenyHosts  is a python program that automatically blocks ssh attacks by
   adding entries to /etc/hosts.deny.  DenyHosts will  also  inform  Linux
   administrators  about  offending  hosts,  attacked users and suspicious
   logins.

Насколько я знаю, denyhostsэто только для sshсоединений, но есть также, fail2banчто имеет дело почти со всем:

   Fail2Ban consists of a client, server and configuration files to  limit
   brute force authentication attempts.

   The  server  program  fail2ban-server is responsible for monitoring log
   files and issuing ban/unban commands.  It  gets  configured  through  a
   simple  protocol  by fail2ban-client, which can also read configuration
   files and issue corresponding configuration commands to the server.

Оба доступны в репозиториях:

sudo apt-get install denyhosts fail2ban

Вы также можете написать это, если хотите. Что-то вроде:

#!/usr/bin/env sh
netstat -an | 
    awk -vmax=100 '/tcp/{split($5,a,":"); if(a[1] > 0 && a[1]!="0.0.0.0"){c[a[1]]++}}
    END{for(ip in c){if(c[ip]>max){print ip}}}' |
        while read ip; do iptables -I INPUT 1 -s "$ip" -j DROP; done

Он awkизвлечет IP-адреса и посчитает их, а также напечатает только те из них, которые появляются более одного maxраза (здесь -vmax=100, измените их соответственно) Затем IP-адреса передаются в цикл while, который запускает соответствующее iptablesправило.

Чтобы запустить это 24/7, я бы сделал cronjob, который запускает команду выше каждую минуту или около того. Добавить эту строку в/etc/crontab

* * * * * root /path/to/script.sh
terdon
источник
Спасибо Тердону за точный ответ. AFAIK, fail2ban для аутентификации ssh. Все соединения открываются на порту 80. Я буду исследовать, могу ли я использовать fail2ban на порту 80. Для пользовательского скрипта, как я могу запустить его 24/7 в фоновом режиме? экранная команда? Или установить cron? КСТАТИ. Я использую сервер в качестве сервера чата, чтобы человек мог пинговать много раз (или открывать несколько соединений), поэтому я мог бы использовать предоставленный вами скрипт.
user3404047 10.10.15
2
@ user3404047 вы можете запустить его как cronjob, да. Смотрите обновленный ответ. Тем fail2banне менее, это не только для SSH. Он также отлично работает для порта 80. Смотрите, например, здесь , здесь и здесь .
Terdon
1

Возможный альтернативный вариант - идентифицировать и разрешить проблемные IP-адреса в рамках набора правил iptables, используя recentмодуль. Задачей этого метода является ограничение по умолчанию для количества посещений по умолчанию, равное 20, поэтому необходимо либо отклониться от значений по умолчанию, либо создать счетчики переноса более высокого уровня для достижения более высокой точки срабатывания счетчика обращений.

Приведенный ниже пример взят из моего набора правил iptables и запретит IP-адрес чуть более чем на 1 день, если он установит 80 новых TCP-соединений через порт 80 менее чем за 12 минут. Попав в список плохих парней, любая попытка подключения обнулит счетчик 1 дня до 0. Этот метод может привести к максимуму 400 ударам, прежде чем потребуется расширение до другого переноса (и я проверил другую цепочку переносов). Обратите внимание, что опубликованный код имеет инфраструктуру, которая будет использоваться для запрета на длительный период времени при нескольких кратковременных срабатываниях. В настоящее время я настроен на длительный бан при первом срабатывании.

#######################################################################
# USER DEFINED CHAIN SUBROUTINES:
#
# http-new-in4
#
# A NEW Connection on port 80 part 4.
#
# multiple hits on the banned list means you get a one day ban.
# (I re-load the firewall rule set often, so going longer makes
# little sense.)
#
# Custom tables must exist before being referenced, hence the order
# of these sub-toutines.
#
# Place holder routine, but tested. Logs if a day ban would have
# been activated.
#
$IPTABLES -N http-new-in4
#$IPTABLES -A http-new-in4 -m recent --set --name HTTP_BAN_DAY

$IPTABLES -A http-new-in4 -j LOG --log-prefix "DAY80:" --log-level info
$IPTABLES -A http-new-in4 -j DROP

#######################################################################
# USER DEFINED CHAIN SUBROUTINES:
#
# http-new-in3
#
# A NEW Connection on port 80 part 3.
#
# carry forward to the actual banned list:
# Increment this count. Leave the previous count.
#
# Custom tables must exist before being referenced, hence the order
# of these sub-toutines.
#
$IPTABLES -N http-new-in3
$IPTABLES -A http-new-in3 -m recent --remove --name HTTP_02
$IPTABLES -A http-new-in3 -m recent --update --hitcount 1 --seconds 86400 --name HTTP_BAN -j http-new-in4
$IPTABLES -A http-new-in3 -m recent --set --name HTTP_BAN

$IPTABLES -A http-new-in3 -j LOG --log-prefix "BAN80:" --log-level info
$IPTABLES -A http-new-in3 -j DROP

#######################################################################
# USER DEFINED CHAIN SUBROUTINES:
#
# http-new-in2
#
# A NEW Connection on port 80 part 2.
#
# carry forward from previous max new connections per unit time:
# Increment this count and clear the lesser significant count.
#
$IPTABLES -N http-new-in2
$IPTABLES -A http-new-in2 -m recent --remove --name HTTP_01
$IPTABLES -A http-new-in2 -m recent --update --hitcount 3 --seconds 720 --name HTTP_02 -j http-new-in3
$IPTABLES -A http-new-in2 -m recent --set --name HTTP_02

$IPTABLES -A http-new-in2 -j LOG --log-prefix "CARRY80:" --log-level info
$IPTABLES -A http-new-in2 -j ACCEPT

#######################################################################
# USER DEFINED CHAIN SUBROUTINES:
#
# http-new-in
#
# A NEW Connection on port 80:
#
$IPTABLES -N http-new-in

echo Allowing EXTERNAL access to the WWW server

# . check the static blacklist.
#
# http related
$IPTABLES -A http-new-in -i $EXTIF -s 5.248.83.0/24 -j DROP
... delete a bunch on entries ...
$IPTABLES -A http-new-in -i $EXTIF -s 195.211.152.0/22 -j DROP
$IPTABLES -A http-new-in -i $EXTIF -s 198.27.126.38 -j DROP

# . check the dynamic banned list
#
# The 1 Hour banned list (bumped to more than a day):
$IPTABLES -A http-new-in -m recent --update --seconds 90000 --name HTTP_BAN --rsource -j LOG --log-prefix "LIM80:" --log-level info
$IPTABLES -A http-new-in -m recent --update --seconds 90000 --name HTTP_BAN --rsource -j DROP

# A generic log entry. Usually only during degugging
#
#$IPTABLES -A http-new-in -j LOG --log-prefix "NEW80ALL:" --log-level info

# Dynamic Badguy List. Least significant hit counter.  Detect and DROP Bad IPs that do excessive connections to port 80.
#
$IPTABLES -A http-new-in -m recent --update --hitcount 20 --seconds 240 --name HTTP_01 -j http-new-in2
$IPTABLES -A http-new-in -m recent --set --name HTTP_01

$IPTABLES -A http-new-in -j LOG --log-prefix "NEW80:" --log-level info
$IPTABLES -A http-new-in -j ACCEPT

... a bunch of stuff not included here

# Allow any related traffic coming back to the server in.
#
#
$IPTABLES -A INPUT -i $EXTIF -s $UNIVERSE -d $EXTIP -m state --state ESTABLISHED,RELATED -j ACCEPT

... the above is needed before the below ...

# If required, go to NEW HTTP connection sub-routine
#
$IPTABLES -A INPUT -i $EXTIF -m state --state NEW -p tcp -s $UNIVERSE -d $EXTIP --dport 80 -j http-new-in
Дуг Смитис
источник