TL;DR — Resumen Rápido

nftables reemplaza a iptables como el firewall moderno de Linux. Aprende sintaxis nft, familias de tablas, conjuntos, NAT, limitación de tasa y migración.

nftables es el sucesor oficial de iptables, ip6tables, arptables y ebtables, unificados en un solo framework en el kernel de Linux desde la versión 4.x. Si todavía escribes reglas de firewall con iptables, esta guía te muestra por qué nftables es mejor, cómo migrar tus reglas existentes y cómo construir un firewall completo desde cero con nft.

Requisitos Previos

  • Kernel de Linux 4.x o posterior (Ubuntu 20.04+, Debian 10+, RHEL/CentOS 8+, Fedora 32+).
  • Acceso como root o con sudo.
  • Conocimientos básicos de redes TCP/IP (puertos, protocolos, notación CIDR).
  • Reglas iptables existentes para migrar (opcional, pero útil para el contexto).

¿Por Qué nftables?

El ecosistema iptables consistía en cuatro herramientas separadas — nftables las reemplaza a todas:

  • IPv4/IPv6 unificado — La familia inet maneja ambos en un solo conjunto de reglas.
  • Reemplazo atómico de reglas — El conjunto de reglas completo se aplica en una sola transacción del kernel.
  • Mejor sintaxis — Una regla puede coincidir con múltiples puertos, protocolos o direcciones sin repetirla.
  • Conjuntos y mapas — Almacena miles de IPs o rangos de puertos como conjuntos en el kernel para búsqueda O(1).
  • Mejor rendimiento — Menos llamadas al kernel. Los conjuntos de reglas grandes son significativamente más rápidos.
  • Un solo comandonft reemplaza a iptables, ip6tables, arptables y ebtables.

Migración desde iptables

La Capa de Compatibilidad iptables-nft

La mayoría de las distribuciones incluyen iptables-nft, un reemplazo directo que ejecuta comandos iptables pero almacena las reglas en el subsistema nftables del kernel:

# Verificar qué backend usa tu iptables
iptables --version
# iptables v1.8.7 (nf_tables)  ← ya usa el backend nftables
# iptables v1.8.7 (legacy)     ← aún usa el backend iptables

Traducción de Reglas con iptables-translate

# Traducir una regla individual
iptables-translate -A INPUT -p tcp --dport 22 -j ACCEPT
# Salida: nft add rule ip filter INPUT tcp dport 22 counter accept

# Traducir un conjunto de reglas guardado
iptables-save | iptables-restore-translate -f /etc/nftables.conf

Fundamentos del Comando nft

# Listar el conjunto de reglas completo
nft list ruleset

# Listar una tabla específica
nft list table inet filter

# Vaciar todo (cuidado — elimina todas las reglas)
nft flush ruleset

# Cargar reglas desde un archivo
nft -f /etc/nftables.conf

# Agregar una tabla
nft add table inet filter

# Eliminar una tabla (y todas sus cadenas y reglas)
nft delete table inet filter

Tablas y Cadenas

Familias de Tablas

FamiliaManeja
ipSolo paquetes IPv4
ip6Solo paquetes IPv6
inetIPv4 e IPv6 (recomendado para la mayoría de reglas)
arpPaquetes ARP
bridgePaquetes que atraviesan un bridge Linux
netdevPaquetes desde un dispositivo de red específico (hook ingress)

Tipos de Cadenas y Hooks

Tipo de CadenaHooks VálidosPrioridad Común
filterprerouting, input, forward, output, postrouting0
natprerouting, input, output, postrouting-100
routeoutput-150
# Crear una cadena base de entrada con política drop
nft add chain inet filter input \
  '{ type filter hook input priority 0 ; policy drop ; }'

# Crear una cadena de reenvío
nft add chain inet filter forward \
  '{ type filter hook forward priority 0 ; policy drop ; }'

# Crear una cadena regular (sin hook — llamada vía jump)
nft add chain inet filter tcp_permitido

Sintaxis de Reglas

Las reglas constan de coincidencias (condiciones) y veredictos (acciones).

Coincidencias Comunes

# Coincidir por IP origen
nft add rule inet filter input ip saddr 192.168.1.0/24 accept

# Coincidir por puerto destino
nft add rule inet filter input tcp dport 443 accept

# Coincidir múltiples puertos en una regla
nft add rule inet filter input tcp dport { 80, 443, 8080 } accept

# Coincidir por estado de seguimiento de conexión
nft add rule inet filter input ct state established,related accept
nft add rule inet filter input ct state invalid drop

# Coincidir por interfaz
nft add rule inet filter input iifname "lo" accept
nft add rule inet filter input iifname "eth0" tcp dport 22 accept

Acciones Comunes (Veredictos)

accept          # Permitir el paquete
drop            # Descartar silenciosamente
reject          # Descartar y enviar ICMP inalcanzable (o TCP RST)
log             # Registrar en el log del kernel (continúa la evaluación)
counter         # Contar paquetes (continúa la evaluación)
jump nombre     # Saltar a otra cadena
return          # Retornar de la cadena actual

Conjuntos y Mapas

Conjuntos Anónimos (en Línea)

# Permitir HTTP y HTTPS en una regla
nft add rule inet filter input tcp dport { 80, 443 } accept

# Bloquear IPs origen específicas
nft add rule inet filter input ip saddr { 10.0.0.5, 10.0.0.6 } drop

Conjuntos Con Nombre

# Crear un conjunto nombrado de direcciones IPv4
nft add set inet filter ips_bloqueadas { type ipv4_addr ; }

# Agregar elementos
nft add element inet filter ips_bloqueadas { 1.2.3.4, 5.6.7.8 }

# Usar el conjunto en una regla
nft add rule inet filter input ip saddr @ips_bloqueadas drop

# Conjunto con intervalos (rangos CIDR)
nft add set inet filter redes_confiables \
  { type ipv4_addr ; flags interval ; }
nft add element inet filter redes_confiables \
  { 192.168.0.0/24, 10.0.0.0/8 }

Mapas de Veredictos (vmaps)

# Mapa de puerto destino a veredicto
nft add map inet filter veredicto_puerto \
  { type inet_service : verdict ; }
nft add element inet filter veredicto_puerto \
  { 22 : accept, 80 : accept, 443 : accept, 25 : drop }

nft add rule inet filter input \
  tcp dport vmap @veredicto_puerto

Configuración NAT

# Crear tabla NAT y cadenas
nft add table ip nat
nft add chain ip nat prerouting \
  '{ type nat hook prerouting priority -100 ; }'
nft add chain ip nat postrouting \
  '{ type nat hook postrouting priority 100 ; }'

# Masquerade (SNAT para tráfico saliente — router/gateway)
nft add rule ip nat postrouting oifname "eth0" masquerade

# DNAT (reenvío de puertos — redirigir puerto 8080 a host interno)
nft add rule ip nat prerouting \
  tcp dport 8080 dnat to 192.168.1.100:80

# SNAT estático (usar una IP origen específica)
nft add rule ip nat postrouting \
  ip saddr 192.168.1.0/24 snat to 203.0.113.1

Limitación de Tasa

# Limitar nuevas conexiones SSH a 3 por minuto por IP origen
nft add rule inet filter input \
  tcp dport 22 ct state new \
  limit rate 3/minute burst 5 packets accept

# Limitar tasa de ping ICMP
nft add rule inet filter input \
  ip protocol icmp icmp type echo-request \
  limit rate 10/second accept

Registro de Eventos

# Registrar con un prefijo personalizado
nft add rule inet filter input \
  log prefix "FIREWALL-DROP: " level warn

# Registrar y aceptar SSH
nft add rule inet filter input \
  tcp dport 22 log prefix "SSH-ACCESO: " level info accept

Visualiza logs: journalctl -k | grep FIREWALL-DROP o dmesg | grep FIREWALL.


Persistencia: Guardar y Restaurar Reglas

# Guardar el conjunto de reglas actual
nft list ruleset > /etc/nftables.conf

# Cargar reglas desde un archivo
nft -f /etc/nftables.conf

# Habilitar el servicio systemd
systemctl enable --now nftables
systemctl reload nftables

Ejemplo de /etc/nftables.conf

#!/usr/sbin/nft -f
flush ruleset

table inet filter {
    set ssh_confiable {
        type ipv4_addr
        flags interval
        elements = { 192.168.1.0/24, 10.0.0.0/8 }
    }

    chain input {
        type filter hook input priority 0 ; policy drop ;
        iifname "lo" accept
        ct state established,related accept
        ct state invalid drop
        ip saddr @ssh_confiable tcp dport 22 accept
        tcp dport { 80, 443 } accept
        ip protocol icmp accept
        ip6 nexthdr icmpv6 accept
    }

    chain forward {
        type filter hook forward priority 0 ; policy drop ;
    }

    chain output {
        type filter hook output priority 0 ; policy accept ;
    }
}

Ejemplos Prácticos

Servidor Web (Nginx/Apache)

nft add table inet filter
nft add chain inet filter input \
  '{ type filter hook input priority 0 ; policy drop ; }'
nft add rule inet filter input iifname "lo" accept
nft add rule inet filter input ct state established,related accept
nft add rule inet filter input ct state invalid drop
nft add rule inet filter input tcp dport { 22, 80, 443 } accept
nft add rule inet filter input ip protocol icmp accept
nft add rule inet filter input ip6 nexthdr icmpv6 accept

Gateway / Router

# Habilitar reenvío IP
sysctl -w net.ipv4.ip_forward=1

# NAT para tráfico saliente
nft add table ip nat
nft add chain ip nat postrouting \
  '{ type nat hook postrouting priority 100 ; }'
nft add rule ip nat postrouting oifname "eth0" masquerade

# Cadena forward — permitir LAN a WAN, bloquear WAN a LAN
nft add chain inet filter forward \
  '{ type filter hook forward priority 0 ; policy drop ; }'
nft add rule inet filter forward \
  iifname "eth1" oifname "eth0" ct state new,established,related accept
nft add rule inet filter forward \
  iifname "eth0" oifname "eth1" ct state established,related accept

Comparativa: nftables vs iptables vs firewalld vs ufw

Característicanftablesiptablesfirewalldufw
IPv4 + IPv6 unificadoSí (inet)No (herramientas separadas)Sí (vía nftables)Parcial
Actualizaciones atómicasNoNo
Conjuntos / mapasNativosipset (externo)Vía reglas ricasNo
SintaxisModerna, concisaVerbosaXML / CLICLI simple
Rendimiento (reglas grandes)ExcelenteDeficiente (escaneo lineal)BuenoRegular
Integración directa con kernelLegado (obsoleto)FrontendFrontend
Curva de aprendizajeModeradaBaja (familiar)BajaMuy baja

Depuración con nft monitor y Contadores

# Monitorear todos los eventos de netfilter en tiempo real
nft monitor

# Ver valores de contadores
nft list table inet filter

# Resetear contadores sin eliminar reglas
nft reset counters table inet filter

# Verificar sintaxis de un archivo sin cargarlo
nft -c -f /etc/nftables.conf

# Rastrear el camino de un paquete
nft add rule inet filter input meta nftrace set 1
nft monitor trace

Resumen

  • nftables unifica iptables, ip6tables, arptables y ebtables en un solo comando nft.
  • Usa la familia inet para manejar IPv4 e IPv6 en un solo conjunto de reglas.
  • Los conjuntos con nombre y mapas de veredictos reemplazan ipset y patrones complejos de múltiples reglas.
  • El reemplazo atómico de reglas vía nft -f elimina la ventana de actualización parcial que sufre iptables.
  • Persiste las reglas en /etc/nftables.conf y habilita nftables.service con systemd.
  • Usa nft monitor trace y contadores en línea para depurar sin reiniciar.

Artículos Relacionados