você está aqui: Home  → Arquivo de Mensagens

Criando regras para ips dinâmicos no iptables

Colaboração: Alexandro Silva

Data de Publicação: 27 de abril de 2013

Uma boa prática de segurança é limitar o acesso a consoles administrativas ou conteúdo privado para origens específicas. Mas como fazer isso no iptables quando seu ip é dinâmico?

Existe um patch que amplia o suporte do iptables até a camada de aplicação, só é que necessário recompilar o kernel, o que dá um certo trabalho.

Passei pelo mesmo problema e encontrei uma solução que vem funcionando muito bem.

Usando os scripts abaixo as regras do iptables serão atualizadas sempre que houver mudança no ip de origem.

RedHat e derivados

Crie o arquivo /usr/bin/dynamic_iptables.py/ com o conteúdo abaixo. Ele será responsável por verificar se o ip foi modificado e irá reiniciar o iptables.

Altere o valor da variável home_dyndns com o nome do host criado no seu serviço de DNS dinâmico ( e.g. no-ip ou dyndns )

  #!/usr/bin/python
  
  import os
  
  def gettextoutput(cmd):
     """Return (status, output) of executing cmd in a shell."""
     pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r')
     pipe = os.popen(cmd + ' 2>&1', 'r')
     text = pipe.read()
     if text[-1:] == '\n': text = text[:-1]
     return text
  
  home_dyndns = "acme.no-ip.org"
  log_dyndns = "/tmp/iptables_noip_update.log"
  last_dyndns = gettextoutput("cat " + log_dyndns)
  cur_dyndns = gettextoutput("host " + home_dyndns)
  
  print "Log: "+ last_dyndns
  print "Cur: "+ cur_dyndns
  
  if last_dyndns == cur_dyndns:
     print "IPs match, no restart necessary"
  else:
  
     print "Updating last IP with current"
     os.system("echo '" + cur_dyndns + "' > " + log_dyndns)
     print "Restarting iptables to update"
     os.system("/etc/init.d/iptables restart")

Crie o arquivo /usr/bin/update_rules.sh que será responsável pela atualização das regras do iptables com o novo endereço de origem.

Altere o valor da variável HOSTNAME com o nome do host criado no seu serviço de DNS dinâmico ( e.g. no-ip ou dyndns )

  #!/bin/bash
  
  HOSTNAME=acme.no-ip.org
  LOGFILE=/tmp/iptables_noip_update.log
  
  Current_IP=$(host $HOSTNAME | cut -f4 -d' ')
  
  if [ $LOGFILE = "" ] ; then
  iptables -I INPUT -i eth0 -s $Current_IP -j ACCEPT
  echo $Current_IP > $LOGFILE
  else
  
  Old_IP=$(cat $LOGFILE)
  
  if [ "$Current_IP" = "$Old_IP" ] ; then
  echo "IP address has not changed"
  else
  iptables -D INPUT -i eth0 -s $Old_IP -j ACCEPT
  iptables -I INPUT -i eth0 -s $Current_IP -j ACCEPT
  echo $Current_IP > $LOGFILE
  echo "iptables have been updated"
  fi

No Redhat as regras do iptables são armazenadas no arquivo /etc/sysconfig/iptables criado usando o comando iptables-save. Quando o serviço for reiniciado as regras contidas neste arquivo serão reaplicadas.

Debian e derivados

Para rodar no Debian foi preciso fazer pequenas adaptações nos scripts.

Crie o arquivo /usr/bin/dynamic_iptables.py com o conteúdo abaixo.

Altere o valor da variável home_dyndns com o nome do host criado no seu serviço de DNS dinâmico ( e.g. no-ip ou dyndns )

  #!/usr/bin/python
  import os
  
  def gettextoutput(cmd):
     """Return (status, output) of executing cmd in a shell."""
     pipe = os.popen('{ ' + cmd + '; } 2>&1', 'r')
     pipe = os.popen(cmd + ' 2>&1', 'r')
     text = pipe.read()
     if text[-1:] == '\n': text = text[:-1]
     return text
  
  home_dyndns = "acme.no-ip.org"
  log_dyndns = "/tmp/iptables_noip_update.log"
  last_dyndns = gettextoutput("cat " + log_dyndns)
  cur_dyndns = gettextoutput("host " + home_dyndns)
  
  print "Log: "+ last_dyndns
  print "Cur: "+ cur_dyndns
  
  if last_dyndns == cur_dyndns:
     print "IPs match, no restart necessary"
  else:
     print "Updating last IP with current"
     os.system("echo '" + cur_dyndns + "' > " + log_dyndns)

Crie o arquivo /usr/bin/update_rules.sh.

Altere o valor da variável HOSTNAME com o nome do host criado no seu serviço de DNS dinâmico ( e.g. no-ip ou dyndns )

  #!/bin/bash
  
  HOSTNAME=acme.no-ip.org
  LOGFILE=iptables_noip_update.log
  
  Current_IP=$(host $HOSTNAME | cut -f4 -d' ')
  
  if [ $LOGFILE = "" ] ; then
  iptables -I INPUT -i eth0 -s $Current_IP -j ACCEPT
  echo $Current_IP > $LOGFILE
  else
  
  Old_IP=$(cat $LOGFILE)
  
  iptables -D INPUT -i eth0 -s $Old_IP -j ACCEPT
  iptables -I INPUT -i eth0 -s $Current_IP -j ACCEPT
  echo $Current_IP > $LOGFILE
  echo "iptables have been updated"
  fi

Agendamento

Para automatizar o processo de atualização crie agendamentos no /etc/crontab ou no crontab do usuário root usando o comando sudo crontab -e

  * 8 * * * /usr/bin/dynamic_iptables.py > /tmp/dynamic_iptables.log
  * * * * * /usr/bin/update_rules.sh > /tmp/dynamic_rules.log

Referências



Veja a relação completa dos artigos de Alexandro Silva

 

 

Opinião dos Leitores

Alexandro Silva
06 Mai 2013, 08:56
Opa! Valeu Hugo pela excelente dica.

Abs,

Alexos
Hugo
28 Abr 2013, 15:33
Outra solução é usar o mac address no lugar do ip em todas as suas regras de iptables :-)
*Nome:
Email:
Me notifique sobre novos comentários nessa página
Oculte meu email
*Texto:
 
  Para publicar seu comentário, digite o código contido na imagem acima
 


Powered by Scriptsmill Comments Script