Gestión de iptables sencilla en Ubuntu / Debian


Son muchos los artículos que se pueden leer acerca de como configurar iptables. La siguiente entrada pretende aglutinar la información mas importante para realizar y gestionar una configuración sencilla de iptables. 



Configurar el sistema para que se almacene la configuración de iptables de manera permanente



En primer lugar es necesario centrarse en la configuración necesaria para que el sistema cargue al inicio la reglas iptables deseadas. Siempre que se realice algún cambio en iptables se deberá de almacenar dichos cambios en un fichero. En mi caso voy a almacenar las reglas en la ruta /home/cdui/reglas

Cada vez que se realice un cambio en iptables será necesario almacenar la configuración. Para almacenar las reglas se ejecutará el siguiente comando:

sudo iptables-save > /home/cdui/reglas

Una vez almacenadas las reglas es necesario configurar el sistema para que se encargue de cargar las reglas almacenadas en el fichero reglas. A tal efecto, se recomienda el empleo de iptables-persisten que se puede instalar de la siguiente forma:

sudo apt-get install iptables-persistent

Para guardar permanentemente la configuración, se ejecutará el siguiente comando:

sudo bash -c "iptables-save /etc/iptables/rules.v4"



Primeros pasos

Para que el sistema nos muestre las reglas previamente definidas se ejecutará el siguiente comando


sudo iptables -L -v


Si se quiere mostrar todas las reglas así como el número de cada regla se ejecutará el siguiente comando:
sudo iptables -L -v --line-numbers



Para eliminar todas las reglas existentes será necesario ejecutar el siguiente comando:

iptables -F

Si estamos conectados localmente a la máquina tenemos que crear las reglas pertinentes para denegar todo el tráfico. Si queremos denegar el tráfico entrante:

iptables -A INPUT -j DROP

Denegar el resto de tráfico, saliente o de reenvío. 

iptables -A OUTPUT -j DROP
iptables -A FORWARD -j DROP

Notas: Es posible que al usuario solo le interese configurar el sistema para denegar el tráfico entrante. En tal caso no se debería de aplicar el descarte de tráfico de salida o de reenvío ya que conllevará cambios de configuración mas complicados.

Posteriormente también será necesario cambiar la política de la cadena por defecto a drop para el trafico entrante:

iptables -P INPUT DROP

Nota: Esta regla debería de ser la última de todas. De esta forma se deniega todo el tráfico entrante restante.

Cambiar las restantes cadenas de política "Leer la nota anterior":

iptables -P OUTPUT DROP
iptables -P FORWARD DROP

Si no estamos conectados localmente en primer lugar será necesario permitir el acceso SSH entrante mediante la ejecución del siguiente comando:

iptables -I INPUT 1 -i eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT

Aclaraciones: new y established new se emplean ya que cuando se realiza una petición ssh por primera vez del cliente al servidor será una conexión nueva. El resto de las peticiones se considerarán como establecidas.

Posteriormente si se quiere denegar el tráfico por defecto de salida será necesario añadir la siguiente regla de tráfico saliente mediante la ejecución del comando pertinente: 

iptables -I OUTPUT 1 -o eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT

Aclaraciones: Cuando se crean reglas de salida el puerto se define mediante la opción -o de output interface. Mediante --sport se especificará el puerto origen. 

Notas: En ambos casos se ha considerado que la interfaz empleada para este tráfico es eth0 si se emplea otra interfaz se cambiará eth0 por la interfaz pertinente.



Añadir reglas de entrada



Toda regla que se añada irá por debajo de las introducidas anteriormente al menos que se especifique donde se quiere introducir la misma. Es muy importante crear una regla para permitir todo el tráfico al loopback y que esté en primer lugar. Para ello se ejecutará el siguiente comando:


sudo iptables -I INPUT 1 -i lo -j ACCEPT
sudo iptables -I OUTPUT 1 -o lo -j ACCEPT

mediante la directiva -I INPUT "numero" podemos decidir la posición en la que se quiera introducir la regla. 

Si se ha decidido denegar todo el tráfico entrante es necesario definir una regla en una posición anterior a la que deniega todo el tráfico, para permitir que las sesiones establecidas puedan recibir tráfico así como realizar cambios de puertos para mantener dichas conexiones. Para ello será necesario ejecutar el siguiente comando:

sudo iptables -I INPUT 2 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

En este caso la regla se introduce en segundo lugar. Será responsabilidad del lector conocer en que posición se quiere añadir las reglas. Recordar que dicha regla tendrá que ir en una posición anterior a la regla que deniega todo el tráfico. 

Para crear una regla que permita un protocolo por tcp se ejecutará el siguiente comando:

sudo iptables -I INPUT 3 -p tcp --dport https -j ACCEPT

Nota: Los protocolos pueden ser tcp, udp, udplite, icmp, esp, ah, sctp o all 


Para introducir una regla para un puerto especifico se ejecutará el siguiente comando: 

sudo iptables -I INPUT 4 -p tcp --dport 1444 -j ACCEPT



Por lo tanto, --port permite tanto el empleo de un puerto en concreto como como el nombre de un protocolo específico. En caso de que el protocolo introducido por el lector no existe se deberá de emplear el número del puerto. Se puede emplear un rango de puerto de la siguiente forma:

sudo iptables -I INPUT 4 -p tcp --dport 1444:1446 -j ACCEPT


Si pretende emplear una regla que permite especificar la conexiones entrantes por origen y destino así como el puerto empleado o protocolo, será necesario ejecutar el siguiente comando:

sudo iptables -I INPUT 5 -p tcp --dport https -s 192.168.1.0/24 -d 192.168.1.7/32 -j ACCEPT

Nota: -s será el origen y -d el destino. Será necesario emplear mascaras de red.

Regla similar a la anterior solo que permite especificar la interfaz de entrada a través de la opción -i:

sudo iptables -R INPUT 6 -p tcp --dport http -s 192.168.1.0/24 -d 192.168.1.7/32 -j ACCEPT -i eth0



Añadir reglas de salida



Si se quiere permitir la salida de una aplicación y luego su posterior respuesta será necesario ejecutar el siguiente comando:


iptables -I OUTPUT 1 -o eth0 -p tcp --dport 22 -m state --state NEW,ESTABLISHED -j ACCEPT


Se emplea new así como established para iniciar las conexiones y posteriormente poder establecerlas. Posteriormente será necesario crear la regla asociada para permitir las conexiones entrantes ya iniciadas mediajte la ejecución del siguiente comando



iptables -I INPUT 2 -i eth0 -p tcp --sport 22 -m state --state ESTABLISHED -j ACCEPT



Nota: En este caso se emplea solo established ya que las conexiones entrantes solo será para conexiones establecidas.


Modificar reglas



Para modificiar reglas es necesario conocer la posición de la misma. Para ello se ejecutará el siguiente comando:


sudo iptables -L -v 

En este caso se modificará la regla número tres de tipo entrante de la siguiente forma:

sudo iptables -R INPUT 3 -p udp --dport 1999 -j ACCEPT

Es decir, se emplea la opción -R junto con el tipo de tráfico "INPUT" y la posición de la regla a modificar, en este caso la número 3. El resto de los datos tendrá relación con la nuevos datos que se desean añadir.



Eliminar reglas



Al igual que las modificaciones, para eliminar una regla se deberá de conocer en que posición se encuentra. A tal efecto se ejecutará el siguiente comando:


sudo iptables -L -v

Una vez conocida la posición, la regla se eliminará de la siguiente forma:

sudo iptables -D INPUT 5

En este ejemplo se elimina la regla número 5 del tipo de tráfico entrante.


Reglas de tipo Forward

Respecto a las reglas de tipo Forward, desde crónicas de un informático queríamos dar una pincelada al respecto. Si lo que se pretende es permitir que el tráfico de una red pueda pasar a otra a través de la interfaz eth1 será necesario ejecutar los siguiente dos comandos:

iptables -A FORWARD -i eth1 -j ACCEPT
iptables -A FORWARD -o eth1 -j ACCEPT

Si lo que se quiere es permitir todo el tráfico de la red local a internet y que todo el tráfico relacionado a estas conexiones puedan volver a las máquinas que las originaron es necesario ejecutar los siguientes comandos.

sudo iptables -A FORWARD -s 192.168.0.0/16 -o ppp0 -j ACCEPT
sudo iptables -A FORWARD -d 192.168.0.0/16 -m state --state ESTABLISHED,RELATED -i ppp0 -j ACCEPT

Nota: Será necesario adaptar los ejemplos anteriores a la casuística de cada lector. 

Destacar que para estos casos es necesario habilitar ip forwarding. Para habitarlo, en primer lugar se verificará sysctl para ver si está habilitado mediante la ejecución del siguiente comando:

sysctl net.ipv4.ip_forward

Si la respuesta nos indica que el valor está en 1 es que se encuentra habilitado. En caso contrario será necesario cambiar dicho valor. Para ello se editará el siguiente archivo:

sudo nano /etc/sysctl.conf

Se modificará el siguiente parámetro para que quede de la siguiente manera:

net.ipv4.ip_forward = 1

Los cambios se habilitarán de manera permanente mediante la ejecución del siguiente comando

sysctl -p /etc/sysctl.conf

Reglas especiales



En este apartado se describirán un conjunto de reglas que pueden ser de utilidad para casos especiales. Para habilitar DNS se ejecutarán los siguientes comandos:



sudo iptables -I OUTPUT 4 -p udp --dport 53 -j ACCEPT
sudo iptables -I INPUT 5 -p udp --sport 53 -j ACCEPT

Nota: Recordar que la posición de la regla variará en función de cada caso.

Si se quiere prevenir ataques de tipo DoS se recomienda la inserción de la siguiente regla:


iptables -A INPUT -p tcp --dport 443 -m limit --limit 30/minute --limit-burst 100 -j ACCEPT

En este caso se limita a 30 conexiones por minuto el tráfico HTTPS. Este valor se podrá modificar en función de cada casuística. A través del limit-burst implicará que el límite por minuto se forzará cuando se alcance el máximo.

Registro de eventos



Si se quiere registrar el tráfico que se descarta será necesario crear una nueva cadena de tipo LOGGING. Para ello se ejecutará el siguiente comando:



iptables -N LOGGING
Posteriormente es necesario añadir una regla que envíe el tráfico restante a "registro". Esta regla deberá de estar justo por encima de aquella que descarta todo el tráfico entrante. Para ello se ejecutará el siguiente comando: 

iptables -I INPUT 10 -j LOGGING

Nota: En mi caso considero que la última regla es la número 10. Cada lector tendrá que analizar en que posición deberá de insertar esta regla.

Posteriormente se deberá de registrar los paquetes mediante la ejecución del siguiente comando:

iptables -A LOGGING -m limit --limit 2/min -j LOG --log-prefix "IPTables Packet Dropped: " --log-level 7

Se registrarán todos los paquetes descartados. Finalmente será necesario descartar los paquetes restantes mediante la ejecución del siguiente comando:

iptables -A LOGGING -j DROP


Aclaraciones finales

Si lo que se quiere es denegar la entrada de todo el tráfico entrante pero permitir la salida a aplicaciones internas es necesario permitir la entrada de tráfico relativo a aplicaciones saliente ya establecidas. Para ello se ejecutará la siguiente regla:



sudo iptables -A INPUT ACCEPT -m state --state ESTABLISHED



Posteriormente será necesario permitir todo el tráfico saliente de la siguiente forma

sudo iptables -A OUTPUT -j ACCEPT

Finalmente destacar que es necesario almacenar los cambios en iptables a través de la ejecución del comandos sudo iptables-save cada vez que se realicen cambios.