iptables - adiciona regras não como raiz

3

Um dos nossos servidores está sendo atingido diariamente por um grande número de spam bots. Eles não são capazes de postar nenhum spam, mas ainda assim tentam e acabam retardando o servidor para usuários reais.

Para combater isso, eu tenho um script PHP em execução no site que detecta seus endereços IP. No entanto, quero que esse script adicione automaticamente esses endereços IP ao firewall (em vez de eu ter que fazer isso manualmente). Executando algo assim:

iptables -I INPUT -j DROP -s 123.123.123.123

No entanto, parece que os comandos iptables só podem ser executados como root. Qualquer maneira de contornar isso? Eu acho que eu poderia ter os comandos adicionados a um arquivo que root é executado via cron, mas realmente não quero nenhum atraso entre o script php tomando a decisão de banir um IP e a proibição sendo adicionada.

    
por Ross McLellan 11.03.2013 / 13:46

4 respostas

2

Faça com que seu script PHP grave os endereços IP incorretos em um arquivo de log. Em seguida, instale o Fail2Ban e configure-o para ler o seu arquivo de log.

    
por 11.03.2013 / 14:25
4

A maneira mais fácil seria, como você sugere, ter seu script gravando os IPs incorretos em um arquivo de log. Você pode então ter outro script em execução (como root) em um loop que lê o arquivo e envia o comando iptables . Algo como:

#!/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

Você pode então executar este script como root ao iniciar, seja como um serviço ou criando este crontab para o root:

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

Eu assumo que o atraso com o qual você está preocupado é o mínimo de um minuto do cron. Como o script será executado em um loop infinito, você não precisa executá-lo a cada minuto usando o cron e o atraso depende de você. Tal como está, o script irá ler o arquivo de log a cada segundo.

    
por 11.03.2013 / 15:27
3

Como uma alternativa às respostas existentes e adicionando sshguard (não tão bem conhecido por seu escopo, de longe, excede o que o nome sugere) para o mencionado Fail2Ban eu gostaria de sugerir a você sudo .

O arquivo /etc/sudoers pode ser configurado para controlar com segurança quem pode executar o que como quem e de qual máquina. Portanto, você pode escrever um pequeno wrapper como em a resposta de terdon e, em seguida, chown root: e garantir que suas permissões sejam definidas . Jogue-o em uma pasta como /usr/sbin e permita que ele seja executado como root de qualquer conta de usuário em que seu script PHP seja executado. Certifique-se de que, se o seu script for executado no contexto do servidor da web e for chrooted, o script estará dentro do chroot. Tenha em mente que isso poderia ser usado para comprometer o chroot "jail" se o seu script estiver mal escrito. Uma linha de exemplo em /etc/sudoers poderia ser:

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

que permite ao usuário www-data executar /usr/sbin/yourscript.sh como root sem fornecer uma senha em todas as máquinas ( sudoers pode ser central para todas as máquinas em uma rede, é por isso ...).

sudo é considerado mais seguro do que definir o suid em seu script, mas suponho que haja boas razões para usar essa alternativa, por exemplo, quando não há sudo disponível.

Você também pode verificar esta resposta eu dei na irmã SE site askubuntu.com.

    
por 11.03.2013 / 15:56
0

Um método muito simples ...

Eu escrevi um script php que escreve o ip indesejado em um arquivo de texto em cada linha (insira sempre que necessário)

$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 );
}

Então eu criei uma cadeia iptables personalizada e a chamei de " banlist " (chame como quiser) usando o comando ...

sudo iptables --new-chain banlist

Também instalando o iptables-persistent usando ...

sudo apt-get install iptables-persistent

Por fim, usando o comando ...

sudo crontab -e

Eu adicionei esta linha ao cronjob da raiz da seguinte forma para executar a cada 5 minutos (alterar o tempo que você gosta) que lê cada ip, adiciona-os à cadeia de iptables que criei com um destino DROP e limpa o arquivo de texto. ..

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

Também adicionei esta linha para garantir que as regras sejam salvas a cada 5 minutos ...

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

É isso! Doce e simples, teste-o adicionando um ip aleatório (ou ip's cada em uma nova linha) ao arquivo de texto e esperando que seu cronjob seja executado no intervalo escolhido ... Cuidado para não se proibir testando o script php da sua própria rede ...

Nota: Para limpar todos os ip's na iptables Chain você pode usar " sudo iptables -F banlist "

    
por 09.06.2016 / 21:41