Skip to content
Breachfolio
RECURSOS · CHECKLIST

Checklist de hardening de un servidor Linux: de cero a producción.

Una instalación recién hecha de Linux no es una instalación segura. Los pasos de verdad — acceso, red, parches, servicios, logging — antes de que esa máquina toque tráfico de producción.

8 de julio de 202610 min de lectura

Una instalación por defecto de Linux se optimiza para la compatibilidad, no para la seguridad. El trabajo del instalador es dejarte un sistema que funcione y arranque, capaz de hablar con la mayor cantidad de hardware y de redes posible con la menor fricción — no está intentando adivinar qué vas a ejecutar en esa máquina ni quién podría venir a buscarla una vez que tenga una IP pública. El hardening (endurecimiento) es el proceso deliberado y repetible de cerrar esa brecha: recortar permisos, reducir la superficie de ataque y asegurarte de que la máquina avise a alguien cuando algo va mal — antes de que se acerque siquiera a producción o a internet.

Ninguno de los pasos de abajo es exótico. La mayoría lleva unos pocos minutos cada uno. Lo que importa es hacerlos todos, siempre, en cada máquina — que es exactamente para lo que sirve un checklist.

Hardening de usuarios y accesos

El control de acceso es la primera capa, porque casi todos los compromisos del mundo real empiezan con una credencial, no con un exploit. Empieza por aquí.

  • Desactiva el login SSH directo como root. Root nunca debería ser un destino válido de login remoto — cada sesión debería autenticarse como un usuario con nombre y elevar con sudo cuando haga falta, para que las acciones sigan siendo atribuibles. En /etc/ssh/sshd_config:
PermitRootLogin no
  • Fuerza la autenticación por clave en lugar de por contraseña. Las contraseñas son adivinables, susceptibles de phishing y reutilizables entre sitios; un par de claves SSH bien generado no es nada de eso. Una vez que tu clave esté instalada y confirmes que funciona, desactiva las contraseñas por completo:
PasswordAuthentication no
PubkeyAuthentication yes
  • Aplica reglas de sudo con privilegio mínimo, no acceso sudo indiscriminado. Añadir a cada administrador a un grupo wheel o sudo con acceso ALL=(ALL) ALL sin restricciones significa que una sola cuenta comprometida es un root comprometido. Acota las entradas de sudoers en /etc/sudoers.d/ a los comandos concretos que un usuario o servicio realmente necesita, y prefiere varias reglas estrechas antes que una amplia.
  • Cambia el puerto SSH por defecto — pero sé honesto sobre lo que consigue. Salir del puerto 22 no es un control de seguridad real; no hace nada frente a un atacante dirigido que simplemente escanea los 65535 puertos en segundos. Su único beneficio real es reducir el ruido de fondo constante de los bots automatizados que rastrean internet en busca del puerto 22, lo que hace que tus logs sean más fáciles de leer. Trátalo como mantenimiento, no como defensa.

Hardening de red

Si el hardening de accesos controla quién puede llamar a la puerta, el hardening de red decide cuántas puertas existen en primer lugar. El objetivo es el denegar-por-defecto: nada es accesible salvo que lo hayas permitido explícitamente.

  • Establece una línea base de firewall con denegación por defecto. Tanto ufw (familia Debian/Ubuntu) como nftables (el sucesor moderno de iptables, disponible de forma amplia) pueden expresar la misma política: denegar todo lo entrante por defecto y luego permitir solo los puertos concretos que la máquina realmente necesita servir. Una línea base realista de ufw para un servidor web que además se administra por SSH:
ufw default deny incoming
ufw default allow outgoing
ufw allow 22/tcp
ufw allow 443/tcp
ufw enable
  • Instala y activa fail2ban. Un firewall de denegación por defecto detiene el tráfico no solicitado, pero aun así tiene que dejar pasar SSH y tus puertos web — y esos se convierten en el objetivo de intentos de login por fuerza bruta repetidos. fail2ban vigila los logs de autenticación y banea temporalmente las IP de origen tras un umbral de intentos fallidos, convirtiendo un juego de adivinanzas ilimitado en uno con límite:
apt install fail2ban
systemctl enable --now fail2ban

Higiene de parches y paquetes

La mayoría de las vulnerabilidades explotadas ya son públicas y ya están parcheadas — la máquina simplemente todavía no ha recibido el arreglo. La higiene de parches cierra esa ventana, y la higiene de paquetes reduce el número de cosas que alguna vez podrían necesitar un parche.

  • Activa las actualizaciones de seguridad automáticas. En los sistemas de la familia Debian/Ubuntu, el paquete unattended-upgrades aplica los parches de seguridad de forma programada sin que un humano tenga que acordarse de ejecutar apt upgrade. Existen mecanismos equivalentes para otras familias de distribuciones (dnf-automatic en Fedora/RHEL, por ejemplo) — importa más el concepto que la herramienta exacta: el parcheo debería ocurrir según un calendario, no según la memoria de alguien.
  • Elimina los paquetes y servicios sin usar. Cada paquete instalado es una potencial vulnerabilidad futura, incluso uno que nunca tocas. Una imagen de servidor por defecto suele venir con compiladores, utilidades de correo o servicios de ejemplo que nadie pidió. Audita lo que hay instalado y elimina lo que la máquina no necesita de verdad — «instalado pero sin usar» sigue siendo superficie de ataque, solo que no lo parece hasta que resulta ser lo que acaban explotando.

Hardening de servicios

Cada servicio en ejecución es un proceso a la escucha con su propio código, sus propios bugs y sus propios privilegios. Menos servicios en ejecución, y menos privilegiados, significa que hay menos cosas que puedan salir mal.

  • Desactiva y enmascara cualquier cosa que no necesites de verdad. Un servicio detenido todavía puede ser arrancado por otro proceso o por un reinicio; enmascararlo evita eso por completo.
systemctl disable --now cups
systemctl mask cups
  • Ejecuta los servicios como un usuario dedicado sin privilegios. Si un servidor web o un proceso de aplicación se ve comprometido, el atacante hereda los privilegios con los que ese proceso se estuviera ejecutando. Un servicio que corre como su propio usuario sin privilegios limita el radio de impacto; un servicio que corre como root entrega la máquina entera.
  • Usa las directivas de sandboxing de systemd para servicios personalizados. Esta es una palanca infrautilizada pero genuinamente potente: directivas como NoNewPrivileges=true (bloquea la escalada de privilegios mediante binarios setuid) y ProtectSystem=strict (monta la mayor parte del sistema de archivos como solo lectura para el servicio) limitan lo que un proceso comprometido puede hacer, incluso antes de pensar en el propio código de la aplicación. Añádelas al archivo de unidad de un servicio:
[Service]
NoNewPrivileges=true
ProtectSystem=strict
ProtectHome=true

Logging y monitorización

El hardening reduce las probabilidades de un mal día; el logging es lo que te dice si de verdad está ocurriendo uno. Un servidor sin logging puede estar perfectamente endurecido y aun así fallar en silencio.

  • Activa auditd. El demonio de auditoría de Linux registra eventos relevantes para la seguridad — acceso a archivos, escalada de privilegios, intentos de autenticación — con un nivel de detalle que el syslogging por defecto no captura. Es la diferencia entre saber que ha ocurrido una brecha y saber exactamente qué tocó el atacante.
  • Envía los logs fuera de la máquina, no solo al disco local. Los logs que viven únicamente en el servidor que describen son lo primero que borra un atacante con acceso root. Reenviar los logs a una ubicación centralizada — idealmente una que la propia máquina comprometida no pueda sobrescribir — significa que el registro sobrevive aunque el servidor no lo haga. En un SIEM que de verdad puedas leer se cubre un ejemplo a escala de home-lab de exactamente este tipo de montaje centralizado de logs y detección.

Sistema de archivos y permisos

La última capa es el sistema de archivos en sí — los valores por defecto silenciosos que determinan quién puede leer qué, mucho después de que las capas de red y de servicios hayan hecho su trabajo.

  • Establece un umask por defecto sensato. Un umask de 027 o 077 (en lugar del más laxo 022 que traen algunas distribuciones) asegura que los archivos nuevos no sean legibles por el grupo ni por todo el mundo por defecto, lo que importa más en máquinas multiusuario.
  • Ajusta los permisos de los archivos genuinamente sensibles. /etc/shadow nunca debería ser legible por todo el mundo, y las claves privadas deberían quedar restringidas solo a su propietario:
chmod 640 /etc/shadow
chmod 600 ~/.ssh/id_ed25519
  • Desactiva los módulos de sistema de archivos del kernel sin usar. Un paso de menor prioridad, pero real para despliegues concienciados con la seguridad: sistemas de archivos como cramfs o freevxfs que la máquina nunca va a montar siguen siendo módulos del kernel cargables, y un módulo sin usar sigue siendo código que podría contener un bug. Ponerlos en la lista negra elimina un rincón poco revisado pero real de la superficie de ataque.

En conjunto, estos pasos son una línea base, no una meta final. Un servidor endurecido una vez y nunca revisado se desvía — se instala un nuevo servicio, se afloja una regla de firewall para una prueba puntual y nunca se revierte, una actualización de paquete reintroduce un valor por defecto que ya habías desactivado. Vuelve a este checklist siempre que cambie el rol del servidor, y combínalo con el logging y la monitorización de arriba: el hardening decide lo que no debería ocurrir, la monitorización es lo que de verdad se da cuenta cuando se desvía de todos modos.