Saltar al contenido

iptables y nftables: el firewall de Linux explicado desde cero

    iptables y nftables:

    el firewall de Linux explicado desde cero

    Linux y sistemas  |  unfantasmaenelsistema.com

    En Linux el firewall no es un programa que instalas ni un servicio que arrancas: es una parte del propio kernel. Ese subsistema se llama netfilter, y lleva décadas filtrando, redirigiendo y contando paquetes en prácticamente todos los servidores, routers domésticos y contenedores del planeta. Lo que cambia con el tiempo es la herramienta con la que le hablas: primero fue `iptables`, hoy es `nft` (nftables), y por encima de ambas viven frontends más amigables como `ufw` o `firewalld`.

    Este artículo recorre el modelo mental completo —tablas, cadenas, reglas y estados— con ejemplos comentados en las dos sintaxis, para que entiendas qué hace cada línea y no te limites a copiar reglas de un foro. Al final tendrás un ruleset de ejemplo que puedes adaptar a tu servidor y saber cómo hacerlo persistente tras un reinicio.

    Qué aprenderás en este artículo

    Qué es netfilter y por qué iptables y nftables son solo interfaces hacia él · El modelo de tablas, cadenas y reglas, y el recorrido de un paquete · Por qué la política por defecto debe ser DROP y cómo no dejarte fuera por SSH · Seguimiento de conexiones (conntrack) y estados NEW / ESTABLISHED / RELATED · NAT básico: enmascaramiento y redirección de puertos · Migrar de iptables a nftables y dejar el ruleset persistente

    1. netfilter: el firewall vive en el kernel

    netfilter es un conjunto de hooks (puntos de enganche) repartidos por la ruta que sigue un paquete dentro del kernel. Cuando un paquete entra por la tarjeta de red, cuando el sistema decide si es para él o hay que reenviarlo, y cuando sale hacia la red, pasa por uno de esos hooks. Ahí es donde se evalúan tus reglas.

    `iptables` y `nft` son herramientas de espacio de usuario que traducen tus órdenes a estructuras que netfilter entiende. No son «el firewall»: son el teclado con el que lo configuras. Desde el kernel 3.13 (2014) existe nftables, que sustituye internamente a la familia clásica (`iptables`, `ip6tables`, `arptables`, `ebtables`) por un único motor con una sintaxis unificada. En las distros modernas —Debian 11+, RHEL 8+, Ubuntu 20.04+— el comando `iptables` que escribes suele ser en realidad `iptables-nft`, una capa de compatibilidad que habla con el motor nuevo.

    Comprueba qué estás usando

    `iptables –version` muestra `(nf_tables)` o `(legacy)` según el backend activo · `update-alternatives –config iptables` en Debian/Ubuntu permite cambiar entre uno y otro · Regla práctica: no mezcles reglas creadas con el backend legacy y con nft en el mismo sistema

    2. El modelo: tablas, cadenas y reglas

    La jerarquía es siempre la misma en ambas herramientas. Una tabla agrupa cadenas con un propósito común. Una cadena es una lista ordenada de reglas enganchada a un hook de netfilter. Una regla es una condición («si el paquete cumple X») más una acción o *target* («haz Y»).

    2.1 Las tablas clásicas de iptables

    TablaPara qué sirve
    filterFiltrado puro: aceptar o descartar paquetes. Es la tabla por defecto
    natTraducción de direcciones: enmascaramiento, redirección de puertos
    mangleModificación de campos de la cabecera (TTL, TOS, marcado de paquetes)
    rawExención del seguimiento de conexiones (NOTRACK), se evalúa muy pronto

    En nftables no hay tablas predefinidas: las creas tú y les das el nombre y la familia que quieras (`ip`, `ip6`, `inet` para ambas a la vez, `arp`, `bridge`, `netdev`). La familia `inet` es la recomendada hoy porque una sola tabla cubre IPv4 e IPv6.

    2.2 Las cadenas y el recorrido de un paquete

    • PREROUTING: nada más llegar el paquete, antes de decidir su destino. Aquí se hace el DNAT
    • INPUT: paquetes cuyo destino es la propia máquina
    • FORWARD: paquetes que la máquina enruta hacia otro host (routers, gateways, contenedores)
    • OUTPUT: paquetes generados localmente que salen hacia la red
    • POSTROUTING: justo antes de que el paquete abandone la máquina. Aquí se hace el SNAT / MASQUERADE

    Un paquete dirigido a tu servidor recorre `PREROUTING -> INPUT`. Uno que solo pasa a través (reenvío) recorre `PREROUTING -> FORWARD -> POSTROUTING`. Uno que tu servidor origina recorre `OUTPUT -> POSTROUTING`. Tener claro este mapa es lo que evita el error clásico de poner una regla en la cadena equivocada y que «no haga nada».

    2.3 Targets más habituales en la tabla filter

    TargetEfecto
    ACCEPTDeja pasar el paquete
    DROPDescarta el paquete en silencio, sin responder nada al origen
    REJECTDescarta pero avisa al origen (ICMP port-unreachable o TCP RST)
    LOGEscribe una línea en el log del kernel y sigue evaluando reglas
    RETURNSale de la cadena actual y vuelve a la que la llamó

    3. Política por defecto DROP: denegar salvo lo permitido

    Un firewall serio funciona en modo lista blanca: la política por defecto de la cadena es DROP y solo se abren explícitamente los servicios que hacen falta. Lo contrario —política ACCEPT y bloquear casos concretos— es un colador: cualquier servicio nuevo queda expuesto sin que te enteres.

    No te cierres el acceso remoto

    Si administras el servidor por SSH y pones la política INPUT a DROP antes de permitir tu propio puerto SSH, pierdes la sesión y no puedes volver a entrar · Orden correcto: primero la regla que permite ESTABLISHED,RELATED y tu SSH; luego, y solo luego, cambias la política a DROP · Red de seguridad: lanza `sleep 900 && iptables -P INPUT ACCEPT` en segundo plano, o usa `iptables-apply`, que revierte los cambios si no confirmas en 10 segundos

    3.1 Ruleset mínimo en iptables

    # Empezar de cero
    iptables -F
     
    # Permitir el trafico de loopback (procesos locales que hablan entre si)
    iptables -A INPUT  -i lo -j ACCEPT
     
    # Permitir respuestas a conexiones que YO he iniciado, y su trafico relacionado
    iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
     
    # Descartar paquetes en estado invalido (no encajan en ninguna conexion)
    iptables -A INPUT -m conntrack --ctstate INVALID -j DROP
     
    # Abrir SSH, HTTP y HTTPS (paquetes NEW hacia esos puertos)
    iptables -A INPUT -p tcp --dport 22  -m conntrack --ctstate NEW -j ACCEPT
    iptables -A INPUT -p tcp --dport 80  -m conntrack --ctstate NEW -j ACCEPT
    iptables -A INPUT -p tcp --dport 443 -m conntrack --ctstate NEW -j ACCEPT
     
    # Permitir ping
    iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT
     
    # Ahora si: denegar todo lo demas que llegue a esta maquina
    iptables -P INPUT DROP
    iptables -P FORWARD DROP
    iptables -P OUTPUT ACCEPT

    3.2 El mismo ruleset en nftables

    #!/usr/sbin/nft -f
    flush ruleset
     
    table inet firewall {
      chain input {
        type filter hook input priority 0; policy drop;
     
        iif lo accept
        ct state established,related accept
        ct state invalid drop
     
        tcp dport { 22, 80, 443 } ct state new accept
        ip protocol icmp icmp type echo-request 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; }
    }

    Se nota de un vistazo por qué nftables es el futuro: conjuntos entre llaves (`{ 22, 80, 443 }`) en vez de una regla por puerto, IPv4 e IPv6 en la misma tabla `inet`, y un fichero declarativo que se carga entero con `nft -f` en lugar de una ristra de comandos imperativos.

    4. conntrack: el firewall con memoria

    El seguimiento de conexiones (connection tracking o conntrack) es lo que convierte a netfilter en un firewall *stateful*. El kernel mantiene una tabla de todas las conexiones activas y clasifica cada paquete según su relación con ellas.

    EstadoSignificado
    NEWPrimer paquete de una conexión que aún no existe en la tabla de conntrack
    ESTABLISHEDPertenece a una conexión ya vista en ambos sentidos
    RELATEDConexión nueva pero derivada de una existente (p. ej. datos de FTP, errores ICMP)
    INVALIDNo se puede asociar a ninguna conexión conocida; casi siempre se descarta
    UNTRACKEDMarcado explícitamente para no seguirse (tabla raw, NOTRACK)

    La consecuencia práctica es enorme: solo necesitas una regla para permitir todo el tráfico de vuelta de las conexiones que tus usuarios o servicios inician (`ESTABLISHED,RELATED accept`), y a partir de ahí solo abres los puertos donde aceptas conexiones entrantes `NEW`. Puedes inspeccionar la tabla en vivo con `conntrack -L` o `cat /proc/net/nf_conntrack`.

    5. NAT básico: compartir conexión y redirigir puertos

    5.1 Enmascaramiento (SNAT dinámico)

    Es lo que hace un router: varias máquinas de una red interna salen a internet con la única IP pública del gateway. Requiere activar el reenvío de paquetes en el kernel (`sysctl -w net.ipv4.ip_forward=1`, y persistente en `/etc/sysctl.d/`).

    # iptables: enmascarar todo lo que salga por la interfaz externa eth0
    iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
    iptables -A FORWARD -i eth1 -o eth0 -j ACCEPT
    iptables -A FORWARD -i eth0 -o eth1 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
     
    # nftables equivalente
    # chain postrouting { type nat hook postrouting priority 100; oifname "eth0" masquerade; }

    5.2 Redirección de puertos (DNAT)

    Publicar un servicio interno hacia fuera: el tráfico que llega al puerto 443 de la IP pública se reenvía a un servidor web en la red interna.

    iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 443 \
             -j DNAT --to-destination 192.168.56.20:443
    iptables -A FORWARD -p tcp -d 192.168.56.20 --dport 443 \
             -m conntrack --ctstate NEW -j ACCEPT

    El orden de las reglas importa, y mucho

    netfilter evalúa las cadenas de arriba abajo y ejecuta la PRIMERA regla que hace match · Una regla `ACCEPT` amplia colocada antes que un `DROP` específico anula el bloqueo · `iptables -L -v –line-numbers` numera las reglas; usa `-I cadena N` para insertar en una posición concreta en vez de `-A`, que siempre añade al final

    6. Persistencia: que las reglas sobrevivan al reinicio

    Las reglas viven en memoria. Si no las guardas, un reinicio te deja el sistema sin firewall (o peor, con la política DROP y sin reglas, aislado de la red).

    HerramientaCómo se hace persistente
    iptables (Debian/Ubuntu)Paquete `iptables-persistent`; guarda en `/etc/iptables/rules.v4` y `rules.v6` con `netfilter-persistent save`
    iptables (RHEL/CentOS)`service iptables save` -> `/etc/sysconfig/iptables`
    nftablesEditar `/etc/nftables.conf` y habilitar el servicio: `systemctl enable –now nftables`
    ufw / firewalldGuardan su configuración automáticamente; se recarga con `ufw reload` o `firewall-cmd –reload`

    6.1 Frontends: ufw y firewalld

    No todo el mundo necesita escribir reglas a mano. ufw (Uncomplicated Firewall, por defecto en Ubuntu) traduce órdenes como `ufw allow 22/tcp` a reglas de netfilter. firewalld (Fedora, RHEL) añade el concepto de zonas (`public`, `home`, `trusted`) y recarga en caliente sin cortar las conexiones activas. Ambos son perfectamente válidos para un servidor típico; bajar a iptables/nft directo tiene sentido cuando necesitas reglas que el frontend no expone (marcado de paquetes, NAT complejo, rate limiting fino).

    7. Migrar de iptables a nftables

    • `iptables-translate ‘iptables -A INPUT -p tcp –dport 22 -j ACCEPT’` convierte una regla suelta a sintaxis nft sin aplicarla, útil para aprender la equivalencia
    • `iptables-save > reglas.txt` y luego `iptables-restore-translate -f reglas.txt` migra un ruleset completo a un fichero nft
    • Revisa siempre el resultado a mano: la traducción automática es literal y no aprovecha conjuntos, mapas ni la familia `inet`, que son la razón de migrar
    • No cargues reglas legacy y nft a la vez: elige un backend, migra del todo y desinstala el otro para evitar comportamientos difíciles de depurar

    Comandos de diagnóstico que conviene memorizar

    `nft list ruleset` — vuelca toda la configuración activa de nftables · `iptables -L -v -n –line-numbers` — reglas de filter con contadores de paquetes/bytes · `iptables -t nat -L -v -n` — no olvides el `-t nat`, `-L` a secas solo muestra filter · `nft monitor` — muestra en tiempo real los cambios en el ruleset · Añade una regla `LOG` temporal justo antes de un `DROP` para ver qué se está descartando

    Conclusión

    El firewall de Linux intimida porque su documentación suele empezar por la sintaxis en lugar de por el modelo. Pero el modelo es corto: netfilter engancha puntos en la ruta del paquete, las cadenas cuelgan de esos puntos, las reglas se evalúan en orden, y conntrack le da memoria para distinguir una conexión nueva de la respuesta a una que ya autorizaste. Con eso claro, `iptables` y `nft` son solo dos dialectos para decir lo mismo.

    Si montas un servidor nuevo hoy, empieza directamente en nftables —o en su frontend firewalld/ufw— con política `drop` y abre solo lo imprescindible. Y antes de tocar la política de INPUT en una máquina remota, ten siempre preparada la red de seguridad que revierte los cambios: el error más caro con un firewall no es dejar un puerto abierto, es cerrarte a ti mismo la puerta.

    Referencias

    netfilter.org — Documentación oficial de netfilter, iptables y nftables · wiki.nftables.org — Guía de referencia y recetario de nftables · Arch Wiki: nftables / iptables — De las explicaciones prácticas más claras que hay · man 8 nft, man 8 iptables — La página de manual sigue siendo la fuente definitiva

    unfantasmaenelsistema.com | Seguridad, sistemas y todo lo que no debería funcionar (pero funciona)

    Resumen de privacidad

    Esta web utiliza cookies para que podamos ofrecerte la mejor experiencia de usuario posible. La información de las cookies se almacena en tu navegador y realiza funciones tales como reconocerte cuando vuelves a nuestra web o ayudar a nuestro equipo a comprender qué secciones de la web encuentras más interesantes y útiles.