Usando iptables con IPs dinámicas

Si en casa tienes una máquina con IP dinámica y utilizas un servicio DNS gratuito como DynDNS, quizás alguna vez te has planteado cómo filtrar el acceso para esa máquina en un firewall con iptables.

El problema es que iptables realiza una única consulta de nombres cuando carga las reglas. Por ejemplo, si tenemos una regla para permitir el acceso al puerto 22 (ssh) al host ejemplo.dyndns.org, iptables resolverá la IP 200.41.214.129 y cargará en memoria la regla pertinente para esa IP. Cuando posteriormente la IP dinámica cambie (ej. 200.41.214.130) la regla anterior dejará de ser válida, la máquina perderá el acceso y, lo que es peor, otra máquina a la que se le asigne la IP que teníamos anteriormente podría acceder entonces por ssh...

En lugar de reiniciar iptables regularmente para comprobar si el nombre de host cambia ("/etc/init.d/iptables restart"), es recomendable definir una cadena específica y eliminar y volver a crear las reglas correspondientes cuando se detecte el cambio de host. Un shell script para este ejemplo sería:


#!/bin/bash

HOSTNAME=ejemplo.dyndns.org
LOGFILE=/tmp/dyndns.log
CADENA="dynamichosts"

IP_actual=$(host $HOSTNAME | cut -f4 -d' ')

if [ $LOGFILE = "" ] ; then
iptables -I $CADENA -i eth1 -s $IP_actual -p tcp --dport ssh -j ACCEPT
echo $IP_actual > $LOGFILE
else
IP_anterior=$(cat $LOGFILE)

if [ "$IP_actual" = "$IP_anterior" ] ; then
echo la direccion IP no ha cambiado
else
iptables -D $CADENA -i eth1 -s $IP_anterior -p tcp --dport ssh -j ACCEPT
iptables -I $CADENA -i eth1 -s $IP_actual -p tcp --dport ssh -j ACCEPT
echo $IP_actual > $LOGFILE
echo iptables actualizadas
fi
fi

Y finalmente tendríamos que añadir este script al crontab para que se ejecute cada 5 minutos:

*/5 * * * * /root/comprueba_dyndns.sh > /dev/null 2>&1

Comentarios