Configuración de nftables (Sucesor de iptables): Guía Completa
Introducción
nftables representa la evolución moderna del filtrado de paquetes en Linux, diseñado como sucesor de los venerables frameworks iptables, ip6tables, arptables y ebtables. Introducido en el kernel de Linux 3.13 y alcanzando madurez en años recientes, nftables ofrece un enfoque unificado, simplificado y más poderoso para el filtrado de paquetes y la traducción de direcciones de red. A diferencia de las herramientas legacy fragmentadas que requerían utilidades separadas para filtrado IPv4, IPv6, ARP y bridge, nftables proporciona una única interfaz de línea de comandos (nft) y una sintaxis de conjunto de reglas cohesiva que maneja todos los escenarios de filtrado de paquetes.
nftables aborda muchas limitaciones de iptables mientras mantiene conceptos similares, haciendo la transición manejable para administradores experimentados. Las mejoras clave incluyen mejor rendimiento a través de comunicación reducida kernel-espacio de usuario, sintaxis mejorada con variables y diccionarios, mejor soporte dual-stack IPv4/IPv6, actualizaciones atómicas de conjunto de reglas y un lenguaje de configuración más lógico y legible por humanos. Las principales distribuciones de Linux incluyendo Debian 10+, Ubuntu 20.04+, RHEL 8+ y Rocky Linux 8+ han adoptado nftables como su backend de firewall por defecto.
Esta guía exhaustiva cubre nftables desde conceptos fundamentales hasta configuraciones avanzadas, incluyendo estructura de conjunto de reglas, tipos de familia, organización de tablas y cadenas, implementación NAT, registro, optimización de rendimiento y estrategias de migración desde iptables. Ya sea que estés desplegando nftables en sistemas nuevos o migrando configuraciones iptables existentes, esta guía proporciona el conocimiento necesario para aprovechar este poderoso framework de filtrado de paquetes.
Entendiendo la Arquitectura de nftables
¿Por Qué nftables?
Ventajas sobre iptables:
- Framework unificado - Herramienta única para filtrado IPv4, IPv6, ARP y bridge
- Sintaxis simplificada - Reglas más legibles y mantenibles
- Mejor rendimiento - Comunicación reducida kernel-espacio de usuario
- Actualizaciones atómicas - Todos los cambios de reglas aplicados atómicamente
- Variables incorporadas - Conjuntos, mapas y diccionarios para coincidencia compleja
- Depuración mejorada - Mejores mensajes de error y rastreo
- Base de código más pequeña - Implementación de kernel más mantenible
Componentes de nftables
1. Tablas
- Contenedores para cadenas
- Definidas por familia (ip, ip6, inet, arp, bridge, netdev)
2. Cadenas
- Listas de reglas
- Pueden ser cadenas base (enganchadas a netfilter) o cadenas regulares
3. Reglas
- Criterios de coincidencia y veredicto (accept, drop, reject, etc.)
- Procesadas secuencialmente dentro de cadenas
4. Conjuntos y Mapas
- Colecciones nombradas para coincidencia eficiente
- Diccionarios para mapeo de valores
Tipos de Familia
# ip - Paquetes IPv4
# ip6 - Paquetes IPv6
# inet - Tanto IPv4 como IPv6 (dual-stack)
# arp - Paquetes ARP
# bridge - Tráfico bridge
# netdev - Tráfico ingress (filtrado temprano)
Tipos de Hook
Hooks de cadena base:
ingress - Etapa muy temprana (solo familia netdev)
prerouting - Antes de decisión de enrutamiento
input - Para proceso local
forward - Para paquetes enrutados
output - Desde proceso local
postrouting - Después de decisión de enrutamiento
Prerrequisitos
Antes de configurar nftables, asegúrate de tener:
- Sistema Linux con kernel 3.13+ (4.x+ recomendado)
- Acceso root o sudo
- Paquete nftables instalado
- Comprensión básica de conceptos de filtrado de paquetes
- Conocimiento de tu topología de red
- Acceso SSH o consola (crítico para recuperación)
Instalación
Debian/Ubuntu:
sudo apt update
sudo apt install nftables -y
RHEL/CentOS/Rocky Linux 8+:
sudo dnf install nftables -y
Habilitar servicio nftables:
sudo systemctl enable nftables
sudo systemctl start nftables
Verificar Instalación
# Verificar versión
nft --version
# Listar conjunto de reglas actual
sudo nft list ruleset
# Verificar estado del servicio
sudo systemctl status nftables
Comandos Básicos de nftables
Ver Conjuntos de Reglas
# Listar conjunto de reglas completo
sudo nft list ruleset
# Listar tabla específica
sudo nft list table inet filter
# Listar cadena específica
sudo nft list chain inet filter input
# Listar con handles (para eliminación de reglas)
sudo nft -a list ruleset
Crear Tablas y Cadenas
# Crear tabla
sudo nft add table inet filter
# Crear cadena base
sudo nft add chain inet filter input '{ type filter hook input priority 0; policy accept; }'
# Crear cadena regular
sudo nft add chain inet filter custom_chain
Agregar Reglas
# Agregar regla al final de cadena
sudo nft add rule inet filter input tcp dport 22 accept
# Insertar regla al principio
sudo nft insert rule inet filter input tcp dport 22 accept
# Agregar regla en posición específica
sudo nft insert rule inet filter input position 5 tcp dport 22 accept
Eliminar Reglas
# Eliminar regla por handle
sudo nft delete rule inet filter input handle 5
# Eliminar cadena completa
sudo nft delete chain inet filter input
# Eliminar tabla completa
sudo nft delete table inet filter
# Vaciar todas las reglas en cadena
sudo nft flush chain inet filter input
# Vaciar todas las reglas en tabla
sudo nft flush table inet filter
# Vaciar conjunto de reglas completo
sudo nft flush ruleset
Configuración Básica de Firewall
Ejemplo Simple de Firewall
#!/usr/sbin/nft -f
# Vaciar conjunto de reglas existente
flush ruleset
# Crear tabla inet (maneja tanto IPv4 como IPv6)
table inet filter {
# Cadena input
chain input {
type filter hook input priority 0; policy drop;
# Permitir loopback
iif lo accept
# Permitir conexiones establecidas y relacionadas
ct state established,related accept
# Descartar paquetes inválidos
ct state invalid drop
# Permitir SSH
tcp dport 22 accept
# Permitir HTTP y HTTPS
tcp dport { 80, 443 } accept
# Permitir ping
icmp type echo-request limit rate 1/second accept
icmpv6 type echo-request limit rate 1/second accept
# Registrar paquetes descartados
limit rate 5/minute log prefix "nftables input drop: "
}
# Cadena forward (para routers)
chain forward {
type filter hook forward priority 0; policy drop;
}
# Cadena output
chain output {
type filter hook output priority 0; policy accept;
}
}
Guardar como /etc/nftables.conf y aplicar:
sudo nft -f /etc/nftables.conf
sudo systemctl reload nftables
Configuración de Servidor Web
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Loopback
iif lo accept
# Conexiones establecidas
ct state established,related accept
ct state invalid drop
# SSH desde subred específica
ip saddr 192.168.1.0/24 tcp dport 22 accept
# Servicios web
tcp dport { 80, 443 } accept
# ICMP
ip protocol icmp icmp type { echo-request, echo-reply } limit rate 1/second accept
ip6 nexthdr icmpv6 icmpv6 type { echo-request, echo-reply } limit rate 1/second accept
# Registrar y descartar
limit rate 5/minute log prefix "nftables drop: "
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Características Avanzadas
Conjuntos para Coincidencia Eficiente
Conjuntos nombrados:
# Crear tabla y cadena
nft add table inet filter
nft add chain inet filter input '{ type filter hook input priority 0; policy drop; }'
# Crear conjunto de IPs permitidas
nft add set inet filter allowed_ips '{ type ipv4_addr; }'
# Agregar elementos al conjunto
nft add element inet filter allowed_ips { 192.168.1.10, 192.168.1.20, 192.168.1.30 }
# Usar conjunto en regla
nft add rule inet filter input ip saddr @allowed_ips accept
Conjuntos anónimos en línea:
# Permitir múltiples puertos
nft add rule inet filter input tcp dport { 22, 80, 443, 8080 } accept
# Bloquear múltiples IPs
nft add rule inet filter input ip saddr { 10.0.0.1, 10.0.0.2 } drop
Intervalos en conjuntos:
# Crear conjunto con soporte de intervalo
nft add set inet filter blocked_ranges '{ type ipv4_addr; flags interval; }'
# Agregar rangos de IP
nft add element inet filter blocked_ranges { 192.168.1.1-192.168.1.50, 10.0.0.0/8 }
# Usar en regla
nft add rule inet filter input ip saddr @blocked_ranges drop
Mapas (Diccionarios)
Mapeo de puertos:
# Crear mapa
nft add map inet nat portmap '{ type inet_service : ipv4_addr; }'
# Agregar mapeos de puerto a IP
nft add element inet nat portmap { 80 : 192.168.1.10, 443 : 192.168.1.20 }
# Usar en regla DNAT
nft add rule inet nat prerouting dnat to tcp dport map @portmap
Mapas de veredicto:
# Crear mapa de veredicto
nft add map inet filter ip_actions '{ type ipv4_addr : verdict; }'
# Definir acciones por IP
nft add element inet filter ip_actions { 192.168.1.10 : accept, 192.168.1.20 : drop }
# Usar en regla
nft add rule inet filter input ip saddr vmap @ip_actions
Variables
#!/usr/sbin/nft -f
# Definir variables
define WAN_IF = eth0
define LAN_IF = eth1
define SSH_PORT = 22
define WEB_PORTS = { 80, 443 }
define TRUSTED_IPS = { 192.168.1.10, 192.168.1.20 }
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# Usar variables
iif $LAN_IF accept
iif $WAN_IF ip saddr $TRUSTED_IPS tcp dport $SSH_PORT accept
tcp dport $WEB_PORTS accept
}
}
Concatenaciones
# Coincidir combinación de IP y puerto de origen
nft add rule inet filter input ip saddr . tcp sport { 192.168.1.10 . 1234, 192.168.1.20 . 5678 } accept
# Usar en conjunto
nft add set inet filter ssh_access '{ type ipv4_addr . inet_service; }'
nft add element inet filter ssh_access { 192.168.1.10 . 22, 192.168.1.20 . 22 }
nft add rule inet filter input ip saddr . tcp dport @ssh_access accept
Traducción de Direcciones de Red (NAT)
Enmascaramiento (SNAT)
#!/usr/sbin/nft -f
flush ruleset
table inet nat {
chain postrouting {
type nat hook postrouting priority 100; policy accept;
# Enmascarar tráfico saliente en interfaz WAN
oif eth0 masquerade
}
}
table inet filter {
chain forward {
type filter hook forward priority 0; policy drop;
# Permitir reenvío desde LAN a WAN
iif eth1 oif eth0 accept
# Permitir conexiones establecidas de vuelta
ct state established,related accept
}
}
Habilitar reenvío IP:
sudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
NAT de Origen Estático
table inet nat {
chain postrouting {
type nat hook postrouting priority 100; policy accept;
# SNAT tráfico saliente a IP específica
oif eth0 snat to 203.0.113.50
}
}
NAT de Destino (Reenvío de Puertos)
table inet nat {
chain prerouting {
type nat hook prerouting priority -100; policy accept;
# Reenviar puerto 80 a servidor interno
iif eth0 tcp dport 80 dnat to 192.168.1.100:80
# Reenviar puerto 443 a servidor interno
iif eth0 tcp dport 443 dnat to 192.168.1.100:443
# Reenviar SSH en puerto no estándar
iif eth0 tcp dport 2222 dnat to 192.168.1.10:22
}
}
table inet filter {
chain forward {
type filter hook forward priority 0; policy drop;
# Permitir conexiones reenviadas
ct state established,related accept
iif eth0 oif eth1 tcp dport { 80, 443 } accept
iif eth0 oif eth1 ip daddr 192.168.1.10 tcp dport 22 accept
}
}
Balanceo de Carga con NAT
table inet nat {
chain prerouting {
type nat hook prerouting priority -100; policy accept;
# Balanceo de carga round-robin
tcp dport 80 dnat to numgen inc mod 3 map { \
0 : 192.168.1.10, \
1 : 192.168.1.11, \
2 : 192.168.1.12 \
}
}
}
Registro y Monitoreo
Registro Básico
# Registrar paquetes descartados
nft add rule inet filter input limit rate 5/minute log prefix "nftables drop: " drop
# Registrar acceso a servicio específico
nft add rule inet filter input tcp dport 22 log prefix "SSH access: " accept
# Registrar con nivel de log
nft add rule inet filter input log prefix "INPUT: " level info
Registro Avanzado
table inet filter {
# Cadena de registro
chain log_and_drop {
limit rate 5/minute log prefix "nftables denied: " level warning
drop
}
chain input {
type filter hook input priority 0; policy drop;
# ... reglas de aceptación ...
# Saltar a cadena de registro para todo lo demás
jump log_and_drop
}
}
Monitoreo de Rastreo de Conexión
# Ver tabla conntrack
sudo conntrack -L
# Estadísticas
sudo conntrack -S
# Ver conexiones en tiempo real
sudo conntrack -E
Ver Estadísticas de nftables
# Mostrar contadores de reglas
sudo nft list ruleset -a
# Monitorear cadena específica
watch -n 1 'sudo nft list chain inet filter input'
Endurecimiento de Seguridad
Firewall Endurecido Completo
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
# Conjuntos para organización
set allowed_ssh_ips {
type ipv4_addr
flags interval
elements = { 192.168.1.0/24, 10.0.0.100 }
}
set blocked_ips {
type ipv4_addr
flags interval
}
# Cadena de limitación de velocidad
chain ssh_ratelimit {
# Permitir 3 conexiones por minuto por IP
ct state new limit rate over 3/minute drop
accept
}
# Cadena input
chain input {
type filter hook input priority 0; policy drop;
# Loopback
iif lo accept
# IPs bloqueadas
ip saddr @blocked_ips drop
# Rastreo de conexión
ct state invalid drop
ct state established,related accept
# Anti-spoofing (ajustar para tu red)
iif eth0 ip saddr { 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16 } drop
# SSH con limitación de velocidad desde IPs confiables
ip saddr @allowed_ssh_ips tcp dport 22 jump ssh_ratelimit
# Servicios web
tcp dport { 80, 443 } ct state new accept
# Limitación de velocidad ICMP
ip protocol icmp icmp type echo-request limit rate 1/second accept
ip6 nexthdr icmpv6 icmpv6 type echo-request limit rate 1/second accept
# Detección de escaneo de puertos
tcp flags & (fin|syn|rst|psh|ack|urg) == fin|syn log prefix "Port scan SYN-FIN: " drop
tcp flags & (fin|syn|rst|psh|ack|urg) == 0 log prefix "Port scan NULL: " drop
tcp flags & (fin|syn|rst|psh|ack|urg) == fin|psh|urg log prefix "Port scan XMAS: " drop
# Registrar descartes restantes
limit rate 5/minute log prefix "nftables input drop: " level warning
}
chain forward {
type filter hook forward priority 0; policy drop;
ct state established,related accept
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Protección DDoS
table inet filter {
# Protección contra inundación SYN
chain input {
type filter hook input priority 0; policy drop;
# Limitar nuevas conexiones TCP
tcp flags syn tcp dport { 80, 443 } limit rate over 25/second drop
# Continuar con otras reglas
# ...
}
}
Migración desde iptables
Traducción Automática
# Traducir reglas iptables a nftables
sudo iptables-save > /tmp/iptables.rules
sudo iptables-restore-translate -f /tmp/iptables.rules > /tmp/nftables.nft
# Revisar reglas traducidas
cat /tmp/nftables.nft
# Aplicar si es satisfactorio
sudo nft -f /tmp/nftables.nft
Comparación Lado a Lado
iptables:
iptables -A INPUT -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A INPUT -s 192.168.1.0/24 -j ACCEPT
nftables:
nft add rule inet filter input tcp dport 22 accept
nft add rule inet filter input ct state established,related accept
nft add rule inet filter input ip saddr 192.168.1.0/24 accept
Coexistencia
nftables e iptables pueden coexistir, pero no se recomienda a largo plazo:
# Deshabilitar backend iptables si se usa nftables
sudo systemctl disable iptables
sudo systemctl disable ip6tables
# Habilitar nftables
sudo systemctl enable nftables
Gestión de Configuración
Estructura de Archivo de Configuración
Archivo de configuración principal: /etc/nftables.conf
#!/usr/sbin/nft -f
# Incluir otros archivos
include "/etc/nftables.d/*.nft"
flush ruleset
# Configuración principal
table inet filter {
# ...
}
Organización modular:
# /etc/nftables.d/00-defines.nft
define WAN_IF = eth0
define LAN_IF = eth1
define SSH_PORT = 22
# /etc/nftables.d/10-filter-table.nft
table inet filter {
# ...
}
# /etc/nftables.d/20-nat-table.nft
table inet nat {
# ...
}
Actualizaciones Atómicas de Reglas
# Guardar conjunto de reglas actual
sudo nft list ruleset > /tmp/ruleset-backup.nft
# Probar nueva configuración
sudo nft -c -f /etc/nftables.conf
# Aplicar atómicamente
sudo nft -f /etc/nftables.conf
# Revertir si es necesario
sudo nft -f /tmp/ruleset-backup.nft
Backup y Restauración
#!/bin/bash
# backup-nftables.sh
BACKUP_DIR="/root/nftables-backups"
mkdir -p $BACKUP_DIR
# Guardar conjunto de reglas actual
nft list ruleset > $BACKUP_DIR/nftables-$(date +%Y%m%d-%H%M%S).nft
# Mantener solo últimos 30 días
find $BACKUP_DIR -name "nftables-*.nft" -mtime +30 -delete
echo "Backup de nftables completado"
Resolución de Problemas
Problemas Comunes
Reglas no se cargan:
# Verificar sintaxis
sudo nft -c -f /etc/nftables.conf
# Ver errores detallados
sudo nft -f /etc/nftables.conf 2>&1
Bloqueado por SSH:
# Prevención: Probar con timeout
#!/bin/bash
nft -f /etc/nftables.conf
sleep 60
nft flush ruleset
# Si SSH funciona dentro de 60 segundos, Ctrl+C y guardar permanentemente
Problemas de rendimiento:
# Verificar tamaño de tabla conntrack
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_max
# Aumentar si es necesario
sudo sysctl -w net.netfilter.nf_conntrack_max=262144
Depuración
Habilitar rastreo:
# Agregar regla de rastreo
sudo nft add rule inet filter input tcp dport 80 meta nftrace set 1
# Monitorear rastreo
sudo nft monitor trace
Verificar coincidencia de reglas:
# Ver contadores de reglas
sudo nft list chain inet filter input
# Resetear contadores
sudo nft reset counters inet filter input
Mejores Prácticas
1. Usar Familia inet para Dual-Stack
# En lugar de tablas ip e ip6 separadas
table inet filter {
# Maneja tanto IPv4 como IPv6
}
2. Organizar con Conjuntos y Mapas
# Mejor que muchas reglas individuales
set web_servers {
type ipv4_addr
elements = { 192.168.1.10, 192.168.1.11, 192.168.1.12 }
}
3. Usar Variables para Mantenibilidad
define ADMIN_IPS = { 192.168.1.5, 10.0.0.100 }
define SSH_PORT = 22
# Usar en toda la configuración
ip saddr $ADMIN_IPS tcp dport $SSH_PORT accept
4. Implementar Registro Estratégicamente
# Registrar solo lo necesario, con limitación de velocidad
limit rate 5/minute log prefix "Blocked: "
5. Probar Antes de Producción
# Validar sintaxis
nft -c -f /etc/nftables.conf
# Probar en entorno de staging
# Usar timeout rollback para producción
6. Documentar Tus Reglas
# Usar comentarios
nft add rule inet filter input tcp dport 22 accept comment "SSH access"
# Mantener documentación externa
Conclusión
nftables representa el futuro del filtrado de paquetes en Linux, ofreciendo mejoras significativas sobre iptables en rendimiento, claridad de sintaxis y riqueza de características. Su framework unificado, potentes capacidades de conjuntos y mapas, y actualizaciones atómicas lo hacen ideal para infraestructura moderna que va desde servidores únicos hasta redes empresariales complejas.
Puntos clave:
- El framework unificado maneja filtrado IPv4, IPv6 y bridge en una herramienta
- La sintaxis simplificada mejora legibilidad y mantenibilidad
- Los conjuntos y mapas permiten coincidencia de reglas eficiente y escalable
- La familia inet simplifica configuraciones dual-stack
- Las actualizaciones atómicas aseguran aplicación consistente de reglas
- Mejor rendimiento a través de comunicación optimizada del kernel
- Las herramientas de migración facilitan la transición desde iptables
A medida que las distribuciones de Linux continúan adoptando nftables como framework de firewall por defecto, dominar sus capacidades se vuelve esencial para administradores de sistemas y profesionales de seguridad. Ya sea desplegando nuevos sistemas o migrando desde iptables, la flexibilidad y poder de nftables proporcionan filtrado de paquetes robusto para requisitos de seguridad de red contemporáneos.
Para escenarios avanzados, explora integración con fail2ban para bloqueo dinámico, automatización con Ansible para despliegue a escala de infraestructura, y la familia netdev de nftables para filtrado ingress de alto rendimiento.


