Hardening de servidores Linux: guía práctica
Etiquetas: linux,seguridad,ssh,devops,vpsTener 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 no
Despué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 65535
En 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 verbose
Actualizaciones 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-upgrades
Para verificar que está activo:
systemctl is-active unattended-upgrades
El 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 false
Para deshabilitar un usuario sin eliminarlo:
sudo usermod -s /usr/sbin/nologin usuario
sudo passwd -l usuario # Bloquear contraseña
sudo 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: ALL
Protecció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 fail2ban
Configuració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)s
sudo systemctl enable fail2ban
sudo systemctl start fail2ban
# Ver IPs baneadas
sudo fail2ban-client status sshd
Auditorí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 security
Cifrado 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 > publickey
El 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.
Equipamiento recomendado
- Mini PC Intel N100 — Mini PC silencioso y eficiente para servidor doméstico 24/7
- YubiKey 5 NFC — Llave de seguridad física para 2FA y acceso SSH seguro
Enlaces de afiliado. Sin coste extra para ti.