Lista de comprobación de endurecimiento post-reinstalación: qué asegurar primero

¿Te fue útil?

Has reinstalado un servidor. Arranca. Los servicios se inician. Todo el mundo respira tranquilo… hasta que recuerdas que un sistema recién instalado es básicamente una casa nueva con las puertas apoyadas para los mudanceros.

Esta es la ventana donde las decisiones pequeñas se convierten en historias caras. A continuación está el orden de endurecimiento que realmente resiste en producción: detén las intrusiones fáciles primero, luego haz que el sistema sea superviviente, y después haz que sea diagnosticable.

El orden importa: principios de endurecimiento que no engañan

Endurecer tras una reinstalación no es una actividad basada en sensaciones. Es un problema de secuencia. Estás intentando reducir el riesgo rápido mientras mantienes el sistema lo bastante operativo para terminar el trabajo.

Principio 1: Cierra las puertas remotas antes de decorar el interior

Empieza por todo lo accesible desde fuera: SSH, gestión remota, paneles web expuestos, credenciales por defecto, puertos abiertos. Si un atacante puede obtener una shell interactiva, tus permisos de archivos meticulosos son solo un tope de velocidad.

Principio 2: Identidad y acceso son tu primer estado permanente

Usuarios, grupos, reglas sudo, cuentas de servicio y claves API son cómo se usará el sistema durante el próximo año. Tu reinstalación borró la historia desordenada. No la reintroduzcas por comodidad.

Principio 3: Observabilidad es parte de la seguridad

Si no puedes responder “¿qué cambió?” y “¿quién lo hizo?”, no tienes un sistema endurecido. Tienes un sistema que esperas que esté endurecido. Logs centrales, trazas de auditoría y sincronización horaria no son adornos; son herramientas de respuesta a incidentes.

Principio 4: El almacenamiento es donde los accidentes se vuelven desastres

La mayoría de los incidentes de producción no son hacks de Hollywood; son errores de permisos, logs desbocados, un filesystem raíz lleno, o un montaje “temporal” que se olvidó. Endurecer el almacenamiento significa hacer las rutas de escritura aburridas y predecibles.

Principio 5: Las líneas base vencen a los heroísmos

Tras la reinstalación puedes construir una línea base conocida y buena. Esa línea base es tu diff futuro. Si no la estableces ahora, pasarás meses discutiendo si “antes funcionaba”.

Una cita que vale la pena tener en la cabeza cuando te tiente improvisar: “La esperanza no es una estrategia.” — atribuido a John M. Sullivan (citada comúnmente en contextos de operaciones y planificación).

Broma #1: Un servidor recién reinstalado es como un recién nacido: lindo, ruidoso y absolutamente no listo para quedarse solo en internet.

Guía de diagnóstico rápido (primera/segunda/tercera comprobación)

Este es el playbook de “se está comportando raro tras la reinstalación”. Úsalo para encontrar el cuello de botella rápido y evitar cavar en la capa equivocada.

Primera: ¿Está el sistema sano a nivel de SO?

  • ¿Presión de CPU? Comprueba la carga, la cola de ejecución y si es CPU o iowait.
  • ¿Presión de memoria? Comprueba la memoria disponible y la actividad de swap.
  • ¿Disco lleno? Root y /var llenos son fallos clásicos después de reinstalar.
  • ¿Hora correcta? Si los relojes se desincronizan, TLS falla, los logs mienten y la autenticación se vuelve “misteriosa”.

Segunda: ¿Es la ruta de red sensata?

  • ¿Ruta por defecto y DNS? Una reinstalación suele resetear resolvers, rutas y nombres de interfaz.
  • ¿Reglas de firewall? Tus servicios pueden estar en ejecución pero inalcanzables.
  • ¿Endurecimiento de SSH demasiado estricto? “Bloqueado” no es lo mismo que “bloqueado fuera”.

Tercera: ¿Hace la pila de almacenamiento lo que crees que hace?

  • ¿Montajes y fstab? Montajes faltantes hacen que las apps escriban en root.
  • ¿Estado RAID/ZFS? Arrays degradados rinden mal y fallan peor.
  • ¿Permisos? Una reinstalación puede cambiar silenciosamente mapeos UID/GID.

Cuando estés atascado, elige una pregunta por capa: “¿es computación, red o almacenamiento?” La mayoría de las horas perdidas son por gente que adivina la capa equivocada y se obsesiona con ella.

Datos interesantes y contexto histórico (para los escépticos)

  1. Unix temprano asumía redes de confianza. Muchos valores por defecto históricamente favorecían la conveniencia en redes de campus, no la exposición a Internet hostil.
  2. SSH reemplazó a telnet por una razón. En los 90, los inicios de sesión remotos en texto plano eran normales; SSH hizo que la administración remota cifrada fuera común.
  3. Servicios abiertos por defecto tienen una larga cola. “Solo escucha en la LAN” ha sido una frase recurrente antes de incidentes desde las primeras redes planas.
  4. La sincronización de tiempo se volvió una característica de disponibilidad. TLS, Kerberos y muchos sistemas distribuidos fallan de formas extrañas cuando los relojes se desincronizan.
  5. La retención de logs solía ser un problema de disco. Discos más pequeños forzaban rotaciones agresivas; ahora el modo de fallo es “guardar todo hasta que /var se llene”.
  6. El principio de menor privilegio no siempre fue aceptado culturalmente. Durante décadas, los equipos de ops resolvían problemas de velocidad con root compartido, y luego pasaron años desaprendiendo eso.
  7. Los firewalls pasaron del perímetro al host. El auge de la nube y el zero-trust hizo que el filtrado a nivel de host y la segmentación sean normales en lugar de paranoicos.
  8. La infraestructura inmutable popularizó reinstalar en lugar de reparar. Reconstruir en vez de reparar mejora la consistencia—pero solo si tu endurecimiento de línea base es real.

Listas de verificación / plan paso a paso (asegurar primero)

Este es el orden que usaría en un servidor Linux de producción tras reinstalar. Ajusta según la distro y el entorno, pero no improvises la secuencia.

Fase 0: No dejes el equipo inservible

  • Obtén acceso fuera de banda (IPMI/iDRAC/consola) o consola serial del cloud antes de cambiar SSH o firewall.
  • Registra las IPs actuales, rutas, DNS y la ruta de acceso SSH.
  • Establece una ventana de reversión: si te bloqueas, necesitas un plan de recuperación conocido.

Fase 1: Detén la compromiso remoto fácil

  • Parchea los paquetes base del SO.
  • Endurece SSH: claves, no login root, sin contraseñas (cuando sea seguro), cifrados/MACs mínimos si tienes una política.
  • Habilita y valida un firewall de host: denegar inbound por defecto, permitir solo lo requerido.
  • Elimina/deshabilita servicios remotos no usados (viejos consolas web, endpoints RPC, puertos de desarrollo).

Fase 2: Haz que la identidad sea aburrida

  • Crea cuentas administrativas nombradas; evita root compartido.
  • Restringe sudoers: grupos explícitos, no NOPASSWD a menos que tengas una razón defendible.
  • Establece una política de contraseñas sensata donde aplique (o políticas de autenticación central).
  • Inventaría las authorized_keys de SSH y elimina las claves zombis.

Fase 3: Almacenamiento y seguridad de datos (donde vive el dolor)

  • Confirma montajes y opciones de sistema de archivos (nodev/nosuid/noexec donde aplique).
  • Verifica salud de RAID/ZFS; programa scrubs y comprobaciones SMART.
  • Establece permisos y propiedad en rutas de datos; verifica la alineación UID/GID para cuentas de servicio.
  • Configura rotación de logs y salvaguardas de uso de disco.
  • Backups: configura, ejecuta y prueba una restauración. Si no pruebas, no es backup; es un deseo.

Fase 4: Observabilidad y respuesta

  • Sincronización de tiempo (chrony/systemd-timesyncd) y zona horaria sensata.
  • Centrar logs o al menos enviar logs críticos fuera del host.
  • Habilitar auditoría para acciones privilegiadas si el entorno lo requiere.
  • Monitoreo base: CPU, memoria, disco, comprobaciones de servicios y ruteo de alertas.

Fase 5: Endurecimiento de servicios (defensa en profundidad)

  • Opciones de sandboxing de systemd donde sea seguro.
  • Deshabilitar módulos de kernel no usados y ajustar sysctl para reducir exposición en red.
  • Enfoque de gestión de secretos (permisos de archivos, variables de entorno, integración con vault, rotación).

Tareas prácticas (comandos, salidas, decisiones)

A continuación hay tareas prácticas que puedes ejecutar justo después de reinstalar. Cada una incluye: un comando, cómo se ve la salida “normal”, qué significa y qué decisión tomar a continuación.

Tarea 1: Confirma qué está escuchando realmente (y en qué interfaces)

cr0x@server:~$ sudo ss -lntup
Netid State  Recv-Q Send-Q Local Address:Port  Peer Address:Port Process
tcp   LISTEN 0      4096   0.0.0.0:22         0.0.0.0:*     users:(("sshd",pid=812,fd=3))
tcp   LISTEN 0      4096   127.0.0.1:5432     0.0.0.0:*     users:(("postgres",pid=1021,fd=7))
tcp   LISTEN 0      4096   0.0.0.0:9100       0.0.0.0:*     users:(("node_exporter",pid=1102,fd=3))

Qué significa: SSH y node_exporter están expuestos en todas las interfaces; Postgres está solo en loopback (buen valor por defecto).

Decisión: Si 9100 no debería ser público, aplica firewall para tu red de monitorización o enlázalo a una interfaz privada. Si algo inesperado está en 0.0.0.0, considéralo un bug hasta demostrar lo contrario.

Tarea 2: Verifica que el firewall esté habilitado y la política no sea “me da igual”

cr0x@server:~$ sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To                         Action      From
22/tcp                     ALLOW IN    203.0.113.10
9100/tcp                   ALLOW IN    10.10.0.0/16

Qué significa: Denegar inbound por defecto está establecido. SSH está restringido a una IP administrativa conocida; métricas están permitidas desde un rango interno.

Decisión: Si ves “Default: allow (incoming)”, arréglalo inmediatamente. Si SSH está “Anywhere”, restríngelo a menos que realmente necesites acceso global de administración (no lo necesitas).

Tarea 3: Confirma que la configuración de SSH no te vaya a avergonzar más tarde

cr0x@server:~$ sudo sshd -T | egrep '^(permitrootlogin|passwordauthentication|pubkeyauthentication|challengeresponseauthentication|x11forwarding|allowusers|allowgroups)'
permitrootlogin no
passwordauthentication no
pubkeyauthentication yes
challengeresponseauthentication no
x11forwarding no

Qué significa: Login root y autenticación por contraseña están deshabilitados; autenticación por clave está habilitada; reenvío X11 está apagado.

Decisión: Si este servidor es un endpoint de rescate o necesita break-glass, defínelo explícitamente (IP de origen restringida + clave separada + alertas). De lo contrario, mantén las contraseñas desactivadas.

Tarea 4: Valida que no te hayas bloqueado (desde otra terminal)

cr0x@server:~$ ssh -o PreferredAuthentications=publickey -o PasswordAuthentication=no admin@server.example
Linux server 6.5.0-21-generic #21-Ubuntu SMP ...
admin@server:~$ echo OK
OK

Qué significa: El login por clave funciona como se espera; no hay fallback por contraseña.

Decisión: Solo después de que esto tenga éxito deberías cerrar tu sesión de consola fuera de banda. Si falla, no “lo arregles en vivo” a ciegas—revisa sshd_config y authorized_keys.

Tarea 5: Inventaría el acceso privilegiado (sudo) y elimina sorpresas

cr0x@server:~$ sudo getent group sudo
sudo:x:27:admin,deploy

Qué significa: El grupo sudo contiene las cuentas admin y deploy.

Decisión: Decide si deploy realmente necesita sudo completo. A menudo necesita comandos específicos, no modo dios.

Tarea 6: Comprueba sudo sin contraseña (se propaga)

cr0x@server:~$ sudo grep -R --line-number -E 'NOPASSWD|ALL=\(ALL\) ALL' /etc/sudoers /etc/sudoers.d 2>/dev/null
/etc/sudoers:27:%sudo   ALL=(ALL:ALL) ALL
/etc/sudoers.d/deploy:1:deploy ALL=(root) NOPASSWD:/usr/bin/systemctl restart myapp.service

Qué significa: El usuario deploy puede reiniciar un servicio sin contraseña. Eso está estrechamente acotado y es defendible.

Decisión: Mantenlo si es necesario para automatización y está bien acotado. Si encuentras NOPASSWD:ALL, quítalo y espera descubrir “automatización” que en realidad fue “alguien con prisa”.

Tarea 7: Confirma actualizaciones de seguridad automáticas (o tu pipeline de parches)

cr0x@server:~$ systemctl status unattended-upgrades --no-pager
● unattended-upgrades.service - Unattended Upgrades Shutdown
     Loaded: loaded (/lib/systemd/system/unattended-upgrades.service; enabled)
     Active: active (running) since Tue 2026-02-03 11:14:26 UTC; 1 day ago

Qué significa: Las actualizaciones automáticas están habilitadas y en ejecución.

Decisión: En entornos controlados puedes desactivar esto y parchear vía tu pipeline en su lugar. De cualquier modo, elige uno. “Parcheamos manualmente a veces” es cómo te compromete una vulnerabilidad con logo mono.

Tarea 8: Confirma que la versión del kernel y del SO coinciden con tu línea base

cr0x@server:~$ uname -a
Linux server 6.5.0-21-generic #21-Ubuntu SMP PREEMPT_DYNAMIC x86_64 GNU/Linux

Qué significa: Este es el kernel en ejecución. Debe coincidir con lo que esperan tus controladores, política de seguridad y herramientas.

Decisión: Si necesitas una línea de kernel específica (p. ej., para controladores HBA de almacenamiento), arréglalo ahora—no después de cargar datos y arrepentirte.

Tarea 9: Comprueba la sincronización horaria (seguridad y cordura)

cr0x@server:~$ timedatectl
               Local time: Wed 2026-02-04 09:22:11 UTC
           Universal time: Wed 2026-02-04 09:22:11 UTC
                 RTC time: Wed 2026-02-04 09:22:10
                Time zone: Etc/UTC (UTC, +0000)
System clock synchronized: yes
              NTP service: active
          RTC in local TZ: no

Qué significa: El reloj está sincronizado; NTP activo; UTC en uso (benditamente aburrido).

Decisión: Si System clock synchronized: no, arréglalo antes de depurar TLS, pertenencia a clúster o fallos “aleatorios” de autenticación.

Tarea 10: Revisa discos, sistemas de archivos y qué está montado dónde

cr0x@server:~$ lsblk -f
NAME   FSTYPE FSVER LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINTS
sda
├─sda1 vfat   FAT32       2F1A-9C2B                              512M     2% /boot/efi
├─sda2 ext4   1.0         6f8d1c6a-1f6a-4b6c-9f0a-1f7c6e2a1b4a   18G     21% /
└─sda3 ext4   1.0         41b2b9b0-9a1f-4b57-9b0d-0d8d1d7b6e2e  820G     9% /srv

Qué significa: Root y /srv están separados. Eso es bueno: los datos de la app no derriban instantáneamente el SO.

Decisión: Si /var no está separado y esperas muchos logs, considera dividirlo o al menos aplicar rotación agresiva y monitorización.

Tarea 11: Verifica que fstab no te vaya a reiniciar sorpresivamente

cr0x@server:~$ sudo cat /etc/fstab
UUID=6f8d1c6a-1f6a-4b6c-9f0a-1f7c6e2a1b4a /     ext4 defaults,errors=remount-ro 0 1
UUID=41b2b9b0-9a1f-4b57-9b0d-0d8d1d7b6e2e /srv  ext4 defaults,noatime         0 2

Qué significa: Los montajes usan UUIDs (estables). errors=remount-ro protege root de corrupción silenciosa poniéndolo en solo lectura al detectar errores.

Decisión: Si tienes montajes “temporales”, decide si deberían ser nofail. Para datos críticos, no uses nofail; falla rápido en lugar de arrancar en un estado medio operativo.

Tarea 12: Comprueba uso del sistema de archivos y encuentra el primer “¿por qué está lleno esto?”

cr0x@server:~$ df -hT
Filesystem     Type  Size  Used Avail Use% Mounted on
/dev/sda2      ext4   20G  4.2G   15G  23% /
/dev/sda3      ext4  900G   80G  774G  10% /srv
tmpfs          tmpfs 3.1G     0  3.1G   0% /run/user/1000

Qué significa: Mucho espacio ahora. El objetivo es establecer la línea base antes de que el sistema empiece a envejecer.

Decisión: Configura alertas en 70/80/90% según la tasa de crecimiento. Si / es pequeño, sé más agresivo.

Tarea 13: Confirma que la rotación de logs está habilitada y no es fantasía

cr0x@server:~$ sudo logrotate -d /etc/logrotate.conf | tail -n 8
reading config file /etc/logrotate.conf
including /etc/logrotate.d
reading config file apt
reading config file rsyslog
Handling 2 logs
rotating pattern: /var/log/syslog  weekly (4 rotations)
renaming /var/log/syslog to /var/log/syslog.1

Qué significa: Logrotate puede parsear la configuración y tiene intención de rotar syslog semanalmente con 4 rotaciones.

Decisión: Si dependes solo de journald, ajusta SystemMaxUse y SystemMaxFileSize en /etc/systemd/journald.conf. De lo contrario /var eventualmente dará un golpe de estado.

Tarea 14: Comprueba persistencia y límites de tamaño de journald

cr0x@server:~$ sudo journalctl --disk-usage
Archived and active journals take up 384.0M in the file system.

Qué significa: Los journals están consumiendo disco. Eso está bien—hasta que no lo está.

Decisión: Si esto sube impredeciblemente, ponle un tope y envía logs fuera del host. Si lo mantienes volátil, acepta que un reboot borra tu escena del crimen.

Tarea 15: Encuentra servicios que se inician automáticamente (y no deberían)

cr0x@server:~$ systemctl list-unit-files --type=service --state=enabled
UNIT FILE                         STATE   PRESET
cron.service                      enabled enabled
ssh.service                       enabled enabled
unattended-upgrades.service       enabled enabled
postgresql.service                enabled enabled
apache2.service                   enabled enabled

Qué significa: Apache está habilitado. Puede que sea intencional. Puede que sea un residuo de paquetes de prueba rápidos.

Decisión: Si un servicio no forma parte del propósito del sistema, deshabilítalo y elimínalo. Cada demonio habilitado es una potencial suscripción a CVE.

Tarea 16: Verifica que claves privadas TLS y secretos no sean legibles por todo el mundo

cr0x@server:~$ sudo find /etc/ssl -type f -name '*.key' -printf '%m %u %g %p\n'
640 root ssl-cert /etc/ssl/private/server.key

Qué significa: Modo 640, propietario root, grupo ssl-cert. Eso es típico en Debian/Ubuntu.

Decisión: Asegúrate de que solo el grupo de la cuenta de servicio pueda leerla. Si ves 644 o propiedad aleatoria, arréglalo de inmediato y audita quién la accedió.

Tarea 17: Verifica la salud del almacenamiento (SMART) antes de confiar en la máquina

cr0x@server:~$ sudo smartctl -H /dev/sda
smartctl 7.3 2022-02-28 r5338 [x86_64-linux-6.5.0-21-generic] (local build)
=== START OF READ SMART DATA SECTION ===
SMART overall-health self-assessment test result: PASSED

Qué significa: El disco reporta saludable (no es garantía, pero sí una línea base).

Decisión: Si falla o muestra sectores realocados en aumento, reemplaza el disco antes de empezar a creer que la reinstalación “lo arregló”.

Tarea 18: Si usas ZFS, confirma el estado del pool y programa scrubs

cr0x@server:~$ sudo zpool status
  pool: tank
 state: ONLINE
  scan: scrub repaired 0B in 00:12:44 with 0 errors on Sun Feb  1 03:10:02 2026
config:

        NAME        STATE     READ WRITE CKSUM
        tank        ONLINE       0     0     0
          sdb       ONLINE       0     0     0
          sdc       ONLINE       0     0     0

errors: No known data errors

Qué significa: El pool está online, el último scrub no encontró errores.

Decisión: Si el estado es DEGRADED, trátalo como urgente. También confirma que los scrubs estén programados (cron/systemd timer) para que la degradación por bit rot no sea un hobby sorpresa.

Tarea 19: Confirma permisos en rutas de datos críticas (y consistencia UID/GID)

cr0x@server:~$ sudo stat -c '%U %G %a %n' /srv /srv/myapp /srv/myapp/data
root root 755 /srv
myapp myapp 750 /srv/myapp
myapp myapp 700 /srv/myapp/data

Qué significa: Los datos están restringidos. La cuenta de servicio posee sus datos. Bien.

Decisión: Si ves directorios de datos propiedad de root para servicios de aplicación, probablemente “lo arreglarás” más tarde con chmod -R y causarás daños colaterales. Establece la propiedad correctamente ahora.

Tarea 20: Verifica que existan backups y sean restaurables (la única prueba que cuenta)

cr0x@server:~$ sudo restic -r /backups/restic repo snapshots
repository 2f1a... opened (version 2, compression level auto)
ID        Time                 Host        Tags        Paths
c31e9f5a  2026-02-04 02:00:12  server                  /etc /srv/myapp

Qué significa: Existe una instantánea. Eso aún no es confianza.

Decisión: Realiza una restauración dirigida a un directorio temporal y verifica checksums/arranque del servicio. Los backups sin restauraciones son solo arte performativo.

Broma #2: Si nunca has probado una restauración, tu estrategia de backup es básicamente “pensamientos y plegarias con disco extra”.

Tres micro-historias corporativas (cómo falla esto en empresas reales)

1) Incidente causado por una suposición errónea: “Solo es accesible internamente”

Una empresa mediana reconstruyó un servidor de métricas tras una falla de disco. El ingeniero hizo lo que muchos hacemos cuando estamos cansados: instaló el exporter, confirmó que los dashboards estaban verdes y siguió adelante. La suposición era que el servidor vivía “en la red privada”.

Lo hacía, en cierto modo. La nueva imagen de cloud venía con una IP pública asignada por defecto, y los grupos de seguridad se copiaron de una plantilla usada para otro rol. El exporter escuchaba en 0.0.0.0:9100. Sin autenticación. Sin regla de firewall en el host. El dashboard funcionaba, por tanto todo estaba “bien”.

En días, el servidor mostró picos extraños y tráfico saliente. Nada dramático, solo lo suficiente para activar una alerta de facturación. La respuesta a incidentes encontró escáneres oportunistas tirando metadata e intentando endpoints conocidos débiles. El exporter en sí no era la joya de la corona, pero fue una fuga de inventario: versiones de kernel, filesystems montados, interfaces de red, y a veces detalles del entorno vía collectors de textfile.

La causa raíz no fue el exporter. Fue la suposición de que la ubicación en la red equivale a seguridad. La solución fue simple: denegar inbound por defecto en el firewall del host, enlazar servicios internos solo a interfaces internas, y gestionar explícitamente reglas de firewall en la nube por rol—nada de plantillas “suficientemente buenas”.

La lección quedó: “Interno” no es una propiedad de tus sentimientos. Es una propiedad de tablas de enrutamiento, reglas de firewall y de lo que realmente está escuchando.

2) Optimización que salió mal: desactivar actualizaciones para “evitar reboots”

Un equipo fintech tenía una cultura de uptime estricto y miedo a reboots sorpresa del kernel. Tras una reinstalación, desactivaron unattended upgrades y se dijeron que parchearían en una ventana mensual. Luego lo mensual se volvió trimestral, porque siempre había una campaña y siempre una razón.

Optimizaron para menos reboots y obtuvieron exactamente eso. También obtuvieron un userspace cada vez más obsoleto, incluyendo una build de OpenSSL con vulnerabilidades conocidas. Nadie lo notó porque todo funcionaba, y el monitoreo estaba enfocado en latencia, no en CVEs.

Eventualmente, un escaneo de seguridad rutinario encendió todas las alarmas. La reacción fue previsible: parches de emergencia, reboots de emergencia, aprobaciones de cambio de emergencia. La “optimización” produjo justamente lo que intentaba evitar, solo que llegó a las 2 a.m. con la gerencia en la llamada de crisis.

La solución no fue “volver a activar updates y rezar”. Implementaron un pipeline de parches: staging primero, producción después, y una cadencia predecible con plan de rollback. La cultura cambió también: reboots programados se volvieron normales, y los “reboots sorpresa” pasaron a ser síntoma de incidente, no riesgo aceptado.

Si vas a desactivar actualizaciones automáticas, te estás comprometiendo a ser mejor que la automatización. La mayoría de las organizaciones no lo son.

3) Práctica aburrida pero correcta que salvó el día: montajes separados y propiedad estricta

Una empresa logística tenía una flota de servidores de aplicación que se reconstruían con frecuencia—cambios de hardware, upgrades de SO, lo que sea. Su línea base incluía filesystems separados: / pequeño y estable, /srv para datos de aplicación, y /var dimensionado para logs. Era el tipo de configuración de la que nadie presume en conferencias.

Un fin de semana, una nueva versión se lanzó con logging de debug dejado por accidente. El volumen de logs explotó. En un layout de un solo filesystem, esa es la reacción en cadena clásica: / se llena, los servicios fallan, SSH se vuelve inestable, y la recuperación es un caos porque ni siquiera puedes escribir un archivo temporal.

Aquí, /var se llenó, sonaron alertas, la app se degradó y el SO se mantuvo saludable. SSH permaneció estable. Rotaron logs, bajaron el nivel de logging y el sistema se recuperó sin corrupción de filesystem ni reconstrucción de emergencia.

El postmortem fue corto. No porque no pasara nada—porque el radio de impacto quedó contenido por decisiones aburridas tomadas en la reinstalación meses antes. Montajes separados, rotación sensata y propiedad correcta no son glamorosos. Son cómo sobrevives a tu propio software.

Errores comunes: síntomas → causa raíz → solución

1) Síntoma: “SSH funcionó ayer, ahora estoy bloqueado”

Causa raíz: Firewall endurecido sin validar acceso desde la IP real del admin; o se deshabilitó PasswordAuthentication antes de desplegar claves; o AllowUsers configurado incorrectamente.

Solución: Usa acceso por consola para revertir. Valida sshd -T e intenta login solo por claves desde una segunda sesión antes de cerrar la consola. Restringe SSH por IP de origen solo después de confirmar rutas de acceso estables.

2) Síntoma: “El servicio está en ejecución pero inalcanzable”

Causa raíz: Proceso ligado a 127.0.0.1 o interfaz equivocada tras la reinstalación; o firewall de host con denegar por defecto sin permitir explícitamente; o desajuste en firewall de la nube.

Solución: Revisa ss -lntup para confirmar direcciones bind. Confirma reglas de firewall en host y en la nube. No asumas que “en ejecución” implica “alcanzable”.

3) Síntoma: “El espacio en disco sigue desapareciendo”

Causa raíz: journald o logs de aplicación sin límite; dumps de core habilitados con volcados grandes; archivos tmp acumulándose; archivos borrados pero abiertos.

Solución: Limita uso de journald, configura logrotate y usa lsof +L1 para encontrar archivos borrados abiertos. Pon rutas de escritura intensiva en montajes separados y alerta pronto.

4) Síntoma: “Los permisos son correctos pero la app no puede leer/escribir”

Causa raíz: Desajuste UID/GID tras reinstalación; volúmenes de contenedor montados propiedad host root; ACLs faltantes; negación SELinux/AppArmor.

Solución: Verifica id myapp y propiedad en disco. Si usas SELinux/AppArmor, revisa denegaciones y etiqueta perfiles correctamente en lugar de chmod ciegamente.

5) Síntoma: “TLS falla de repente: certificado no válido aún / caducado”

Causa raíz: Hora no sincronizada; confusión de zona horaria; RTC mal configurado; NTP bloqueado.

Solución: Arregla la sincronización horaria primero (timedatectl, chrony). No renueves certificados hasta que el reloj sea sensato o perseguirás fantasmas.

6) Síntoma: “El rendimiento es terrible tras reinstalar”

Causa raíz: Driver de almacenamiento equivocado, firmware faltante, RAID/ZFS degradado, o ajustes de IO scheduler/cola reseteados; o thrashing de swap por cambios en configuración de memoria.

Solución: Empieza con iostat, vmstat y chequeos de salud de almacenamiento. Verifica estado RAID/ZFS. Confirma que estás en la pila de kernel/driver pretendida.

7) Síntoma: “Los backups tienen éxito pero las restauraciones fallan”

Causa raíz: Backups capturando rutas equivocadas, permisos/ACLs faltantes, o claves de cifrado no almacenadas de forma segura; procedimiento de restauración nunca validado.

Solución: Haz un drill de restauración: restaura a una ruta temporal, valida integridad y arranca el servicio usando la configuración restaurada. Trata los pasos de restauración como código y automatízalos.

Preguntas frecuentes

1) ¿Qué debo asegurar primero después de reinstalar?

La exposición de SSH y la política de entrada de red. Parchea el SO base, endurece SSH (claves, no root, sin contraseñas cuando sea posible) y establece un firewall con denegar inbound por defecto y permisos explícitos.

2) ¿Debo deshabilitar la autenticación por contraseña en SSH de inmediato?

Solo después de verificar el acceso por claves desde una sesión separada y tener acceso por consola. Desactiva contraseñas pronto, pero no lo hagas como el primer cambio en un host accesible únicamente de forma remota.

3) ¿Está bien permitir SSH desde cualquier lugar si uso claves fuertes?

Es tolerable, no óptimo. Las claves fuertes reducen ataques por credenciales, pero aun así recibes ruido de fuerza bruta, intentos de exploits y mayor exposición. Restringe por IP de origen o VPN cuando puedas.

4) ¿Cómo decido entre UFW, nftables y firewalld?

Elige el que tu equipo pueda operar de forma consistente. UFW es simple y común en Ubuntu. nftables es potente y directo. firewalld está bien en entornos ya estandarizados en él. La consistencia vence a la preferencia.

5) Después de reinstalar, ¿por qué se rompen los permisos de mi app aunque los archivos parezcan correctos?

La deriva UID/GID es clásica. El nombre de usuario puede coincidir, pero los IDs numéricos no. También revisa ACLs y negaciones SELinux/AppArmor. Arregla el mapeo de identidad primero; evita chmod -R como “solución”.

6) ¿Debería cifrar discos en servidores?

Si tienes riesgo de acceso físico, preocupaciones multi-tenant, requisitos de cumplimiento o envías discos para RMA, sí. LUKS añade complejidad operativa (desbloqueo al arranque, gestión de claves). Decide deliberadamente y prueba arranque y recuperación.

7) ¿Cuánto logging es “suficiente” después de reinstalar?

Suficiente para responder: quién inició sesión, qué cambió, qué falló y qué hizo el sistema antes de fallar. Como mínimo: logs de auth, logs del sistema, logs de servicio y sincronización horaria. Envía fuera del host si el riesgo de compromiso es real.

8) ¿Cuál es la forma más rápida de detectar un servicio expuesto accidentalmente?

ss -lntup en el host, más un escaneo de puertos externo desde un punto de vista conocido. La vista del host te dice qué escucha; el escaneo externo te dice qué es alcanzable a través de firewalls.

9) ¿Realmente necesito una prueba de restauración justo después de reinstalar?

Sí. La reinstalación es cuando las suposiciones cambian: rutas, permisos, claves de cifrado, nombres de servicios. Una prueba de restauración ahora es barata. En un incidente, marca la diferencia entre recuperar y lamentar.

10) ¿Cuál es un cambio de endurecimiento que la gente exagera?

Cabeceras de seguridad y ajustes cripto antes de haber clavado identidad, parches, firewall y backups. No ganas puliendo la cerradura mientras dejas la puerta del garaje abierta.

Siguientes pasos prácticos

  1. Ejecuta el inventario de puertos en escucha y haz que cada puerto abierto se justifique.
  2. Establece denegar inbound por defecto en el firewall del host y permite explícitamente SSH desde orígenes conocidos.
  3. Endurece SSH con claves, sin login root y sin contraseñas (tras la validación).
  4. Establece una línea base de identidad: cuentas admin, reglas sudo y usuarios de servicio con mínimo privilegio.
  5. Haz el almacenamiento aburrido: verifica montajes, permisos, rotación y comprobaciones de salud de disco.
  6. Demuestra los backups restaurando algo real y arrancando un servicio con ello.
  7. Activa las señales aburridas: sincronización horaria, límites de retención de logs y envío de logs fuera del host cuando proceda.
  8. Escribe la línea base: salidas de comandos clave, versiones, reglas de firewall y expectativas de propiedad—para que tu yo futuro pueda diffear la realidad contra la intención.

Si no haces otra cosa: asegúrate el acceso remoto, pon un firewall con denegar inbound por defecto y prueba una restauración. Todo lo demás es más fácil cuando no estás en llamas.

← Anterior
Convertir MBR a GPT sin reinstalar (con herramientas integradas)
Siguiente →
Entregabilidad de correo: la política DMARC que evita la suplantación sin perder correo

Deja un comentario