Guía de firewall para servidores Linux: nftables, ufw y firewalld sin quedarse fuera
Configure un firewall de denegación predeterminada en Debian, Ubuntu y RHEL con nftables, ufw o firewalld, mantenga el acceso SSH, gestione IPv6 y Docker, y pruébelo desde fuera.
Un servidor Linux de empresa debe bloquear de forma predeterminada todas las conexiones entrantes y permitir solo los servicios que realmente ofrece, por ejemplo SSH desde su oficina y HTTPS para todo el mundo. En Debian puede escribir esa política directamente en nftables; en Ubuntu la herramienta habitual es ufw; en Red Hat Enterprise Linux y AlmaLinux es firewalld. Las tres terminan como reglas de nftables en el kernel. Los dos errores clásicos son quedarse sin acceso SSH al activar el firewall y suponer que el firewall protege los puertos que publicó Docker, cosa que muchas veces no ocurre. Esta guía cubre la denegación predeterminada con cada herramienta, cómo activarla sin riesgos, la limitación de conexiones, IPv6, Docker y cómo probar el resultado.
Primero la política, después la herramienta
Antes de escribir un comando, anote tres listas:
- Servicios públicos: lo que internet debe alcanzar (a menudo solo TCP 80 y 443).
- Servicios restringidos: lo que solo su oficina, su VPN o su red de administración deben alcanzar (SSH, paneles de administración, bases de datos, monitoreo).
- Todo lo demás: denegado.
Compruebe lo que realmente está escuchando con sudo ss -tulpn. Todo lo que escuche y no esté en sus listas debe detenerse o limitarse a 127.0.0.1, no solo bloquearse en el firewall. Use un solo gestor de firewall por servidor: no mezcle ufw, firewalld y un conjunto de reglas de nftables escrito a mano en la misma máquina. Esto encaja en la lista más amplia de nuestra guía de fundamentos para proteger servidores Linux.
No se quede fuera
Basta un error en el firewall para cortar su sesión SSH, así que prepárese:
- Tenga una segunda vía de acceso: la consola web de su proveedor de hosting, IPMI/iDRAC/iLO o alguien en el sitio.
- Permita SSH antes de activar una política de denegación predeterminada, y permita las conexiones establecidas para que su sesión actual sobreviva.
- Mantenga abierta la sesión actual y pruebe con una conexión SSH nueva antes de cerrar.
- Programe una reversión automática mientras prueba un nuevo conjunto de reglas de nftables:
sudo systemd-run --unit=fw-rollback --on-active=5m /usr/sbin/nft delete table inet filter
Aplique y pruebe las reglas nuevas, y luego cancele la reversión:
sudo systemctl stop fw-rollback.timer
firewalld trae esto incorporado: las reglas en tiempo de ejecución pueden caducar con --timeout=5m, y los cambios hechos sin --permanent desaparecen en la siguiente recarga o reinicio.
nftables en Debian 12 y 13
Debian usa nftables como su marco de firewall. Instálelo y active el servicio que carga /etc/nftables.conf al arrancar:
sudo apt install nftables
sudo systemctl enable nftables
Este es un ejemplo de denegación predeterminada para un servidor web. Reemplace las direcciones de ejemplo por las de su oficina o su VPN.
#!/usr/sbin/nft -f
table inet filter
delete table inet filter
table inet filter {
set ssh_allow_v4 {
type ipv4_addr; flags interval;
elements = { 203.0.113.10, 198.51.100.0/24 }
}
set ssh_allow_v6 {
type ipv6_addr; flags interval;
elements = { 2001:db8:10::/48 }
}
set ssh_rate_v4 {
type ipv4_addr; flags dynamic; timeout 1m; size 65536;
}
chain input {
type filter hook input priority filter; policy drop;
ct state vmap { established : accept, related : accept, invalid : drop }
iif "lo" accept
# ICMP para descubrir la MTU de la ruta y para diagnóstico
ip protocol icmp icmp type { echo-request, destination-unreachable, time-exceeded, parameter-problem } accept
# ICMPv6 es imprescindible para que IPv6 funcione (descubrimiento de vecinos)
icmpv6 type { echo-request, destination-unreachable, packet-too-big, time-exceeded, parameter-problem, nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept
# SSH: máximo 10 conexiones nuevas por minuto por dirección IPv4, solo desde redes permitidas
tcp dport 22 ct state new add @ssh_rate_v4 { ip saddr limit rate over 10/minute } drop
tcp dport 22 ip saddr @ssh_allow_v4 accept
tcp dport 22 ip6 saddr @ssh_allow_v6 accept
# Servicios web públicos (IPv4 e IPv6)
tcp dport { 80, 443 } accept
# Registrar una muestra de los paquetes descartados
limit rate 5/minute log prefix "nft-drop: " level info
}
chain forward {
type filter hook forward priority filter; policy drop;
}
}
Algunas notas sobre estas reglas:
- Las dos primeras líneas reinician solo esta tabla, sin tocar las tablas de Docker ni de otras herramientas, así que el archivo se puede recargar sin riesgo.
- La familia
inetcubre IPv4 e IPv6 en una sola tabla, así que no puede olvidarse de IPv6. Nunca bloquee todo ICMPv6: IPv6 deja de funcionar sin el descubrimiento de vecinos. - La línea
ct stateacepta las respuestas al tráfico que inició el servidor y mantiene vivas las sesiones existentes. - El límite de conexiones usa un conjunto dinámico, como describe el manual
nft(8), para que una sola dirección ruidosa no inunde SSH. - La cadena
forwarddescarta el tráfico enrutado. En un servidor con Docker, KVM o Proxmox, elimínela o adáptela, porque una política de descarte aquí también descarta el tráfico hacia contenedores y máquinas virtuales.
Compruebe la sintaxis y luego cárguela con el temporizador de reversión activo:
sudo nft -c -f /etc/nftables.conf
sudo nft -f /etc/nftables.conf
sudo nft list ruleset
Como el archivo lo carga nftables.service, las reglas se mantienen tras reiniciar una vez que el servicio está activado.

ufw en Ubuntu 24.04
ufw ("uncomplicated firewall") viene con Ubuntu y está inactivo hasta que usted lo activa. Defina los valores predeterminados y permita SSH antes de activarlo:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow proto tcp from 203.0.113.10 to any port 22
sudo ufw allow proto tcp from any to any port 80,443
sudo ufw enable
sudo ufw status verbose
Si SSH debe seguir accesible desde cualquier lugar, use la limitación de ufw en lugar de la regla restringida por origen. Según el manual de ufw, deniega a una dirección que abre 6 o más conexiones en 30 segundos:
sudo ufw limit 22/tcp
- IPv6: ufw gestiona IPv6 de forma predeterminada (
IPV6=yesen/etc/default/ufw), y las reglas que agregue se aplican a ambos protocolos. - Persistencia: las reglas de ufw y su estado activado se mantienen tras reiniciar automáticamente.
- Revisión:
sudo ufw show addedlista las reglas tal como las escribió;sudo ufw status numberedlas muestra numeradas para usarsudo ufw delete <n>. - El manual de ufw advierte que activarlo puede cortar conexiones existentes, y pide confirmación cuando se hace por SSH. Es la señal para revisar dos veces la regla de SSH.
firewalld en RHEL y AlmaLinux 9 y 10
firewalld viene instalado y en ejecución de forma predeterminada en las instalaciones estándar (algunas imágenes mínimas para la nube no lo incluyen). Agrupa las reglas en zonas; las interfaces pertenecen a la zona predeterminada, normalmente public, salvo que se asignen a otra. Empiece por ver qué está abierto:
sudo firewall-cmd --get-default-zone
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --list-all
En una instalación nueva, la zona public suele permitir ssh, dhcpv6-client y cockpit. Abra solo lo que necesita y quite lo demás:
sudo firewall-cmd --permanent --add-service=http --add-service=https
sudo firewall-cmd --permanent --remove-service=cockpit
sudo firewall-cmd --reload
Para restringir SSH a su oficina, agregue una regla enriquecida (rich rule), recargue, pruebe una sesión SSH nueva desde la oficina y solo entonces quite el servicio general ssh:
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="203.0.113.10" service name="ssh" accept limit value="10/m"'
sudo firewall-cmd --reload
Cuando una conexión SSH nueva desde 203.0.113.10 funcione:
sudo firewall-cmd --permanent --remove-service=ssh
sudo firewall-cmd --reload
- Los cambios sin
--permanentse aplican de inmediato pero se pierden al recargar; los cambios con--permanentse aplican después de--reload. Cuando esté conforme con las reglas en tiempo de ejecución,sudo firewall-cmd --runtime-to-permanentlas guarda. - Los servicios y puertos de una zona se aplican a IPv4 e IPv6. Las reglas enriquecidas con
family="ipv4"solo coinciden con IPv4, así que agregue una regla equivalente confamily="ipv6"si administra el servidor por IPv6. - No active
nftables.servicecon sus propias reglas junto a firewalld.
La advertencia sobre Docker
La documentación de Docker es explícita: los puertos publicados de los contenedores son accesibles desde fuera de forma predeterminada, y con ufw el tráfico se desvía antes de que se apliquen las reglas de ufw, así que ufw deny no protege un puerto publicado con -p. Con firewalld, Docker crea su propia zona docker con destino ACCEPT. En la práctica:
- Limite a localhost cuando un contenedor está detrás de un proxy inverso en el mismo servidor:
-p 127.0.0.1:8080:80(o"127.0.0.1:8080:80"en Compose). - Filtre en la cadena
DOCKER-USER, que Docker procesa antes que sus propias reglas, por ejemplo para permitir solo una dirección de origen:sudo iptables -I DOCKER-USER -i eth0 ! -s 192.0.2.2 -j DROP(reemplaceeth0por su interfaz externa). - No borre las tablas de Docker: un conjunto de reglas que empieza con
flush rulesettambién elimina las reglas de Docker. Reiniciar solo su propia tabla, como en el ejemplo anterior, lo evita.
Pruebe desde fuera
Un firewall solo queda verificado cuando lo escanea desde otro lugar, como otro servidor o un equipo de la oficina desde el que esté autorizado a hacer pruebas:
nmap -Pn -p 1-1024,3306,5432,8080 server.example.com
nmap -6 -Pn -p 22,80,443 server.example.com
Espere ver open solo en los servicios de su lista pública y filtered en todo lo demás. Repita el escaneo después de cada cambio, después de instalar software nuevo y de forma periódica, y guarde el resultado con sus registros de cambios.
Si quiere una segunda opinión sobre los firewalls de sus servidores, o ayuda para proteger servidores con Docker de forma segura, solicite una evaluación de TI gratuita. Core Florida IT configura y monitorea servidores empresariales para compañías de Miami-Dade y todo el sur de Florida con nuestros servicios de ciberseguridad y servidores en la nube y dedicados.


