iptables y nftables prácticos: stateless y stateful
En el post anterior comenté las diferencias fundamentales entre un firewall stateful (con manejo de estados de conexiones) y uno stateless (sin manejo de estados). Veamos ahora ejemplos concretos de configuración en iptables y nftables.
Escenario de ejemplo
Supongamos un escenario muy sencillo. Un ordenador que Linux que quiere recibir conexiones SSH remotas, desde cualquier equipo de la red. En este ordenador vamos a configurar nuestro firewall.
Para lograr este objetivo debemos habilitar:
- Tráfico entrante (INPUT) al puerto 22 de TCP.
- Tráfico saliente (OUTPUT) desde el puerto 22 de TCP.
En todos los casos voy a usar políticas predeterminadas a DROP, es decir, salvo que yo indique lo contrario, el tráfico de cualquier tipo va a ser descartado.
Si bien hay varias formas de configurar un firewall, aquí voy a mostrar los scripts de la shell para cada ejemplo, las líneas de comando que solucionan nuestro problema. En otra oportunidad profundizamos estos detalles.
En estos scripts verán también las líneas que limpian las configuraciones previas del firewall, establecen políticas por defecto, y las que habilitan el tráfico en la interfaz de loopback (lo
) de Linux… no quiero que medio sistema deje de funcionar xD
🔒 Ejemplos de configuración STATELESS en iptables y nftables
Stateless en iptables
Veamos el script para lograr el objetivo con iptables stateless. Aquí las líneas importantes son las finales: habilitamos el tráfico entrante al puerto TCP 22, y luego sus respuestas, desde dicho puerto.
# Limpiamos la conf de firewall
iptables -F
# Política por defecto: denegar todo
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
# Permitir tráfico de loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Permitir tráfico entrante en puerto 22 (SSH)
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# Permitir tráfico saliente en puerto 22 (SSH)
iptables -A OUTPUT -p tcp --sport 22 -j ACCEPT
Stateless en nftables
Veamos la versión de nftables. Al principio parece más complejo puesto que en nftables debemos crear las tablas y cadenas, dado que estas no vienen configuradas de manera predeterminada como en iptables.
Aquí creamos la tabla «filtro«, y las cadenas IN y OUT (le podemos poner los nombres nosotros… les puse así para no escribir tanto, pero serían equivalentes a las cadenas INPUT y OUTPUT predeterminadas de iptables.
En la creación de las cadenas especificamos las políticas por defecto.
Luego, al igual que en el caso anterior, cargamos las reglas para permitir el tráfico TCP 22 en ambas direcciones.
# Limpiamos la conf del firewall
nft flush ruleset
# Creamos la tabla filtro
nft add table inet filtro
# Creamos las chains IN y OUT dentro de filtro, con política por defecto "drop"
nft 'add chain inet filtro IN { type filter hook input priority 0; policy drop ; }'
nft 'add chain inet filtro OUT { type filter hook output priority 0; policy drop ; }'
# Aceptamos tráfico entrante y saliente en loopback
nft add rule inet filtro IN iifname "lo" accept
nft add rule inet filtro OUT iifname "lo" accept
# Aceptamos tráfico entrante de SSH
nft add rule inet filtro IN tcp dport 22 accept
# Aceptamos tráfico saliente de SSH
nft add rule inet filtro OUT tcp sport 22 accept
🔒 Ejemplos de configuración STATEFUL en iptables y nftables
Stateful en iptables
Veamos ahora el ejemplo de iptables con manejo de estados de las conexiones en iptables.
En primer lugar, repetimos las instrucciones para limpiar el firewall, para cargar las políticas por defecto, y para aceptar el tráfico loopback.
Luego, dos reglas, una para aceptar todo el tráfico perteneciente a conexiones establecidas y relacionadas, y otras para aceptar el tráfico que provenga del exterior, con puerto 22 de TCP.
Cuando un equipo consulte el puerto de SSH, el paquete será aceptado por esta última regla, mientras que la respuesta será aceptada con la regla de manejo de estados.
# Limpiamos la conf del firewall
iptables -F
# Política por defecto: denegar todo
iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT DROP
# Aceptamos tráfico entrante y saliente en loopback
iptables -A INPUT -i lo -j ACCEPT
iptables -A OUTPUT -o lo -j ACCEPT
# Aceptamos tráfico saliente de conexiones establecidas y relacionadas
iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
# Aceptamos tráfico entrante SSH
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
Nota aquí, en la regla de manejo de estados de iptables he usado el match «state», que es en realidad un subset del match «conntrack», por lo que pueden encontrarse esta regla de esta manera también:
iptables -A OUTPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
Stateful en nftables
Finalmente, veamos el ejemplo de firewall stateful con nftables.
Aquí las primeras instrucciones son las mismas: limpieza del firewall, creación de la tabla «filtro», creación de las chains «IN» y «OUT» con policy «drop», y aceptación del tráfico loopback.
Luego viene o interesante: una regla que acepta todo el tráfico de salida (chain OUT en la tabla filtro) cuando éste pertenece a conexiones establecidas y relacionadas.
Al final, aceptamos todo el tráfico entrante cuyo puerto destino sea TCP 22, los paquetes SSH.
# Limpiamos la conf del firewall
nft flush ruleset
# Creamos la tabla filtro
nft add table inet filtro
# Creamos las chains IN y OUT dentro de filtro, con política por defecto "drop"
nft 'add chain inet filtro IN { type filter hook input priority 0; policy drop ; }'
nft 'add chain inet filtro OUT { type filter hook output priority 0; policy drop ; } '
# Aceptamos tráfico entrante y saliente en loopback
nft add rule inet filtro IN iifname "lo" accept
nft add rule inet filtro OUT iifname "lo" accept
# Aceptamos tráfico saliente de conexiones establecidas y relacionadas
nft add rule inet filtro OUT ct state established,related accept
# Aceptamos tráfico entrante SSH
nft add rule inet filtro IN tcp dport 22 accept
iptables y nftables: conclusiones
Hemos visto ejemplos simples de cómo configurar un firewall stateless y uno stateful con iptables y con nftables.
La idea general es la misma en ambos casos, cambia la sintaxis de la herramienta nada más.
Espero que les haya resultado interesante!
Publicaré más contenido sobre nftables para los usuarios de iptables, así aprendemos de a poco cómo se configura esta nueva herramienta 🙂
Hasta la próxima!