Primeros pasos en nftables: resolviendo un caso práctico
Hoy vamos a dar nuestros primeros pasos en nftables adentrándonos en las configuraciones persistentes del firewall en Debian, resolviendo un pequeño caso práctico.
El esquema de red del ejemplo
Supongamos el siguiente esquema de red:
- Un cliente que se conecta a Internet por medio de un router/firewall Linux.
- El cliente tiene la dirección IP 192.168.20.100, y usa como puerta de enlace predeterminada (default gateway) al router/firewall.
- El router/firewall dispone de dos interfaces de red:
- enp2s0, conectada al cliente, con IP 192.168.20.1
- ens1, conectada a Internet, con una dirección IP pública.

Vamos a realizar las siguientes configuraciones en nuestro router/firewall con nftables:
- Configurar el firewall GNU/Linux como router (reglas NAT incluidas)
- Crear la tabla filter
- Crear las cadenas input, output y forward en la tabla filter
- Denegar todo el tráfico en las tres cadenas de manera predeterminada
- Habilitar el tráfico input/output en la interfaz de loopback
- Crear las reglas de manejo de estado de conexiones (firewall stateful)
- Habilitar al cliente para que pueda navegar en Internet (http/https, dns)
- Habilitar al cliente para que pueda conectarse al firewall via SSH
- Habilitar al cliente para que pueda hacer
ping
al exterior, sólo con fines de debugging.
Con estas configuraciones tocamos varias cosas de networking y nftables… por supuesto, le daremos un pequeño valor añadido con variables y comentarios 🙂
¿Querés saber más de Redes TCP/IP y protocolos de Internet?
Sumate a nuestro curso 📚!
Linux como router!
Esto ya lo hemos visto con anterioridad, así que les comparto el artículo en el blog, y el video en youtube para que puedan cumplimentar este paso 🙂
- Artículo en el blog: Linux como router: configuraciones básicas
- Video en Youtube: https://www.youtube.com/watch?v=gcdIfT9fMNQ
Tablas, cadenas y reglas
En esta oportunidad vamos a dar nuestros primeros pasos en nftables de manera perrsistente, no vamos a detallar cada uno de los comandos para crear cada cosa manualmente (ya hemos visto algo de eso antes), sino que vamos ha hacerlo editando un archivo de configuración.
En esta configuración tendremos lo siguiente:
- Una tabla filter con:
- Una cadena INPUT con política por default a DROP, con:
- Una rergla para aceptar conexiones establecidas y relacionadas (stateful).
- Una regla para aceptar el tráfico loopback de entrada.
- Una regla para aceptar el tráfico entrante TCP 22 (SSH).
- Una cadena OUTPUT con política por default a DROP, con:
- Una rergla para aceptar conexiones establecidas y relacionadas.
- Una regla para aceptar el tráfico loopback de salida.
- Una cadena FORWARD con política por default a DROP, con:
- Una rergla para aceptar conexiones establecidas y relacionadas.
- Una regla para aceptar tráfico TCP 80/443 (HTTP/HTTP) desde la LAN.
- Una regla para aceptar tráfico UDP 53 (DNS) desde la LAN.
- Una regla para aceptar tráfico ICMP (ping) desde la LAN, para depuración.
- Una cadena INPUT con política por default a DROP, con:
- Una tabla NAT con:
- Una cadena POSTROUTING con:
- Una regla para enmascarar todo el tráfico saliente hacia Internet.
- Una cadena POSTROUTING con:
A esto vamos a sumarle algunas funcionalidades de nftables, como:
- Uso de comentarios para documentar la configuración.
- Uso de variables para parametrizar las reglas.
El script completo
Aquí va el script de configuración. En este caso fue un Debian 12, por lo que el script se encuentra en /etc/nftables.conf.
#!/usr/sbin/nft -f
# limpiamos las reglas
flush ruleset
# Definimos algunas variables
define LAN = 192.168.20.0/24
define POLICY = "drop"
define OIF = "ens1"
# Tabla Filter
table inet filter {
# cadena INPUT con policy default a drop
chain input {
type filter hook input priority filter;
policy $POLICY
# stateful
ct state {established,related} accept
# aceptamos tráfico loopback para que no explote todo
iifname "lo" accept
# SSH desde la LAN
ip saddr $LAN tcp dport 22 accept
}
# cadena FORWARD con policy default a drop
chain forward {
type filter hook forward priority filter;
policy $POLICY
# stateful
ct state {established,related} accept
# ping desde la LAN a Internet (testing)
ip saddr $LAN icmp type echo-request accept
# HTTP/HTTPS desde la LAN a Internet
ip saddr $LAN tcp dport {80,443} accept
# DNS desde la LAN a Internet
ip saddr $LAN udp dport 53 accept
}
# cadena OUTPUT con policy default a drop
chain output {
type filter hook output priority filter;
policy $POLICY
# stateful
ct state {established,related} accept
# aceptamos tráfico loopback para que no explote todo
oifname "lo" accept
}
}
# Tabla NAT
table ip nat {
# Cadna POSTROUTING
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
# masquerade del tráfico de la LAN a Internet
ip saddr $LAN oifname $OIF masquerade
}
}
Como se ve, he parametrizado direcciones IP de la LAN, nombre de la interfaz de red de salida, y la policy por default. Esto me permite cambiar todas las policies predeterminadas modificando el valor de una variable, muy útil cuando estamos aprendiendo, y queremos cambiar el comportamiento con poco esfuerzo.
Primeros pasos en nftables: ¿se puede hacer más?
La intención de este post es que demos nuestros primeros pasos en nftables, que veamos una manera de configurarlo de forma simple, y nos deje un firewall funcional y persistente.
¿Podría haberse hecho de otra forma? ¿Podría ser mejor?
Sí, por supuesto, entre otras:
- Podríamos haber organizado mejor las tablas en diferentes archivos de configuración, facilitando el mantenimiento de las configuraciones.
- Podríamos también haber añadido contadores de tráfico para mantener estadísticas.
- Podríamos haber incluido comentarios dentro de las reglas para verlos en un
list ruleset
.
Pero esto vamos a dejarlo para más adelante, o para que puedan verlo directamente en el curso, al igual que los comandos detallados y otras curiosidades 😜
En poco tiempo tendremos el curso de Nftables online para que puedan seguir aprendiendo esto y mucho más!
Y sí, este artículo será publicado en el canal de Youtube como video, para que veamos paso a paso las configuraciones y sus detalles, no olviden seguirnos para enterarse!
Hasta la próxima!