Configurar ufw en Linux: firewall en el servidor y nociones de nftables
Configurar ufw se reduce a tres pasos: definir las políticas por defecto (sudo ufw default deny incoming y allow outgoing), permitir SSH y los puertos necesarios (sudo ufw allow 22/tcp, sudo ufw allow 443/tcp) y activar el firewall con sudo ufw enable. Las reglas se revisan con sudo ufw status numbered; por debajo, ufw gestiona netfilter mediante iptables o nftables.
El firewall de Linux decide qué paquetes de red dejar pasar hacia el servidor y cuáles descartar. El propio kernel lo hace con el subsistema netfilter, y se gestiona con utilidades: los programas de bajo nivel iptables y nftables y la capa ufw (Uncomplicated Firewall). En la mayoría de servidores Ubuntu y Debian, configurar ufw lleva cinco minutos: bloquear todo lo entrante, abrir SSH y los puertos de los servicios y activarlo. A continuación tiene el escenario paso a paso, los errores típicos y lo mínimo de nftables para entender qué ocurre por debajo.
Cómo funciona el firewall en Linux
El filtrado de paquetes está en el kernel: es netfilter. Ofrece puntos de intercepción (hooks): tráfico entrante al propio host, saliente y de tránsito (forward). Las utilidades de usuario solo escriben reglas en el kernel para esos puntos.
| Herramienta | Nivel | Cuándo usarla |
|---|---|---|
ufw | capa sencilla, sintaxis simple | servidor único en Ubuntu/Debian, reglas habituales |
firewalld | capa con zonas | RHEL, Rocky, Fedora |
nftables (nft) | bajo nivel, moderno | reglas complejas, NAT, conjuntos de direcciones |
iptables | bajo nivel, en desuso | sistemas antiguos y scripts |
Importante: utilice una sola herramienta de gestión. Si modifica las reglas a la vez con ufw y a mano con iptables, se sobrescribirán unas a otras y el resultado será impredecible.
Instalación y comprobación de ufw
En Ubuntu ufw suele estar instalado pero desactivado. En Debian hay que instalarlo aparte:
$ sudo apt update
$ sudo apt install ufw
$ sudo ufw status
Status: inactive
El estado inactive significa que las reglas de ufw no se aplican. Todavía no conviene activarlo: primero permitiremos SSH, o en un servidor remoto se cortará su propio acceso.
Configuración paso a paso de ufw en el servidor
Paso 1. Políticas por defecto
La política por defecto es qué hacer con un paquete si ninguna regla encaja. Para un servidor, el esquema seguro es: entrante denegado, saliente permitido.
$ sudo ufw default deny incoming
Default incoming policy changed to 'deny'
$ sudo ufw default allow outgoing
Default outgoing policy changed to 'allow'
Las respuestas a sus propias conexiones salientes pasan automáticamente: ufw hace seguimiento del estado de las conexiones (connection tracking), así que no hace falta abrir puertos para las respuestas.
Paso 2. Permitir SSH
$ sudo ufw allow OpenSSH
Rules updated
Rules updated (v6)
OpenSSH es un perfil de aplicación. Si SSH escucha en un puerto no estándar, permítalo explícitamente: sudo ufw allow 2222/tcp. Para comprobar qué puerto usa realmente sshd, ejecute sudo ss -tlnp | grep sshd.
Paso 3. Abrir los puertos de los servicios
$ sudo ufw allow 80/tcp
$ sudo ufw allow 443/tcp
Indique siempre el protocolo: sin /tcp ufw abre el puerto tanto para TCP como para UDP, y una puerta abierta de más no hace falta.
Paso 4. Activar el firewall
$ sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
ufw se inicia de inmediato y se activará en cada arranque. No cierre la sesión SSH actual: abra una segunda y compruebe que la conexión funciona.
Paso 5. Revisar las reglas
$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp (OpenSSH) ALLOW IN Anywhere
80/tcp ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
22/tcp (OpenSSH (v6)) ALLOW IN Anywhere (v6)
80/tcp (v6) ALLOW IN Anywhere (v6)
443/tcp (v6) ALLOW IN Anywhere (v6)
Las reglas para IPv6 las crea ufw solo si en /etc/default/ufw está IPV6=yes (valor por defecto).
Cómo abrir un puerto en ufw: todas las variantes de sintaxis
El comando ufw allow admite una forma corta y una completa. La corta sirve para los casos típicos; la completa, cuando hay que indicar el origen, la interfaz o la dirección de destino.
| Tarea | Comando |
|---|---|
| Puerto TCP | sudo ufw allow 443/tcp |
| Puerto UDP | sudo ufw allow 51820/udp |
| Rango de puertos | sudo ufw allow 6000:6007/tcp |
| Por nombre de servicio | sudo ufw allow https |
| Desde una IP | sudo ufw allow from 203.0.113.10 |
| Desde una subred a un puerto | sudo ufw allow from 10.0.0.0/24 to any port 5432 proto tcp |
| En una interfaz concreta | sudo ufw allow in on eth1 to any port 3306 proto tcp |
| Denegar | sudo ufw deny 23/tcp |
| Rechazar con respuesta | sudo ufw reject 25/tcp |
Diferencia entre deny y reject: deny descarta el paquete en silencio y el cliente espera hasta el tiempo de espera; reject envía una respuesta de que el puerto está cerrado. Para el exterior suele elegirse deny, y para redes internas reject resulta más cómodo, porque los clientes ven el error de inmediato.
Acceso a la base de datos solo desde un servidor
Una tarea frecuente: PostgreSQL o MySQL no deben ser visibles desde internet, pero la aplicación de otro servidor sí debe conectarse.
$ sudo ufw allow from 10.0.0.5 to any port 5432 proto tcp
Rule added
El puerto 5432 queda cerrado para todos los demás gracias a la política deny incoming. Además, conviene configurar el propio SGBD para que escuche solo en la dirección interna: el firewall y la configuración del servicio se protegen mutuamente.
Perfiles de aplicaciones
Los paquetes pueden dejar descripciones de sus puertos en /etc/ufw/applications.d/. Lista y contenido de los perfiles:
$ sudo ufw app list
Available applications:
Nginx Full
Nginx HTTP
Nginx HTTPS
OpenSSH
$ sudo ufw app info "Nginx Full"
Profile: Nginx Full
Title: Web Server (Nginx, HTTP + HTTPS)
Description: Small, but very powerful and efficient web server
Ports:
80,443/tcp
Para permitir un perfil: sudo ufw allow "Nginx Full". Los nombres con espacios van entre comillas. Un perfil propio se puede describir en formato INI en el mismo directorio y aplicarse con sudo ufw app update nombre.
Cómo eliminar una regla de ufw
La forma más segura es por número:
$ sudo ufw status numbered
Status: active
To Action From
-- ------ ----
[ 1] OpenSSH ALLOW IN Anywhere
[ 2] 80/tcp ALLOW IN Anywhere
[ 3] 443/tcp ALLOW IN Anywhere
[ 4] OpenSSH (v6) ALLOW IN Anywhere (v6)
[ 5] 80/tcp (v6) ALLOW IN Anywhere (v6)
[ 6] 443/tcp (v6) ALLOW IN Anywhere (v6)
$ sudo ufw delete 2
Deleting:
allow 80/tcp
Proceed with operation (y|n)? y
Rule deleted
Tras borrar una regla, los números cambian, así que antes de la siguiente eliminación vuelva a ejecutar status numbered. La otra forma es repetir la regla con la palabra delete: sudo ufw delete allow 80/tcp; así se elimina también la variante IPv4 y la IPv6 a la vez.
Orden de las reglas e inserción al principio
ufw revisa las reglas de arriba abajo y aplica la primera que encaja. Por eso la prohibición para una dirección concreta debe estar por encima del permiso general:
$ sudo ufw insert 1 deny from 198.51.100.23
Rule inserted
Si añade el deny con el comando normal, quedará al final de la lista, después de allow 443/tcp, y no surtirá efecto para ese puerto.
Protección de SSH contra fuerza bruta: ufw limit
La regla limit permite la conexión, pero bloquea la dirección que abre 6 o más conexiones en 30 segundos:
$ sudo ufw limit OpenSSH
Rule updated
Es una protección sencilla contra la adivinación masiva de contraseñas. Para una defensa seria, añada el acceso solo con claves y, si lo desea, fail2ban: sabe bloquear direcciones mediante ufw.
Registros de ufw
El registro se activa con sudo ufw logging on; los niveles son low, medium, high y full. Las entradas van a /var/log/ufw.log (mediante rsyslog) y al registro del kernel:
$ sudo journalctl -k | grep 'UFW BLOCK' | tail -2
Oct 14 10:12:03 web kernel: [UFW BLOCK] IN=eth0 OUT= SRC=45.155.205.1 DST=192.0.2.10 PROTO=TCP SPT=51544 DPT=3389
Oct 14 10:12:09 web kernel: [UFW BLOCK] IN=eth0 OUT= SRC=89.248.165.7 DST=192.0.2.10 PROTO=TCP SPT=40312 DPT=23
Los campos SRC y DPT muestran quién y a qué puerto llamaba. Si un servicio no responde y en el registro aparece UFW BLOCK con su puerto, significa que falta la regla.
ufw y Docker: por qué los puertos se abren pese a las reglas
Es la trampa más conocida. Al publicar un puerto (-p 8080:80), Docker añade sus propias reglas NAT y la cadena DOCKER, y el tráfico hacia el contenedor pasa por forward, saltándose las reglas de entrada de ufw. Como resultado, ufw status no muestra el puerto 8080, pero desde fuera es accesible.
Opciones para resolverlo:
- Publicar los puertos solo en localhost:
-p 127.0.0.1:8080:80, y hacia fuera servirlos mediante un proxy inverso (nginx). - Añadir sus propias reglas a la cadena
DOCKER-USER: Docker no la sobrescribe. - No publicar los puertos de los contenedores de servicio y conectarlos a través de la red de Docker.
Restablecer y desactivar
$ sudo ufw disable # desactivar; las reglas se conservan
$ sudo ufw reset # borrar todas las reglas y desactivar
$ sudo ufw reload # volver a leer la configuración
Antes de reset, ufw guarda copias de los archivos de reglas en /etc/ufw/ con un sufijo de fecha. Las reglas en sí están en /etc/ufw/user.rules y user6.rules: no se editan a mano, solo con comandos.
Nociones básicas de nftables
nftables es el sustituto moderno de iptables en el kernel de Linux. En Debian 10+ y Ubuntu 20.10+ el comando iptables funciona por defecto a través de la capa de compatibilidad iptables-nft, así que las reglas de ufw también acaban en nftables. Para ver todo lo cargado en el kernel:
$ sudo nft list ruleset
Estructura de nftables: una tabla (familia ip, ip6 o inet para ambas) contiene cadenas enlazadas a los puntos de netfilter, y las cadenas contienen reglas. Un firewall mínimo para servidor en el archivo /etc/nftables.conf:
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
ct state established,related accept
ct state invalid drop
iif "lo" accept
ip protocol icmp accept
meta l4proto ipv6-icmp accept
tcp dport { 22, 80, 443 } accept
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
Aplicar y activar en el arranque:
$ sudo nft -c -f /etc/nftables.conf # solo comprobar la sintaxis
$ sudo systemctl enable --now nftables
Las reglas también pueden añadirse en caliente, pero desaparecerán tras reiniciar si no se guardan en el archivo:
$ sudo nft add rule inet filter input tcp dport 5432 ip saddr 10.0.0.5 accept
$ sudo nft -a list chain inet filter input # -a muestra el handle de cada regla
$ sudo nft delete rule inet filter input handle 9
La gran ventaja de nftables son los conjuntos ({ 22, 80, 443 }) y una sola tabla inet para IPv4 e IPv6. No ejecute su propio nftables.service a la vez que ufw: flush ruleset borraría las reglas de ufw.
Errores habituales
- Se activó ufw sin regla para SSH — se pierde el acceso. Lo salva la consola del proveedor (VNC/serie):
sudo ufw allow OpenSSHosudo ufw disable. - Se abrió el puerto, pero el servicio no responde — el servicio escucha en
127.0.0.1y no en la dirección externa. Revise conss -tlnp. - Hay otro firewall en la nube — muchos proveedores tienen grupos de seguridad; el puerto también hay que abrirlo allí.
- deny no funciona — la regla está por debajo de la de permiso; use
insert 1.
Resumen
La configuración básica de ufw consiste en default deny incoming, permitir SSH y los puertos de los servicios, ufw enable y revisar con status numbered. Para un acceso puntual use reglas con from y port, para SSH use limit, y al trabajar con Docker recuerde que se salta ufw. Cuando necesite NAT o conjuntos de reglas complejos, pase a nftables. La protección del servidor con firewall se practica en el curso de Linux.
Preguntas frecuentes
¿En qué se diferencia ufw de iptables?
ufw es una capa con sintaxis sencilla que genera por sí misma las reglas de iptables o nftables. iptables y nftables son herramientas de bajo nivel que dan control total, pero exigen más conocimientos.
¿Se conservan las reglas de ufw tras reiniciar?
Sí. Después de sudo ufw enable el firewall arranca con el sistema, y las reglas se guardan en /etc/ufw/user.rules y user6.rules.
¿Hay que abrir puertos para las conexiones salientes?
Con la política allow outgoing, no. ufw deja pasar las respuestas a las conexiones salientes automáticamente gracias al seguimiento del estado.
¿Cómo permitir ping con ufw activado?
Por defecto ufw ya deja pasar el ICMP echo-request entrante: la regla está en /etc/ufw/before.rules. Para prohibir el ping, cambie en ese archivo ACCEPT por DROP y ejecute sudo ufw reload.
¿Existe ufw en CentOS y Rocky Linux?
Allí la herramienta estándar es firewalld con el comando firewall-cmd. ufw se puede instalar desde EPEL, pero no conviene mezclarlo con firewalld.
Este tema se explica a fondo y con práctica en el curso «Linux: с нуля до уверенного администрирования».
Ir al curso