3

Один из наших серверов ежедневно поражается большим количеством спам-ботов. Они не могут публиковать спам, но все же пытаются замедлить работу сервера для реальных пользователей.

Чтобы противостоять этому, у меня на сайте работает скрипт PHP, который определяет их IP-адреса. Однако я хочу, чтобы этот скрипт автоматически добавлял эти IP-адреса в брандмауэр (а не делать это вручную). Запуск примерно так:

iptables -I INPUT -j DROP -s 123.123.123.123

Тем не менее, похоже, что команды iptables могут выполняться только от имени пользователя root. Есть ли способ обойти это? Я думаю, я мог бы добавить команды в файл, root которого запускается через cron, но на самом деле не хочу никакой задержки между принятием сценария php решения о запрете IP и добавлением запрета.

4 ответа4

4

Самым простым способом, как вы предлагаете, было бы, чтобы ваш сценарий записывал нарушающие IP-адреса в файл журнала. После этого вы можете запустить в цикле другой скрипт (с правами root), который читает файл и отправляет команду iptables . Что-то вроде:

#!/bin/bash
while true
do
  while read IP
  do
      ## Check if this IP is already banned
      if ! iptables -L INPUT -v -n | grep $IP >/dev/null
      then
      ## If it is not banned, ban it
         iptables -I INPUT -j DROP -s $IP
      fi
  done < $1
  ## Sleeping to avoid spamming, if even a one second
  ## delay is too slow for you(!) adjust as needed.
  sleep 1
done

Затем вы можете запустить этот скрипт от имени root при запуске, либо в качестве службы, либо создав этот crontab для root:

@reboot /path/to/banips.sh logfile.txt

Я полагаю, что задержка, о которой вы беспокоитесь, составляет минимум минуты. Поскольку скрипт будет выполняться в бесконечном цикле, вам не нужно запускать его каждую минуту, используя cron, и задержка зависит от вас. В настоящее время скрипт будет читать файл журнала каждую секунду.

3

В качестве альтернативы существующим ответам и добавлению sshguard (не так хорошо названный, поскольку его область намного превосходит то, что предлагает название) к упомянутому Fail2Ban, я хотел бы предложить вам sudo .

Файл /etc/sudoers может быть сконфигурирован так, чтобы жестко контролировать, кто может что запускать, кто, с какой машины. Следовательно, вы можете написать небольшую оболочку, похожую на ответ Тердона, а затем chown root: убедитесь, что его права доступа ограничены. Бросьте его в папку, например /usr/sbin и разрешите запускать его как root с любой учетной записи пользователя, под которой работает ваш PHP-скрипт. Убедитесь, что, если ваш скрипт выполняется в контексте веб-сервера и имеет chroot, скрипт находится внутри chroot. Имейте в виду, что это может быть использовано для компрометации "тюрьмы" chroot, если ваш скрипт написан плохо. Пример строки в /etc/sudoers может быть:

www-data   ALL= (root) NOPASSWD: /usr/sbin/yourscript.sh

что позволяет пользователю www-data запускать /usr/sbin/yourscript.sh от имени root без указания пароля на всех машинах (sudoers может быть центральным для всех машин в сети, поэтому ...).

sudo считается более безопасным, чем установка бита suid в вашем скрипте, но я полагаю, что есть веские причины для использования этой альтернативы, например, когда sudo недоступно.

Вы также можете проверить этот ответ, который я передал, на родственном сайте SE askubuntu.com.

2

Сделайте так, чтобы ваш PHP-сценарий записывал некорректные IP-адреса в файл журнала. Затем установите Fail2Ban и настройте его для чтения файла журнала.

0

Очень простой метод ...

Я написал PHP-скрипт, который записывает нежелательный IP-адрес в текстовый файл в каждой строке (вставьте, где это необходимо)

$banlist = file_get_contents( '/var/www/banlist.txt' );
$remoteip = $_SERVER['REMOTE_ADDR'];
if( strpos( $banlist, $remoteip ) === false ){
    file_put_contents( '/var/www/banlist.txt', $remoteip."\n", FILE_APPEND );
}

Затем я создал собственную цепочку iptables и назвал ее « banlist » (называйте как хотите) с помощью команды ...

sudo iptables --new-chain banlist

Также установка iptables-persistent с помощью ...

sudo apt-get install iptables-persistent

Наконец, используя команду ...

sudo crontab -e

Я добавил эту строку в корневой cronjob следующим образом, чтобы запускать каждые 5 минут (по вашему усмотрению), который читает каждый ip, добавляет их в цепочку iptable, которую я создал с целью DROP, а затем очищает текстовый файл ...

*/5 * * * * while read in; do sudo iptables -A banlist -s "$in" -j DROP; done < /var/www/banlist.txt && > /var/www/banlist.txt

Я также добавил эту строку, чтобы правила сохранялись каждые 5 минут ...

*/5 * * * * iptables-save > /etc/iptables/rules.v4 && ip6tables-save > /etc/iptables/rules.v6

Это оно! Сладко и просто, проверьте это, добавив случайный ip (или каждый ip на новой строке) в текстовый файл и ожидая, пока ваш cronjob запустится с выбранным интервалом ... Будьте осторожны, чтобы не забанить себя, протестировав скрипт php из вашей собственной сети ...

Примечание: чтобы очистить все ip в цепочке iptables, вы можете использовать " sudo iptables -F banlist "

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .