Tener un servidor expuesto a Internet sin una configuración de seguridad mínima es dejar la puerta entreabierta. En este artículo recojo los pasos que aplico en mis propios servidores para reducir la superficie de ataque sin complicar la gestión del día a día.
SSH: la primera línea de defensa#
El servicio SSH es el punto de entrada más atacado en cualquier servidor Linux. Estos son los ajustes más importantes en /etc/ssh/sshd_config:
# Deshabilitar acceso root
PermitRootLogin no
# Solo autenticación por clave pública
PasswordAuthentication no
ChallengeResponseAuthentication no
# Limitar intentos de autenticación
MaxAuthTries 3
# Desactivar forwarding innecesario
X11Forwarding no
AllowTcpForwarding noDespués de cada cambio:
sudo systemctl reload ssh # Ubuntu/Debian
sudo systemctl reload sshd # CentOS/RHEL¿Por qué PermitRootLogin no y no prohibit-password? Aunque prohibit-password ya bloquea el acceso root por contraseña, dejar activo el login root por clave sigue siendo un riesgo: si esa clave se compromete, el atacante tiene acceso total al sistema sin necesidad de escalar privilegios.
Cambiar el puerto SSH (seguridad por oscuridad)#
Cambiar el puerto por defecto (22) no es seguridad real, pero elimina el ruido de los bots de internet que escanean continuamente ese puerto:
Port 2222 # cualquier número entre 1024 y 65535En el router o firewall, crea la regla de NAT para redirigir el puerto externo al 22 interno, o configura UFW para aceptar el nuevo puerto.
Firewall con UFW#
UFW (Uncomplicated Firewall) simplifica la gestión de iptables:
# Política por defecto: denegar todo
sudo ufw default deny incoming
sudo ufw default allow outgoing
# Permitir solo lo necesario
sudo ufw allow 2222/tcp # SSH en puerto personalizado
sudo ufw allow 80/tcp # HTTP
sudo ufw allow 443/tcp # HTTPS
# Activar
sudo ufw enable
sudo ufw status verboseActualizaciones de seguridad automáticas#
Los servidores que no se actualizan acaban siendo vulnerables. unattended-upgrades aplica parches de seguridad sin intervención manual:
sudo apt install unattended-upgrades
sudo dpkg-reconfigure unattended-upgradesPara verificar que está activo:
systemctl is-active unattended-upgradesEl fichero de configuración está en /etc/apt/apt.conf.d/50unattended-upgrades. Por defecto solo aplica actualizaciones de seguridad, lo cual es el comportamiento correcto para producción.
Gestión de usuarios#
Principio de mínimo privilegio#
Cada usuario solo debe tener los permisos que necesita. Revisa periódicamente qué usuarios tienen shell activa:
grep -v nologin /etc/passwd | grep -v falsePara deshabilitar un usuario sin eliminarlo:
sudo usermod -s /usr/sbin/nologin usuario
sudo passwd -l usuario # Bloquear contraseñasudo sin contraseña — con cabeza#
Es tentador poner NOPASSWD en sudoers para evitar escribir la contraseña, pero limítalo a los comandos específicos que lo necesiten:
# Bien: solo para comandos concretos
usuario ALL=(ALL) NOPASSWD: /usr/bin/docker, /usr/bin/systemctl restart nginx
# Mal: acceso total sin contraseña
usuario ALL=(ALL) NOPASSWD: ALLProtección contra fuerza bruta con fail2ban#
fail2ban monitoriza los logs del sistema y bloquea automáticamente IPs que realizan demasiados intentos fallidos:
sudo apt install fail2banConfiguración básica en /etc/fail2ban/jail.local:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
[sshd]
enabled = true
port = 2222
logpath = %(sshd_log)s
backend = %(sshd_backend)ssudo systemctl enable fail2ban
sudo systemctl start fail2ban
# Ver IPs baneadas
sudo fail2ban-client status sshdAuditoría: qué revisar periódicamente#
Una vez configurado el servidor, conviene revisar estos puntos con cierta frecuencia:
# Intentos de acceso fallidos
sudo lastb | head -20
# Puertos escuchando (detectar servicios inesperados)
ss -tlnp
# Binarios con SUID (posibles vectores de escalada de privilegios)
find / -perm -4000 -type f 2>/dev/null
# Actualizaciones pendientes
apt list --upgradable 2>/dev/null | grep -i securityCifrado entre servidores con WireGuard#
Si tienes varios servidores que necesitan comunicarse (rsync, bases de datos, APIs internas), evita exponer esos servicios a Internet. WireGuard ofrece un túnel VPN rápido y sencillo con cifrado ChaCha20-Poly1305:
sudo apt install wireguard
wg genkey | tee privatekey | wg pubkey > publickeyEl tráfico entre servidores viaja cifrado por el túnel (10.10.0.x) en lugar de usar las IPs públicas. Así, servicios como rsync o PostgreSQL nunca quedan expuestos aunque alguien intercepte el tráfico de red.
Tengo un artículo específico sobre réplica de emergencia con rsync y WireGuard con la configuración completa.
Resumen: checklist de hardening#
| Acción | Prioridad |
|---|---|
PermitRootLogin no en sshd_config | Alta |
PasswordAuthentication no | Alta |
| Firewall UFW activo y reglas mínimas | Alta |
unattended-upgrades activo | Alta |
| Cambiar puerto SSH | Media |
AllowTcpForwarding no | Media |
MaxAuthTries 3 | Media |
| fail2ban instalado y configurado | Media |
| Revisar usuarios con shell activa | Media |
| Auditoría periódica de puertos y SUID | Baja |
La seguridad perfecta no existe, pero aplicar estos pasos reduce drásticamente la probabilidad de ser el objetivo fácil que los bots automatizados buscan.