Un servidor web nuevo es escaneado a los pocos minutos de ponerse en línea. La mayor parte de ese tráfico es automatizado e inofensivo si has hecho lo básico. Esta guía va un paso más allá del refuerzo en 15 minutos y cubre un cortafuegos, la protección contra fuerza bruta con fail2ban y una configuración de Nginx más segura.
Paso 1: un cortafuegos con denegación por defecto con UFW
Permite solo lo que necesitas y bloquea el resto. Añade primero SSH para no quedarte fuera.
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
Si usas un puerto SSH no estándar, permite ese puerto en lugar de OpenSSH.
Paso 2: fail2ban para fallos repetidos
fail2ban vigila los registros y bloquea las direcciones IP que siguen fallando al iniciar sesión.
sudo apt install -y fail2ban
sudo tee /etc/fail2ban/jail.local > /dev/null <<'CONF'
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
[sshd]
enabled = true
[nginx-http-auth]
enabled = true
[nginx-botsearch]
enabled = true
CONF
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
Usa claves SSH y desactiva también el acceso por contraseña. Consulta claves SSH explicadas.
Paso 3: oculta la versión de Nginx y añade cabeceras seguras
En /etc/nginx/nginx.conf, dentro del bloque http:
server_tokens off;
En el bloque server de tu sitio:
add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "SAMEORIGIN" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
Añade la cabecera HSTS solo cuando HTTPS funcione para tu dominio y para todos los subdominios que uses.
Paso 4: limita las peticiones abusivas
La limitación de tasa frena los intentos de fuerza bruta en las páginas de inicio de sesión:
# in the http block
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
# in your server block
location = /wp-login.php {
limit_req zone=login burst=5 nodelay;
# ...your usual PHP handling
}
Prueba y aplica con sudo nginx -t && sudo systemctl reload nginx.
Paso 5: mantenlo actualizado
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
Las actualizaciones de seguridad automáticas cierran fallos conocidos sin que tengas que hacer nada.
Qué vigilar
- Revisa los bloqueos con
sudo fail2ban-client status sshd. - Revisa
/var/log/nginx/error.logde vez en cuando. - Si estás detrás de un proxy o una CDN, asegúrate de que fail2ban lea la IP real del cliente, o podrías bloquear a tu propio proxy.