¿Por qué hacer hardening?
Montar un servidor Linux y dejarlo con la configuración por defecto es como comprar una casa y no cambiar la cerradura.
El sistema viene pensado para arrancar, instalar paquetes y prestar servicios. No viene pensado para ser tu fortaleza personal. Y en cuanto lo conectas a Internet, los escáneres automáticos empiezan a llamar a la puerta.
No es una metáfora. Es literal.
Un servidor con SSH expuesto recibe intentos de conexión automatizados. Un panel web mal protegido aparece en buscadores de dispositivos expuestos. Un servicio olvidado queda escuchando en un puerto que ya ni recordabas. Y si además tienes contraseñas débiles, paquetes desactualizados o backups que nunca has probado, estás comprando papeletas.
Este artículo no pretende ser una guía de seguridad militar ni un benchmark CIS completo. Es un checklist práctico de hardening básico: las medidas mínimas que aplicaría antes de dejar un servidor Linux funcionando en serio, ya sea en un VPS, en una empresa pequeña o en un homelab.
La idea es sencilla: no convertirte en invulnerable, sino dejar de ser el blanco fácil.
Nota sobre los ejemplos: los usuarios, nombres de equipo, direcciones, puertos y configuraciones mostrados en este artículo son ilustrativos y deben adaptarse a cada entorno. No representan una instalación real.
0. Antes de tocar nada: ten una vía de recuperación
Esto casi nunca se dice y debería ser el primer paso.
Antes de endurecer SSH, firewall o servicios, asegúrate de que tienes una forma de recuperar el servidor si te equivocas.
- Acceso por consola del proveedor si es un VPS.
- Acceso físico si es un servidor de casa.
- Snapshot o backup reciente.
- Sesión SSH abierta mientras pruebas cambios.
- Contraseña o clave de recuperación disponible.
El hardening mal aplicado también puede dejarte fuera. Y no hay nada más absurdo que “asegurar” tanto un servidor que ni tú puedes entrar.
Mi regla: cuando cambio SSH o firewall, mantengo una sesión abierta y pruebo una segunda conexión antes de cerrar la primera.
1. Actualiza el sistema
Parece obvio, pero sigue siendo uno de los pasos que más se saltan.
Un servidor recién instalado puede traer paquetes pendientes de actualización. Antes de montar servicios encima, actualiza:
# Debian / Ubuntu
sudo apt update
sudo apt upgrade -y
# Fedora / RHEL / Rocky / AlmaLinux
sudo dnf update -y
Después, revisa si hace falta reiniciar:
# Debian / Ubuntu
test -f /var/run/reboot-required && cat /var/run/reboot-required
En Ubuntu, las actualizaciones automáticas de seguridad se gestionan normalmente con unattended-upgrades. En muchas instalaciones de servidor ya viene instalado o activado para parches de seguridad, pero conviene comprobarlo.
sudo apt install unattended-upgrades apt-listchanges -y
sudo dpkg-reconfigure --priority=low unattended-upgrades
Y verifica la configuración:
cat /etc/apt/apt.conf.d/20auto-upgrades
Deberías ver algo parecido a:
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
Matiz importante: actualizar automáticamente parches de seguridad tiene mucho sentido en servidores pequeños o homelab, pero en producción conviene controlar ventanas, reinicios y excepciones. No todo parche debería reiniciar servicios críticos sin que lo sepas.
Mi enfoque:
- Homelab: actualizaciones de seguridad automáticas y revisión periódica.
- Servidor crítico: automatizar descarga/aplicación con política clara y ventana de mantenimiento.
- Empresa: gestión de parches, pruebas y trazabilidad.
2. Revisa qué está escuchando
Antes de cerrar o abrir puertos, mira qué servicios tienes realmente expuestos.
sudo ss -tulpn
Ese comando te muestra puertos TCP/UDP en escucha y qué proceso hay detrás.
También puedes ver servicios activos:
systemctl --type=service --state=running
La pregunta que me hago siempre es:
¿Este servicio necesita estar escuchando?
Si la respuesta es no, lo paro y lo deshabilito:
sudo systemctl stop nombre-servicio
sudo systemctl disable nombre-servicio
Reducir superficie de ataque no es instalar diez herramientas más. Muchas veces es justo lo contrario: quitar lo que sobra.
3. Acceso SSH seguro
SSH suele ser la puerta de entrada principal a un servidor Linux. Por eso hay que cuidarlo.
Primero, crea o usa un usuario normal con permisos sudo. No trabajes como root en el día a día.
sudo adduser usuario
sudo usermod -aG sudo admin
Después, configura acceso por clave SSH desde tu equipo:
ssh-keygen -t ed25519 -C "usuario@servidor"
ssh-copy-id admin@IP-DE-TU-SERVIDOR
Comprueba que puedes entrar con clave antes de desactivar contraseña:
ssh usuario@IP-DE-TU-SERVIDOR
Ahora edita la configuración de SSH. En sistemas modernos, puedes tocar /etc/ssh/sshd_config o crear un archivo específico en /etc/ssh/sshd_config.d/.
sudo nano /etc/ssh/sshd_config.d/99-hardening.conf
Contenido recomendado:
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
AllowUsers usuario
Sobre cambiar el puerto SSH:
Port 2222
Cambiar el puerto puede reducir muchísimo el ruido de bots que atacan el puerto 22. Pero no lo vendería como una medida de seguridad fuerte. Un escaneo completo de puertos lo encontrará igual.
Es útil para bajar ruido. No sustituye claves SSH, bloqueo de root, firewall ni Fail2ban.
Antes de reiniciar SSH, valida la configuración:
sudo sshd -t
Si no devuelve nada, la sintaxis está bien.
Reinicia el servicio según tu distribución:
# Debian / Ubuntu
sudo systemctl restart ssh
# RHEL / Fedora / Rocky / AlmaLinux
sudo systemctl restart sshd
Y ahora lo importante: abre otra terminal e intenta entrar de nuevo.
ssh -p 2222 admin@IP-DE-TU-SERVIDOR
No cierres la sesión antigua hasta confirmar que la nueva funciona.
4. Firewall: solo lo necesario
No dejes puertos abiertos “por si acaso”. Cada puerto abierto es una puerta que tendrás que vigilar.
Con UFW en Ubuntu/Debian:
sudo ufw default deny incoming
sudo ufw default allow outgoing
# SSH
sudo ufw allow 2222/tcp
# Web, solo si realmente sirves HTTP/HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
Si usas el puerto 22 en vez de 2222, cambia la regla. Y si estás conectado por SSH, asegúrate de permitir tu puerto antes de activar UFW.
Con firewalld en Fedora/RHEL/Rocky/AlmaLinux:
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
La filosofía es simple:
Denegar por defecto.
Abrir solo lo necesario.
Revisar periódicamente.
Si el servidor solo se administra por VPN, mejor todavía: no expongas SSH a Internet. Permite SSH solo desde tu red VPN o desde una IP concreta.
sudo ufw allow from 10.8.0.0/24 to any port 22 proto tcp
Eso, para mí, es mucho mejor que exponer SSH al mundo.
5. Fail2ban: útil, pero no mágico
Fail2ban monitoriza logs y bloquea IPs que fallan repetidamente al autenticarse. Es muy útil para reducir fuerza bruta y ruido automatizado.
Instalación:
sudo apt install fail2ban -y
No recomiendo editar directamente jail.conf. Crea un archivo local:
sudo nano /etc/fail2ban/jail.d/sshd.local
Contenido:
[sshd]
enabled = true
port = 2222
filter = sshd
backend = systemd
maxretry = 3
findtime = 10m
bantime = 1h
Si usas SSH en el puerto 22, cambia port = 2222 por port = ssh o port = 22.
Reinicia Fail2ban:
sudo systemctl enable --now fail2ban
sudo systemctl restart fail2ban
Comprueba estado:
sudo fail2ban-client status
sudo fail2ban-client status sshd
Matiz importante: si ya has desactivado contraseñas y solo permites claves SSH, Fail2ban pasa a ser una capa adicional contra ruido, no tu defensa principal.
La defensa principal es:
- Claves SSH.
- Root deshabilitado.
- Sin contraseña.
- Firewall.
- VPN si puedes.
6. Usuarios y privilegios
El principio aquí es mínimo privilegio.
Crea usuarios normales. Da sudo solo a quien lo necesite. Y revisa de vez en cuando qué cuentas existen.
getent passwd | awk -F: '$3 >= 1000 && $1 != "nobody" {print $1}'
Ver quién tiene sudo:
getent group sudo
getent group wheel
Bloquear una cuenta que ya no se usa:
sudo usermod -L usuario_no_usado
sudo usermod -s /usr/sbin/nologin usuario_no_usado
Eliminar usuario, conservando o no su home según el caso:
# Eliminar solo la cuenta
sudo userdel usuario_no_usado
# Eliminar cuenta y home
sudo userdel -r usuario_no_usado
También revisa permisos de archivos sensibles:
ls -la ~/.ssh
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
Y si el servidor es importante, considera activar MFA para SSH con TOTP o usar acceso vía VPN con MFA. No siempre lo pondría en un homelab sencillo, pero para servidores expuestos o críticos merece la pena.
7. Protege servicios web
Si expones servicios web, HTTPS no es opcional.
Con Certbot y Let’s Encrypt puedes obtener certificados gratuitos y automatizar renovación:
# Nginx
sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx
# Apache
sudo apt install certbot python3-certbot-apache -y
sudo certbot --apache
Comprueba renovación:
sudo certbot renew --dry-run
Además de HTTPS, añade cabeceras de seguridad. No todas aplican igual en todas las aplicaciones, pero estas suelen ser un buen punto de partida:
- Strict-Transport-Security: fuerza HTTPS en visitas futuras.
- X-Content-Type-Options: evita ciertos problemas de detección de tipos MIME.
- X-Frame-Options o frame-ancestors en CSP: reduce clickjacking.
- Referrer-Policy: limita información enviada como referer.
- Content-Security-Policy: potente, pero hay que configurarla con cuidado para no romper la web.
Ejemplo sencillo en Nginx:
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;
Ojo con HSTS: actívalo cuando tengas claro que todo tu sitio funciona bien por HTTPS. Si lo configuras mal, puedes dejarte sin acceso cómodo durante un tiempo.
También aplica rate limiting cuando tenga sentido. No te salvará de un DDoS serio, pero puede reducir abuso básico en formularios, login o endpoints sensibles.
8. Logs y monitorización
No puedes proteger lo que no ves.
En un servidor pequeño, al menos revisaría:
journalctl -p warning..alert --since "24 hours ago"
sudo tail -n 100 /var/log/auth.log 2>/dev/null
sudo tail -n 100 /var/log/secure 2>/dev/null
En Debian/Ubuntu, /var/log/auth.log suele ser clave para autenticación. En RHEL/Fedora/Rocky/AlmaLinux, suele ser /var/log/secure.
Para resumen diario puedes usar Logwatch:
sudo apt install logwatch -y
sudo logwatch --detail High --service All --range yesterday
Si quieres recibirlo por correo, tendrás que tener envío de correo configurado en el servidor. En muchos VPS o homelabs eso no viene listo de serie.
Para monitorización visual, puedes usar:
- Uptime Kuma: para saber si servicios responden.
- Netdata: métricas rápidas y visuales.
- Prometheus + Grafana: más potente, más mantenible si ya tienes stack de monitorización.
- Grafana Loki: si quieres centralizar logs sin montar algo tan pesado como ELK.
Mi recomendación: empieza simple. Primero uptime y logs básicos. Luego métricas. Después logs centralizados si realmente los necesitas.
9. Backups: si no restauras, no tienes backup
Este punto debería estar en cualquier guía de hardening.
Un servidor seguro no es solo el que evita ataques. Es también el que puede recuperarse.
Aplica la regla 3-2-1:
- 3 copias de los datos.
- 2 soportes o ubicaciones diferentes.
- 1 copia fuera del servidor o fuera de sitio.
Pero lo más importante es probar restauraciones.
Un backup que nunca has restaurado es una promesa, no una garantía.
Como mínimo:
- Backup de configuraciones críticas.
- Backup de datos de aplicaciones.
- Backup de bases de datos con dump consistente.
- Backup de claves/certificados donde corresponda.
- Prueba de restauración documentada.
Y mucho cuidado con guardar secretos sin cifrar en backups. Un backup mal protegido puede ser el camino más fácil para robar credenciales.
10. Auditoría básica
Una vez aplicadas las medidas básicas, conviene auditar.
Herramientas útiles:
- Lynis: auditoría local de seguridad en Linux.
- OpenSCAP: más orientado a cumplimiento y perfiles.
- CIS Benchmarks: referencia seria si quieres ir más lejos.
- nmap: para comprobar desde fuera qué puertos expones.
Instalar Lynis en Ubuntu/Debian:
sudo apt install lynis -y
sudo lynis audit system
Comprobar exposición desde otra máquina:
nmap -sV -Pn IP-DE-TU-SERVIDOR
No te obsesiones con tener puntuación perfecta. Úsalo para descubrir cosas que se te han pasado.
Hardening no es aprobar un examen. Es reducir riesgo de forma práctica.
Checklist rápido de hardening
| ✔️ | Medida |
|---|---|
| ☐ | Tengo una vía de recuperación si rompo SSH o firewall. |
| ☐ | Sistema actualizado con parches de seguridad. |
| ☐ | Actualizaciones automáticas de seguridad revisadas. |
| ☐ | Servicios innecesarios deshabilitados. |
| ☐ | SSH con claves, sin contraseña y sin login root. |
| ☐ | He probado una nueva sesión SSH antes de cerrar la anterior. |
| ☐ | Firewall configurado con denegación por defecto. |
| ☐ | Fail2ban activo para SSH si el servidor está expuesto. |
| ☐ | Usuarios y privilegios revisados. |
| ☐ | Permisos de claves SSH revisados. |
| ☐ | HTTPS configurado en servicios web. |
| ☐ | Cabeceras de seguridad básicas aplicadas donde corresponda. |
| ☐ | Logs revisables y monitorización mínima. |
| ☐ | Backups 3-2-1 configurados y restauración probada. |
| ☐ | Auditoría básica con Lynis, OpenSCAP o benchmark equivalente. |
Si estás montando tu propio laboratorio, te interesa la guía de homelab, donde explico cómo construir un entorno de pruebas sólido. Y para verlo desde una perspectiva más amplia, también puedes leer el artículo sobre ciberseguridad hoy.
En resumen
El hardening no es un proyecto que haces una vez y olvidas.
Es un ciclo:
Actualizar → Reducir superficie → Proteger accesos → Monitorizar → Probar backups → Revisar
Con estas medidas básicas no conviertes tu servidor en inexpugnable. Nadie serio debería prometer eso.
Pero sí consigues algo muy importante: dejas de ser el servidor fácil.
La mayoría de ataques automatizados no buscan una obra de ingeniería. Buscan contraseñas débiles, SSH abierto con root, servicios viejos, paneles expuestos, puertos olvidados y sistemas sin parches.
Si aplicas estas pautas, obligas al atacante a trabajar bastante más.
Y muchas veces, eso es suficiente para que siga buscando la siguiente puerta abierta.
¿Qué medidas aplicas tú en tus servidores? ¿Usas UFW, Fail2ban, WireGuard, Tailscale, Lynis, backups cifrados o alguna práctica que te haya salvado alguna vez? Cuéntalo en los comentarios — las experiencias reales son las que más enseñan.
Lectura desde Gestión TIC
El hardening no va de dejar un servidor “perfecto”, sino de reducir superficie de ataque y evitar errores básicos que luego cuestan caros. Desde gestión TIC, este tipo de medidas son controles sencillos pero importantes: limitar accesos, cerrar lo que no se usa, revisar permisos, registrar actividad y hacer que la configuración sea mantenible. No es la parte más vistosa, pero muchas veces es la que evita problemas reales.
¿Quieres seguir explorando?
Puedes descubrir más artículos, seguir mis publicaciones en LinkedIn o escribirme.