Cumplimiento

Auditar un servidor Linux heredado: qué revisar antes de fiarte de él

Por Equipo Cloud Privado · · 22 min de lectura
Auditoría en pantalla: rkhunter marca un fichero oculto y un binario alterado, junto al registro de accesos fallidos

Un vistazo en 30 segundos

  • Auditar antes de tocar. Primero se documenta lo que hay, después se cambia. Un servidor heredado se describe con hechos, no con lo que cuenta quien lo entrega.
  • Nueve bloques: sistema, accesos, red, procesos, persistencia, ficheros, kernel, registros y recursos. En ese orden, porque cada uno explica al siguiente.
  • Si hay sospecha de intrusión, cambia todo: no reiniciar, aislar por red, tomar una instantánea del disco y analizarla desde fuera. En un sistema manipulado, ps, ss y ls te enseñan la realidad que alguien ha decidido que veas.
  • Hay una comprobación que cuesta dos minutos y descarta media auditoría: la versión. Debian 12 bookworm dejó el soporte completo el 11 de julio de 2026 —hace mes y medio— y Ubuntu 22.04 LTS se queda sin soporte estándar en mayo de 2027.
  • Si solo hay tiempo para un bloque, el de accesos: cuentas con contraseña activa, reglas de sudo y la configuración efectiva de SSH con sshd -T, que no siempre es lo que pone en el fichero.
  • Cuando la máquina es virtual, la auditoría no termina en el invitado. Un contenedor LXC comparte kernel con el nodo, y auditar el invitado no dice nada del hipervisor.
  • El entregable no es una lista de hallazgos: es una línea base —AIDE, etckeeper, la configuración en Ansible— para que la próxima persona no vuelva a empezar de cero.

Hay una escena que se repite en cada migración: alguien pasa un fichero con IPs, usuarios y contraseñas, y con eso se da por hecha la entrega. Pero unas credenciales no dicen qué hace la máquina, quién más puede entrar, qué se ejecuta solo a las tres de la mañana ni cuándo se aplicó el último parche.

Nos pasa cuando entra un cliente nuevo con su parque, cuando se cambia de proveedor y cuando alguien pide mover a infraestructura propia unos servidores que llevan años funcionando sin que nadie los mire. Y la respuesta siempre es la misma: antes de instalar nada, cambiar una configuración o dar la máquina por buena, hay que auditarla.

El procedimiento que sigue está pensado para Debian y Ubuntu, que es lo que más nos encontramos, con las equivalencias para Red Hat Enterprise Linux, Rocky, AlmaLinux, Fedora, openSUSE y Arch. Va en nueve bloques y termina donde tiene que terminar: en una línea base.

Los nueve bloques de una auditoría de servidor Linux, en orden El recorrido empieza por contener y preservar: aislar la máquina, tomar una instantánea del disco y registrar la sesión, sobre todo si hay sospecha de intrusión. Después vienen nueve bloques encadenados: qué sistema es y qué parches le faltan; quién puede entrar y con qué privilegios; qué escucha en la red y qué permite el cortafuegos; qué procesos hay detrás de esos puertos; qué se ejecuta solo mediante cron, temporizadores y unidades; qué ficheros han cambiado respecto a lo que instalaron los paquetes; el estado del kernel, sus módulos y el control de acceso obligatorio; los registros del sistema y de auditoría; y por último el disco, los inodos y el consumo de recursos. El recorrido termina endureciendo la configuración y fijando una línea base de integridad que sirva de referencia la próxima vez. 0. Contener y preservar aislar · snapshot · script 1. Sistema versión · parches · repos 2. Accesos usuarios · sudo · sshd -T 3. Red ss -tulpn · cortafuegos 4. Procesos /proc/pid/exe · rutas 5. Persistencia cron · timers · units 6. Ficheros dpkg -V · SUID · caps 7. Kernel módulos · MAC · sysctl 8. Registros journal · auth · auditd 9. Recursos df -h · df -i · /tmp Endurecer y fijar la línea base retirar · corregir · verificar · documentar
Los nueve bloques de una auditoría de servidor Linux, en orden El recorrido empieza por contener y preservar: aislar la máquina, tomar una instantánea del disco y registrar la sesión, sobre todo si hay sospecha de intrusión. Después vienen nueve bloques encadenados: qué sistema es y qué parches le faltan; quién puede entrar y con qué privilegios; qué escucha en la red y qué permite el cortafuegos; qué procesos hay detrás de esos puertos; qué se ejecuta solo mediante cron, temporizadores y unidades; qué ficheros han cambiado respecto a lo que instalaron los paquetes; el estado del kernel, sus módulos y el control de acceso obligatorio; los registros del sistema y de auditoría; y por último el disco, los inodos y el consumo de recursos. El recorrido termina endureciendo la configuración y fijando una línea base de integridad que sirva de referencia la próxima vez. 0. Contener y preservar aislar · snapshot · script 1. Sistema versión · parches · repos 2. Accesos usuarios · sudo · sshd -T 3. Red ss -tulpn · cortafuegos 4. Procesos /proc/pid/exe · rutas 5. Persistencia cron · timers · units 6. Ficheros dpkg -V · SUID · caps 7. Kernel módulos · MAC · sysctl 8. Registros journal · auth · auditd 9. Recursos df -h · df -i · /tmp Endurecer y fijar la línea base
El orden importa: cada bloque explica el siguiente. Los accesos son el que más riesgo concentra si hay que elegir uno.

Bloque 0: antes de ejecutar el primer comando

Si hay cualquier indicio de compromiso, el orden de trabajo cambia por completo.

Reiniciar destruye la memoria, las conexiones abiertas y los procesos vivos, así que es la última opción y no la primera. Lo razonable es aislar la máquina por red —grupo de seguridad, cortafuegos perimetral, VLAN—, tomar una instantánea del disco y analizar esa copia desde fuera. En un sistema manipulado, ps, ss, ls o el propio find pueden estar sustituidos y devolver una versión filtrada de la realidad.

Aquí la virtualización juega a favor. Si la máquina corre sobre Proxmox VE, la instantánea es inmediata y el disco se puede montar en solo lectura desde otra máquina virtual limpia, con herramientas en las que sí se confía. Esa es la diferencia entre auditar un sistema y auditar lo que ese sistema quiere contarte.

También conviene dejar rastro del propio trabajo. Registrar la sesión y guardar las salidas fuera del servidor evita perderlas si la máquina se reinstala:

script -a ~/auditoria-$(hostname)-$(date +%F).log
# al terminar: exit

Ese fichero, además, es el borrador del informe. En un entorno con ENS, RGPD o NIS2 encima, la diferencia entre «revisamos el servidor» y una evidencia con fecha, comandos y salidas es exactamente lo que te van a pedir.

1. Qué máquina es y desde cuándo

El objetivo de este primer bloque no es encontrar problemas, sino describir el sistema con precisión y contrastarlo con lo que nos han contado.

uname -a
cat /etc/os-release
hostnamectl
uptime -p
last reboot | head -5
systemd-detect-virt              # bare metal, kvm, lxc, docker...
cat /proc/cmdline                # parámetros de arranque del kernel

Salida típica de una máquina heredada:

$ cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.4 LTS"
VERSION_ID="22.04"

$ uptime -p
up 2 years, 47 days, 3 hours, 21 minutes

Dos años de uptime no son un mérito: significan que el kernel en ejecución no es el que hay instalado en disco. Todo lo que se haya parcheado en esos dos años sigue esperando un reinicio.

apt update && apt list --upgradable
needrestart -r l                 # qué servicios y si el kernel pide reinicio
unattended-upgrade --dry-run --debug
pro security-status              # Ubuntu: cobertura de main/universe y ESM

Y la comprobación que descarta media auditoría en dos minutos: si la versión sigue soportada.

VersiónEstado a 30 de agosto de 2026
Debian 13 trixieEstable desde el 9 de agosto de 2025; soporte hasta agosto de 2028
Debian 12 bookwormFuera de soporte completo desde el 11 de julio de 2026; LTS hasta junio de 2028
Ubuntu 26.04 LTSPublicada en abril de 2026; soporte estándar hasta mayo de 2031
Ubuntu 24.04 LTSSoporte estándar hasta mayo de 2029
Ubuntu 22.04 LTSSoporte estándar hasta mayo de 2027: quedan meses, no años
Ubuntu 20.04 LTSFuera de soporte estándar desde mayo de 2025; solo con ESM de Ubuntu Pro

Un servidor fuera de esas ventanas no está roto, pero deja de recibir actualizaciones de seguridad salvo que se contrate soporte ampliado. Si te encuentras un parque en Debian 12 o en Ubuntu 22.04, la conversación sobre el plan de actualización empieza hoy, no cuando salte el primer CVE sin parche.

Merece la pena mirar también de dónde vienen los paquetes, porque un repositorio de terceros olvidado es una vía de entrada permanente:

cat /etc/apt/sources.list
ls -la /etc/apt/sources.list.d/          # incluye ficheros .sources (deb822)
ls -la /etc/apt/keyrings/ /etc/apt/trusted.gpg.d/
apt-cache policy | head -40

apt-key está obsoleto: las claves deben vivir en ficheros propios referenciados con signed-by. Si aparecen claves en el llavero global antiguo, apúntalo para la fase de corrección.

2. Quién puede entrar y con qué privilegios

Si solo hay tiempo para un bloque, es este. Las cuentas sobreviven a las personas: alguien se marchó, la empresa cambió de proveedor y una llave se quedó ahí.

getent passwd | awk -F: '$3 >= 1000 && $3 < 65534 {print $1, $3, $7}'
awk -F: '($2 == "") {print $1" NO TIENE CONTRASENA"}' /etc/shadow
passwd -S -a | grep -v ' L '            # cuentas con contraseña activa
getent group sudo adm admin wheel docker lxd

En Debian y Ubuntu el grupo administrativo es sudo; en Red Hat y openSUSE, wheel. Y hay dos grupos que la gente no asocia con privilegios y lo son: pertenecer a docker o a lxd equivale en la práctica a ser root, aunque el usuario no aparezca en ningún fichero de sudo.

cat /etc/sudoers
ls -la /etc/sudoers.d/ && cat /etc/sudoers.d/*
sudo -l -U deploy                        # privilegios efectivos de un usuario

Lo que se busca es cualquier regla más amplia de lo necesario, empezando por el clásico NOPASSWD: ALL en una cuenta de servicio.

Después, SSH. Y aquí va el consejo que más disgustos ahorra: lee la configuración efectiva, no el fichero, porque casi todas las distribuciones actuales usan directorios de inclusión y lo que está escrito en sshd_config puede estar anulado tres ficheros más abajo.

sshd -T | grep -Ei 'permitrootlogin|passwordauthentication|pubkeyauthentication|maxauthtries|allowusers|allowgroups|port|listenaddress'
ls -la /etc/ssh/sshd_config.d/
find /home /root -name authorized_keys -exec ls -la {} \; 2>/dev/null
ssh-keygen -lf /home/alice/.ssh/authorized_keys     # tipo y huella de cada clave

Un detalle propio de Ubuntu que despista a cualquiera: desde la 22.10 el servidor SSH arranca por activación de socket, así que el puerto se define en ssh.socket y no en sshd_config. Cambiarlo solo en el fichero no surte efecto.

systemctl status ssh.socket
systemctl cat ssh.socket

Antes de reiniciar el servicio tras cualquier cambio, sshd -t valida la sintaxis. Y deja abierta una segunda sesión mientras pruebas: es la diferencia entre corregir un error y pedirle a alguien que vaya al centro de datos.

3. Qué escucha en la red y qué permite el cortafuegos

Cada servicio expuesto amplía la superficie de ataque, y un puerto que nadie recuerda haber abierto es motivo suficiente para investigar.

ss -tulpn                                # sockets en escucha y proceso asociado
ss -tupn state established               # conexiones activas
$ ss -tulpn
Netid State  Local Address:Port  Process
tcp   LISTEN 0.0.0.0:22          users:(("sshd",pid=842,fd=3))
tcp   LISTEN 0.0.0.0:80          users:(("nginx",pid=1264,fd=6))
tcp   LISTEN 127.0.0.1:3306      users:(("mysqld",pid=1102,fd=21))

Un servicio en 127.0.0.1 no es lo mismo que uno en 0.0.0.0, y un puerto abierto detrás de una política de denegación no representa el mismo riesgo que uno accesible desde Internet. Por eso hay que mirar las reglas, no solo los sockets:

ufw status verbose                       # Ubuntu, y Debian si está instalado
nft list ruleset                         # Debian 10+ usa nftables por defecto
iptables -L -n -v                        # sistemas con reglas heredadas
firewall-cmd --list-all                  # RHEL, Rocky, AlmaLinux, openSUSE

Debian en instalación mínima no trae ningún cortafuegos configurado, así que la ausencia de reglas es lo habitual y también es un hallazgo.

Y hay una capa que no se ve desde dentro de la máquina: la de fuera. En un cloud público son los grupos de seguridad; en infraestructura propia, las reglas del firewall del hipervisor y la microsegmentación de la red. Dar este bloque por cerrado mirando solo ufw es dejarse la mitad.

4. Procesos que no cuadran con el puerto que ocupan

Un puerto dice qué acepta conexiones; el proceso dice quién está detrás. Cruzar ambos datos es donde aparecen las sorpresas.

ls -la /proc/<pid>/exe                   # ruta real del binario
cat /proc/<pid>/cmdline | tr '\0' ' '
ls -la /proc/<pid>/cwd
ps -eo pid,ppid,user,etime,cmd --sort=start_time | tail -30

Tres patrones justifican mirar más despacio:

  • Un nombre que no reconocemos, sobre todo si parece aleatorio.
  • Un nombre conocido ejecutándose desde una ruta anómala: /tmp/nginx en vez de /usr/sbin/nginx.
  • /proc/<pid>/exe apuntando a un fichero marcado como (deleted): el binario se borró del disco mientras el proceso seguía vivo. Eso casi nunca es un descuido.

Si la máquina ejecuta contenedores, la auditoría se duplica. docker ps -a y podman ps -a muestran una segunda flota de servicios con sus propios puertos, sus propios usuarios y sus propias versiones sin parchear. Dos cosas que hay que mirar sí o sí: contenedores con --privileged y contenedores con /var/run/docker.sock montado dentro. Cualquiera de las dos equivale, en la práctica, a control del anfitrión. systemd-analyze security ayuda a ver qué unidades corren sin ningún confinamiento.

5. Lo que se ejecuta solo

Todo lo que arranca sin intervención humana o sobrevive a un reinicio es un mecanismo de persistencia, con intención o sin ella.

crontab -l -u root
for u in $(cut -f1 -d: /etc/passwd); do crontab -l -u "$u" 2>/dev/null | sed "s/^/[$u] /"; done
ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/ /etc/cron.weekly/
ls -la /var/spool/cron/crontabs/          # Debian y Ubuntu (RHEL: /var/spool/cron/)
systemctl list-timers --all
systemctl list-unit-files --state=enabled
atq

Y los rincones que casi nadie revisa, que son justo donde se esconde lo que no quiere ser encontrado: /etc/rc.local, /etc/profile.d/, los .bashrc y .profile de cada usuario, los scripts de /etc/update-motd.d/ en Ubuntu, las unidades de usuario con linger activado (loginctl show-user alice), los ganchos de initramfs y, sobre todo, /etc/ld.so.preload, que permite inyectar una biblioteca en todos los procesos del sistema. Ese fichero, en una máquina normal, no existe.

6. Ficheros que han cambiado y no deberían

Aquí se compara el disco con lo que los paquetes dicen haber instalado. Es la comprobación que más gente se salta y la que más rápido detecta un binario sustituido.

find / -xdev -mtime -7 -type f 2>/dev/null | grep -vE '^/(proc|sys|run|tmp|var/log|var/lib)'
dpkg -V                                   # incluido en Debian y Ubuntu
debsums -c                                # requiere el paquete debsums
rpm -Va                                   # RHEL, Rocky, AlmaLinux, Fedora, openSUSE

dpkg -V no necesita instalar nada y marca los ficheros cuyo hash no coincide con el del paquete. debsums se lee mejor, pero depende de que el paquete original incluyera sus sumas de control, así que puede dejar huecos. Un binario modificado en /usr/bin o /usr/sbin que no corresponda a una actualización conocida no es una curiosidad: es un hallazgo grave.

Los permisos especiales completan el cuadro, porque son el camino corto hacia una escalada de privilegios:

find / -xdev -type f -perm -4000 -exec ls -l {} + 2>/dev/null    # SUID
find / -xdev -type f -perm -2000 -exec ls -l {} + 2>/dev/null    # SGID
getcap -r / 2>/dev/null                                          # capabilities
find / -xdev -type d \( -perm -0002 -a ! -perm -1000 \) -exec ls -ld {} + 2>/dev/null
lsattr /etc/passwd /etc/shadow 2>/dev/null                       # atributo inmutable

Un conjunto SUID como passwd, sudo, mount o su es normal. Un intérprete, un editor o una copia de find con SUID, no. El proyecto GTFOBins documenta qué binarios legítimos se pueden abusar cuando se ejecutan con privilegios, y conviene tenerlo abierto mientras se revisa la lista.

7. Kernel y controles de bajo nivel

Si el kernel está manipulado, el resto de la auditoría pierde valor: un módulo malicioso puede ocultar procesos y conexiones a cualquier herramienta de espacio de usuario.

lsmod
cat /proc/sys/kernel/tainted              # 0 = ningún módulo sospechoso o propietario
modinfo -F signer <modulo>
cat /sys/kernel/security/lockdown 2>/dev/null
mokutil --sb-state 2>/dev/null            # estado de Secure Boot

Después, el control de acceso obligatorio —AppArmor en Debian, Ubuntu y openSUSE; SELinux en la familia Red Hat— y los parámetros del kernel:

aa-status                                 # Debian, Ubuntu, openSUSE
sestatus && getenforce                    # RHEL, Rocky, AlmaLinux, Fedora

sysctl kernel.randomize_va_space kernel.kptr_restrict kernel.dmesg_restrict \
       kernel.yama.ptrace_scope fs.protected_hardlinks fs.protected_symlinks \
       net.ipv4.ip_forward net.ipv4.tcp_syncookies \
       net.ipv4.conf.all.accept_redirects net.ipv4.conf.all.send_redirects \
       net.ipv4.conf.all.rp_filter
ParámetroValor de referenciaQué hace
kernel.randomize_va_space2ASLR completo
kernel.kptr_restrict2Oculta punteros del kernel a usuarios sin privilegios
kernel.dmesg_restrict1Restringe la lectura del búfer del kernel
kernel.yama.ptrace_scope1Limita qué procesos pueden depurar a otros
fs.protected_hardlinks / _symlinks1Cierra ataques clásicos de enlaces en directorios compartidos
net.ipv4.ip_forward0Salvo que la máquina sea router o nodo de contenedores
net.ipv4.tcp_syncookies1Resistencia a inundaciones SYN
accept_redirects / send_redirects0Evita redirecciones ICMP no solicitadas
net.ipv4.conf.all.rp_filter1Filtrado por ruta inversa

Cada valor depende del papel del servidor: un nodo que hace de router o que levanta contenedores necesita ip_forward activo, y copiar la tabla sin pensar rompe cosas. Esa es la diferencia entre endurecer y romper.

8. Registros: lo que pasó de verdad

La configuración cuenta lo que el servidor debería hacer. Los registros cuentan lo que hizo.

journalctl -p err..alert --since "7 days ago"
journalctl -u ssh --since "30 days ago"                  # en RHEL, sshd
grep -i "failed password" /var/log/auth.log | tail -50   # Debian y Ubuntu con rsyslog
grep -i "failed password" /var/log/secure | tail -50     # familia Red Hat
last -20
lastb -20                                                # fallidos (/var/log/btmp)
journalctl --verify                                      # integridad del journal

Si el sistema no tiene rsyslog, /var/log/auth.log no existirá y todo estará en el journal. Comprueba además que el journal es persistente y no se evapora en cada reinicio: journalctl --disk-usage y Storage=persistent en /etc/systemd/journald.conf. Un servidor que pierde sus registros al arrancar es un servidor sin memoria.

Si auditd está en marcha, aporta más que todo lo anterior junto:

auditctl -l
ausearch -m avc -ts today
aureport --summary

Y el matiz que lo condiciona todo: los registros locales de una máquina comprometida pueden estar editados. Si hay un colector remoto o un SIEM, esa copia vale más que la del propio servidor. Si no lo hay, ya tienes la primera recomendación del informe.

9. Disco, recursos y señales fuera de lugar

No es un control de seguridad, pero un servidor comprometido suele dejar huella aquí antes que en ningún otro sitio: un minero consume CPU, una inyección de registros llena el sistema de ficheros y los datos preparados para exfiltrar ocupan espacio en /tmp.

df -h && df -i                             # espacio y también inodos
du -sh /var/log/* 2>/dev/null | sort -rh | head -10
ls -la /tmp /var/tmp /dev/shm
iostat -x 1 5                              # paquete sysstat
systemd-cgtop

Los inodos son el fallo que más veces hemos visto diagnosticar mal: el disco tiene sitio, df -h dice que hay un 40 % libre y el sistema no puede escribir. Míralos siempre.

Las equivalencias, en una tabla

TareaDebian / UbuntuRHEL, Rocky, AlmaLinuxopenSUSEArch
Actualizaciones pendientesapt list --upgradablednf check-updatezypper list-updatescheckupdates
Servicios a reiniciarneedrestart -r ldnf needs-restarting -rzypper ps
Parcheo automáticounattended-upgradesdnf-automaticzypper-automatic
Verificar ficheros de paquetesdpkg -V, debsums -crpm -Varpm -Vapaccheck
Grupo administrativosudowheelwheelwheel
Cortafuegos por defectoufw / nftablesfirewalldfirewalldnftables
Control de acceso obligatorioAppArmorSELinuxAppArmor
Registro de accesos/var/log/auth.log/var/log/secure/var/log/messagesjournal
Crontabs de usuario/var/spool/cron/crontabs//var/spool/cron//var/spool/cron/tabs//var/spool/cron/

Lo que cambia cuando la máquina es virtual

Casi ninguna guía de auditoría dice esto, y en infraestructura moderna es la mitad del trabajo: auditar el invitado no audita el anfitrión.

Qué capa audita cada cosa en un servidor virtualizado Un nodo de virtualización contiene máquinas virtuales, que tienen su propio kernel y pueden a su vez ejecutar contenedores, y contenedores LXC, que comparten el kernel del anfitrión. Desde dentro de un invitado se pueden auditar el sistema, los accesos, la red, los procesos, la persistencia, los ficheros, los registros y los recursos, pero no la capa que hay debajo. El kernel, sus módulos, los parámetros sysctl y el arranque seguro solo se responden en el nodo cuando el invitado es un contenedor LXC, y los accesos al propio hipervisor, su cortafuegos y su calendario de parches no aparecen en ninguna auditoría hecha desde dentro de las máquinas que aloja. nodo de virtualización (anfitrión) Máquina virtual kernel propio Contenedor otra flota más Contenedor LXC sin kernel propio el bloque 7 no se responde aquí Kernel del nodo, sysctl, módulos, Secure Boot y sus propios accesos, cortafuegos y parches invisible desde dentro de cualquier invitado Desde el invitado bloques 1-6, 8 y 9 y el 7 solo si es VM Solo desde el nodo kernel y módulos sysctl efectivos accesos al hipervisor firewall del clúster parches del anfitrión
Qué capa audita cada cosa en un servidor virtualizado Un nodo de virtualización contiene máquinas virtuales, que tienen su propio kernel y pueden a su vez ejecutar contenedores, y contenedores LXC, que comparten el kernel del anfitrión. Desde dentro de un invitado se pueden auditar el sistema, los accesos, la red, los procesos, la persistencia, los ficheros, los registros y los recursos, pero no la capa que hay debajo. El kernel, sus módulos, los parámetros sysctl y el arranque seguro solo se responden en el nodo cuando el invitado es un contenedor LXC, y los accesos al propio hipervisor, su cortafuegos y su calendario de parches no aparecen en ninguna auditoría hecha desde dentro de las máquinas que aloja. nodo de virtualización Máquina virtual kernel propio Contenedor: otra flota más Contenedor LXC sin kernel propio: el bloque 7 no Kernel del nodo y sus accesos invisible desde el invitado Desde el invitado bloques 1-6, 8 y 9; el 7 solo si es VM Solo desde el nodo kernel, sysctl, accesos, firewall, parches
Desde dentro de un invitado no se ve la capa de abajo. Cada frontera necesita su propia auditoría y su propio responsable.

Tres consecuencias prácticas:

Un contenedor LXC comparte kernel con el nodo. Todo el bloque 7 de esta guía —módulos, sysctl, Secure Boot— se responde en el anfitrión, no dentro del contenedor, y un sysctl que ves dentro puede venir heredado. Es una de las diferencias que ya repasamos entre contenedores y máquinas virtuales, y en una auditoría se nota enseguida.

Parchear el invitado no parchea el nodo. Un parque de 40 contenedores actualizados sobre un hipervisor sin tocar en año y medio está sin parchear, por mucho que el inventario diga lo contrario. El nodo entra en el alcance de la auditoría con sus propios accesos, su propio SSH y su propio cortafuegos: y se audita con este mismo recorrido, empezando otra vez por los accesos.

Si el hipervisor es de otro, hay una parte que no puedes auditar. En un servicio gestionado por terceros esa capa la responde el proveedor, y conviene tener por escrito quién la revisa y con qué frecuencia. En infraestructura dedicada, en cambio, es tuya: se audita entera y no hay que pedirle permiso a nadie para hacerlo.

Del hallazgo a la decisión

Una lista de hallazgos sin prioridad no sirve de nada. Este es el triaje que usamos:

HallazgoQué suele significarQué hacer
Cuenta con contraseña activa y NOPASSWD: ALLAcceso administrativo sin trazabilidadRetirar hoy; sustituir por acceso nominal con clave
authorized_keys con claves sin dueño conocidoAlguien que ya no está, o peorRetirar, rotar y documentar quién entra
SSH con PasswordAuthentication yes expuestoFuerza bruta continua, y a veces con éxitoSolo clave; PermitRootLogin prohibit-password como paso intermedio
Servicio en 0.0.0.0 que debería ser internoConfiguración por defecto que nadie revisóEscuchar en 127.0.0.1 o cerrar por cortafuegos
dpkg -V marca un binario del sistemaActualización rara… o sustituciónParar y tratar como incidente hasta demostrar lo contrario
/etc/ld.so.preload existeInyección en todos los procesosIncidente. No reiniciar, aislar y copiar el disco
Kernel sin reiniciar desde hace mesesParches aplicados que no están en ejecuciónPlanificar ventana; needrestart dice qué falta
Sin cortafuegos y sin capa externaNadie decidió qué se exponeDefinir política de denegación por defecto
Journal no persistenteEl servidor pierde su memoria al arrancarStorage=persistent y, mejor, colector remoto

Endurecer y fijar una línea base

Con la foto hecha empieza el trabajo de corrección: retirar accesos que sobran, cerrar servicios que nadie usa, aplicar parches y dejar constancia del estado resultante.

Los valores de kernel se fijan en un fichero propio para que sobrevivan a las actualizaciones:

cat > /etc/sysctl.d/99-hardening.conf <<'EOF'
kernel.randomize_va_space = 2
kernel.kptr_restrict = 2
kernel.dmesg_restrict = 1
kernel.yama.ptrace_scope = 1
fs.protected_hardlinks = 1
fs.protected_symlinks = 1
net.ipv4.ip_forward = 0
net.ipv4.tcp_syncookies = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.rp_filter = 1
EOF
sysctl --system

En SSH, el objetivo habitual es acceso solo por clave, sin root directo y con la lista de usuarios acotada:

sshd -T | grep -E 'permitrootlogin|passwordauthentication|maxauthtries|allowgroups'
sshd -t && systemctl reload ssh

Para auditd, las reglas mínimas deberían vigilar /etc/passwd y /etc/shadow, /etc/sudoers y /etc/sudoers.d/, las llamadas execve y la carga y descarga de módulos del kernel.

Y por último, lo que convierte una auditoría en algo que sirve dentro de seis meses:

  • aide --init crea una referencia de integridad de ficheros contra la que comparar más adelante.
  • etckeeper versiona /etc en Git, así que cualquier cambio futuro queda con fecha y autor.
  • La configuración en Ansible o en un repositorio evita que la próxima persona empiece de cero.
  • Una copia verificada antes de tocar nada, que es la red debajo de todo lo demás.

Herramientas que aceleran el recorrido

Ninguna sustituye a mirar la máquina, pero acortan la fase de descubrimiento.

HerramientaPara quéLímite que conviene saber
LynisRecorrido general con hallazgos y sugerenciasDa una puntuación; no la conviertas en objetivo
OpenSCAP + SCAP Security GuideEvaluar contra CIS o STIGPerfil mal elegido = cientos de falsos hallazgos
usg (Ubuntu Security Guide)Aplicar y auditar perfiles CIS en UbuntuRequiere suscripción a Ubuntu Pro
rkhunter, chkrootkitComprobación adicional de rootkitsMuchos falsos positivos, y corren sobre herramientas ya sospechosas
osqueryConsultar el estado del sistema con SQL, en flotaEs inventario continuo, no una auditoría puntual
AIDELínea base de integridadLa base hay que guardarla fuera de la máquina

Sobre rkhunter y chkrootkit, la advertencia de siempre: si el sistema está comprometido de verdad, se están ejecutando sobre unas herramientas en las que ya no se puede confiar. Sirven para descartar, no para confirmar.

Lo que nos llevamos

No cambiar lo que no se entiende y no confiar en lo que no se ha verificado son dos reglas que ahorran incidentes. Una auditoría es el proceso de construir ese entendimiento: qué existe, qué esperábamos encontrar y qué no encaja. Solo después tiene sentido retirar accesos, corregir configuraciones y dejar una referencia para la próxima vez.

En las migraciones que hacemos, este recorrido es el primer día de trabajo, antes de mover una sola máquina: sirve para saber qué se está moviendo, para no arrastrar a la infraestructura nueva los problemas de la vieja y para entregar al cliente algo que casi nunca tenía, que es una descripción honesta de su propio parque. Si estás heredando servidores —de un proveedor, de un equipo que se fue o de una empresa que acabas de integrar— y prefieres que esa foto la haga alguien de fuera, cuéntanos qué tienes y la hacemos contigo.

Preguntas frecuentes

Si solo hay tiempo para revisar una cosa, ¿por dónde se empieza?

Por los accesos. Las cuentas con contraseña activa, las reglas de sudo y la configuración efectiva de SSH (sshd -T) concentran la mayor parte del riesgo inmediato en un servidor heredado.

¿Qué diferencia hay entre dpkg -V y debsums?

dpkg -V viene incluido en Debian y Ubuntu y compara los ficheros instalados con los hashes que registra dpkg. debsums es un paquete aparte, produce un informe más legible, pero solo verifica los paquetes que incluyen sus sumas de control, así que puede dejar huecos.

¿En qué se diferencia auditar Ubuntu de auditar Debian?

Ubuntu trae ufw preinstalado, usa activación por socket para SSH desde la 22.10 —el puerto se define en ssh.socket— y ofrece cobertura ampliada con Ubuntu Pro, con herramientas como pro security-status y usg. Debian en instalación mínima suele llegar sin cortafuegos configurado y con menos servicios activos.

¿Se puede auditar desde dentro un servidor que se sospecha comprometido?

Con reservas. Las herramientas del propio sistema pueden estar manipuladas, así que lo indicado es aislar la máquina, tomar una instantánea del disco y analizarla desde un entorno de confianza, sin reiniciar el servidor afectado. En una máquina virtual eso es cuestión de minutos.

¿Auditar los contenedores o las VM sustituye a auditar el hipervisor?

No. Un contenedor LXC comparte kernel con el nodo, y ni siquiera una máquina virtual dice nada del anfitrión que la ejecuta. El hipervisor tiene sus propios accesos, su propio cortafuegos y su propio calendario de parches, y entra en el alcance como una máquina más.

¿Cada cuánto conviene repetir la auditoría?

El recorrido completo, una vez al recibir la máquina y después cuando cambie algo estructural. El resto se automatiza: verificación de integridad con AIDE, cambios de /etc versionados con etckeeper, inventario continuo con osquery y revisión periódica de accesos, que es lo que más se degrada con el tiempo.

Fuentes

Imagen de portada: Open Security (opensecurity.es).