Recibir acceso root a un servidor Linux no significa que el sistema sea fiable. Puede ser un Debian recién desplegado, un Ubuntu Server que lleva años en producción, una máquina Rocky Linux heredada de otro proveedor o un servidor que haya sobrevivido a varias generaciones de administradores. Antes de actualizar paquetes, cerrar puertos o aplicar una plantilla de hardening conviene averiguar exactamente qué se ha heredado, quién puede entrar, qué se ejecuta, qué está expuesto y qué cambios no tienen una explicación clara.
Las claves de una auditoría de Linux en 30 segundos
- La primera fase debe recopilar información sin alterar innecesariamente el servidor: distribución, kernel, arranques, usuarios, repositorios, servicios y red.
- En Debian y Ubuntu conviene revisar APT,
dpkg, SSH, AppArmor y las actualizaciones de seguridad. - En RHEL, Rocky Linux, AlmaLinux y Fedora entran además DNF, RPM, firewalld y SELinux.
- Puertos, cron, timers, claves SSH, capacidades, SUID y servicios systemd ayudan a encontrar configuraciones inesperadas.
- Si aparecen indicios serios de compromiso, endurecer la máquina en caliente puede destruir evidencias; hay que tratarla como un incidente.
Una auditoría no puede demostrar por sí sola que un servidor está limpio. Si un atacante consiguió comprometer el kernel, sustituir binarios del sistema o manipular los registros, incluso herramientas como ps, ss o ls podrían proporcionar una visión incompleta.
Por eso el objetivo inicial es más realista: construir una fotografía del sistema, compararla con lo que debería existir y localizar todo aquello que no pueda explicarse.
Esta guía está especialmente pensada para Debian y Ubuntu Server, pero la mayoría de las comprobaciones son igualmente útiles en Fedora, Red Hat Enterprise Linux (RHEL), Rocky Linux, AlmaLinux, SUSE, openSUSE y otras distribuciones. Cuando el comando cambia según la familia, se indica expresamente.
Primero: saber qué servidor se está auditando y quién puede entrar
1. Identificar distribución, kernel, arquitectura y virtualización
Antes de cambiar nada hay que saber qué máquina se tiene delante.
Estos comandos funcionan en prácticamente cualquier distribución moderna:
hostnamectl
cat /etc/os-release
uname -a
uname -r
uname -m
uptime
last reboot | head -10
journalctl --list-boots
timedatectl
systemd-detect-virt
/etc/os-release es especialmente útil porque permite identificar la distribución y su versión sin depender de herramientas adicionales.
También interesa comprobar si se trata de hardware físico, una máquina virtual o un contenedor. Dentro de un contenedor, por ejemplo, muchas comprobaciones relacionadas con kernel, módulos o arranque pertenecen realmente al host y no al entorno que se está auditando.
Conviene revisar también discos, sistemas de archivos y puntos de montaje:
lsblk -f
findmnt
df -hT
df -ih
df -ih añade una comprobación que a veces se olvida: los inodos. Un sistema de archivos puede quedarse inutilizable por agotamiento de inodos aunque todavía disponga de espacio en gigabytes.
La hora también importa. Si timedatectl muestra una configuración incorrecta o el servidor ha perdido sincronización horaria, correlacionar logs con otros sistemas puede resultar mucho más complicado.
2. Comprobar la distribución y su estado de actualizaciones
Antes de ejecutar inmediatamente:
apt update
apt upgrade
es preferible terminar la recogida inicial de información.
Actualizar el servidor modifica archivos, bases de datos de paquetes, logs y fechas. En una auditoría de una máquina desconocida puede interesar conservar primero su estado inicial.
En Debian y Ubuntu pueden revisarse los paquetes instalados y la configuración de APT con:
dpkg-query -W -f='${Package}\t${Version}\n'
apt-cache policy
apt list --upgradable 2>/dev/null
También resulta importante saber de dónde llegan los paquetes:
grep -RhsE '^(deb |URIs:|Suites:|Components:|Signed-By:)' \
/etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/null
En instalaciones modernas puede haber archivos .sources con formato deb822, no únicamente las clásicas líneas deb.
Hay que prestar atención a repositorios de terceros que nadie reconoce, ramas antiguas, repositorios de pruebas y claves añadidas para proveedores que ya no se utilizan.
En Ubuntu puede comprobarse además la configuración de actualizaciones automáticas:
systemctl status apt-daily.timer apt-daily-upgrade.timer
grep -R "APT::Periodic" /etc/apt/apt.conf.d/ 2>/dev/null
Ubuntu Server utiliza unattended-upgrades para instalar automáticamente actualizaciones de seguridad en su configuración estándar. Eso no significa que deba darse por hecho que sigue funcionando: el paquete puede haberse eliminado, desactivado o modificado.
Puede revisarse con:
dpkg -l unattended-upgrades
systemctl list-timers | grep apt
ls -la /var/log/unattended-upgrades/ 2>/dev/null
En sistemas con Ubuntu Pro también puede resultar útil:
pro status
En Fedora, RHEL, Rocky Linux y AlmaLinux la comprobación equivalente pasa por RPM y DNF:
dnf repolist
dnf check-update
rpm -qa --last | head -30
En SUSE y openSUSE:
zypper repos
zypper list-updates
El objetivo todavía no es instalar nada. Se intenta descubrir si la máquina está mantenida, si utiliza repositorios esperados y si lleva meses acumulando actualizaciones.
3. Averiguar quién puede iniciar sesión
El siguiente paso es determinar quién tiene acceso al servidor.
Primero pueden localizarse las cuentas interactivas:
getent passwd | awk -F: '$7 !~ /(nologin|false)$/ {print $1, $3, $6, $7}'
También hay que comprobar algo especialmente sensible: cuentas adicionales con UID 0.
getent passwd | awk -F: '$3 == 0 {print $1, $6, $7}'
En un servidor normal lo habitual es encontrar únicamente root. Una segunda cuenta con UID 0 requiere una explicación.
Para revisar las cuentas que tienen un hash de contraseña configurado debe consultarse /etc/shadow, no /etc/passwd:
sudo awk -F: '$2 !~ /^(!|\*)/ {print $1}' /etc/shadow
Las cuentas con el campo de contraseña vacío son todavía más importantes:
sudo awk -F: '$2 == "" {print $1}' /etc/shadow
Un resultado aquí no implica automáticamente que exista acceso remoto sin contraseña, porque intervienen PAM, SSH y otras políticas, pero merece una revisión inmediata.
También conviene comprobar grupos administrativos.
En Debian y Ubuntu es habitual sudo:
getent group sudo
En RHEL, Fedora, Rocky Linux y AlmaLinux suele utilizarse wheel:
getent group wheel
Y las reglas reales no terminan en esos grupos:
sudo visudo -c
sudo grep -RniE 'NOPASSWD|ALL=\(ALL' /etc/sudoers /etc/sudoers.d 2>/dev/null
Una regla NOPASSWD: ALL no es necesariamente una vulnerabilidad. Puede formar parte de una automatización legítima, pero debe existir una razón concreta para ella.
4. Revisar SSH de verdad, no solo sshd_config
Mirar únicamente /etc/ssh/sshd_config puede ser insuficiente.
OpenSSH admite archivos adicionales mediante Include, configuraciones en sshd_config.d y bloques Match que cambian las reglas según usuario, dirección o host.
Una de las mejores comprobaciones es pedir directamente a sshd su configuración efectiva:
sudo sshd -T | grep -Ei \
'permitrootlogin|passwordauthentication|pubkeyauthentication|maxauthtries|authorizedkeysfile|authorizedkeyscommand|allowusers|allowgroups'
En Debian y Ubuntu también merece la pena revisar:
ls -la /etc/ssh/
ls -la /etc/ssh/sshd_config.d/ 2>/dev/null
grep -RniE '^(Include|Match|PermitRootLogin|PasswordAuthentication|AllowUsers|AllowGroups|AuthorizedKeys)' \
/etc/ssh/sshd_config /etc/ssh/sshd_config.d/ 2>/dev/null
Si existen reglas Match, se puede pedir a OpenSSH que evalúe una conexión concreta:
sudo sshd -T -C user=usuario,host=servidor,addr=192.0.2.10
Hay que sustituir esos valores por los apropiados para la auditoría.
Las claves autorizadas son otra parte esencial:
sudo find /root /home -xdev -type f -name authorized_keys -ls 2>/dev/null
No basta con contar archivos. Hay que revisar qué claves contienen, a quién pertenecen y si todavía deberían proporcionar acceso.
Además, AuthorizedKeysCommand permite obtener claves desde un programa externo, por lo que una búsqueda de authorized_keys no siempre muestra todas las formas posibles de autenticación.
5. Revisar puertos, conexiones y firewall
Un servidor puede tener cientos de procesos y decenas de servicios. La red ayuda a reducir rápidamente la investigación.
Para ver qué está escuchando:
sudo ss -lntup
Para revisar conexiones TCP establecidas:
sudo ss -tpn state established
Aquí interesa encontrar servicios que no encajan con la función declarada del servidor.
Una base de datos escuchando en:
127.0.0.1:5432
tiene una exposición muy diferente a otra escuchando en:
0.0.0.0:5432
o:
[::]:5432
Pero escuchar en todas las interfaces tampoco demuestra por sí solo que un puerto sea accesible desde Internet. Después hay que estudiar el firewall local y, en cloud, los grupos de seguridad, ACL y firewalls externos.
Para nftables:
sudo nft list ruleset
En Ubuntu es frecuente encontrar UFW:
sudo ufw status verbose
En Fedora y la familia RHEL es habitual firewalld:
sudo firewall-cmd --state
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --list-all
También pueden seguir existiendo reglas visibles mediante iptables:
sudo iptables -L -n -v
sudo ip6tables -L -n -v
En sistemas modernos estas órdenes pueden estar trabajando sobre una capa de compatibilidad con nftables, por lo que nft list ruleset suele proporcionar una imagen especialmente útil.
La pregunta que debe responderse para cada puerto es sencilla: qué servicio lo abre, por qué lo necesita, desde dónde debería ser accesible y qué regla permite llegar hasta él.
Después: procesos, persistencia e integridad del sistema
6. Relacionar cada servicio con su proceso real
Cuando aparece un PID sospechoso en ss, no conviene quedarse con el nombre que muestra el proceso.
Supongamos que el PID que interesa es 1842:
PID=1842
sudo readlink -f /proc/$PID/exe
sudo tr '\0' ' ' < /proc/$PID/cmdline
echo
sudo cat /proc/$PID/status
sudo ls -la /proc/$PID/cwd
sudo ls -la /proc/$PID/fd 2>/dev/null | head -50
Esto permite comparar nombre, ejecutable, argumentos, directorio de trabajo y archivos abiertos.
Un proceso llamado nginx que realmente ejecuta:
/tmp/.cache/nginx
merece mucha más atención que /usr/sbin/nginx.
También pueden localizarse procesos cuyo ejecutable fue eliminado mientras seguían funcionando:
sudo find /proc/[0-9]*/exe -lname '* (deleted)' -ls 2>/dev/null
Un resultado (deleted) no significa automáticamente malware.
Es relativamente frecuente después de actualizar una librería o un servicio que todavía no se ha reiniciado. La pregunta es qué archivo era, qué paquete lo proporcionaba y por qué el proceso sigue ejecutándolo.
Para obtener una vista general:
ps auxf
Y para localizar rápidamente procesos que están consumiendo CPU o memoria:
ps -eo pid,ppid,user,%cpu,%mem,lstart,cmd --sort=-%cpu | head -30
7. Buscar persistencia: systemd, cron y algo más
En Linux la persistencia no se limita a crontab.
Con systemd conviene empezar por:
systemctl list-unit-files --state=enabled
systemctl list-timers --all
systemctl --failed
systemd-delta
systemd-delta es especialmente interesante porque muestra configuraciones locales que sustituyen o amplían unidades proporcionadas por los paquetes.
Después puede inspeccionarse /etc/systemd/system:
sudo find /etc/systemd/system -maxdepth 3 -type f -o -type l
Para cron:
sudo crontab -l -u root
Y para revisar los usuarios:
for user in $(cut -d: -f1 /etc/passwd); do
sudo crontab -l -u "$user" 2>/dev/null
done
Además:
sudo ls -la /etc/cron.d/
sudo ls -la /etc/cron.hourly/
sudo ls -la /etc/cron.daily/
sudo ls -la /etc/cron.weekly/
sudo ls -la /etc/cron.monthly/
sudo cat /etc/crontab
No hay que olvidarse de las tareas programadas mediante at:
atq
Hay otras ubicaciones menos evidentes que merece la pena comprobar cuando algo no encaja:
sudo ls -la /etc/profile.d/
sudo ls -la /etc/modules-load.d/
sudo ls -la /etc/modprobe.d/
sudo ls -la /etc/udev/rules.d/
sudo ls -la /etc/rc.local 2>/dev/null
sudo cat /etc/ld.so.preload 2>/dev/null
Un /etc/ld.so.preload inesperado merece especial atención porque permite cargar bibliotecas antes que otras dependencias en procesos dinámicos.
En hosts con contenedores también hay otra fuente de persistencia: los propios runtimes.
Para Docker:
docker ps --no-trunc
docker ps -a --no-trunc
Para Podman:
podman ps --all
Hay que comprobar especialmente contenedores privilegiados, montajes del sistema anfitrión, acceso al socket de Docker y políticas de reinicio automático.
8. Verificar si los archivos de paquetes han cambiado
Esta es una de las diferencias prácticas más claras entre familias de distribuciones.
En Debian y Ubuntu puede utilizarse:
sudo dpkg --verify
dpkg compara determinados atributos de los archivos instalados con la información almacenada por el sistema de paquetes.
Otra herramienta conocida es debsums:
sudo apt install debsums
sudo debsums -s
Pero hay que entender su límite: debsums es útil para encontrar archivos modificados o dañados, no es una prueba forense de que el sistema sea fiable. La propia documentación de Debian advierte de sus limitaciones como herramienta de seguridad.
Además, instalar debsums durante una investigación modifica la máquina. Si se está preservando evidencia, no debería instalarse alegremente.
Para saber qué paquete debería proporcionar un archivo:
dpkg-query -S /usr/bin/ssh
En distribuciones RPM como RHEL, Fedora, Rocky Linux, AlmaLinux, SUSE y openSUSE puede verificarse el conjunto de paquetes con:
sudo rpm -Va
Y averiguar a qué paquete pertenece un archivo con:
rpm -qf /usr/bin/ssh
rpm -Va puede devolver cambios perfectamente legítimos, especialmente en archivos de configuración. El resultado necesita interpretación; no debe tratarse cada línea como una intrusión.
Una referencia rápida queda así:
| Distribución | Gestor | Verificación útil | Actualizaciones |
|---|---|---|---|
| Debian | APT / dpkg | dpkg --verify, debsums | apt |
| Ubuntu | APT / dpkg | dpkg --verify, debsums | apt, unattended-upgrades |
| RHEL | DNF / RPM | rpm -Va | dnf |
| Rocky Linux | DNF / RPM | rpm -Va | dnf |
| AlmaLinux | DNF / RPM | rpm -Va | dnf |
| Fedora | DNF / RPM | rpm -Va | dnf |
| SUSE/openSUSE | Zypper / RPM | rpm -Va | zypper |
| Arch Linux | pacman | pacman -Qkk | pacman |
9. Buscar SUID, SGID, capabilities y permisos peligrosos
Los binarios SUID siguen mereciendo una revisión:
sudo find / -xdev -type f -perm -4000 -exec ls -l {} + 2>/dev/null
Para SGID:
sudo find / -xdev -type f -perm -2000 -exec ls -l {} + 2>/dev/null
Muchos resultados serán normales. passwd, su u otros programas pueden necesitar privilegios especiales dependiendo de la distribución.
Lo interesante son binarios desconocidos, situados en ubicaciones poco habituales o que no pertenecen a un paquete esperado.
También hay que mirar capacidades Linux. Un binario puede realizar operaciones privilegiadas sin utilizar SUID:
sudo getcap -r / 2>/dev/null
Por ejemplo, capacidades como cap_sys_admin, cap_sys_ptrace, cap_dac_override o cap_net_admin pueden proporcionar poderes importantes dependiendo del ejecutable y el contexto.
Los directorios escribibles por cualquiera sin sticky bit también necesitan revisión:
sudo find / -xdev -type d -perm -0002 ! -perm -1000 -ls 2>/dev/null
Y los archivos world-writable:
sudo find / -xdev -type f -perm -0002 -ls 2>/dev/null
La clave vuelve a estar en el contexto. /tmp está diseñado para ser escribible por múltiples usuarios y utiliza sticky bit. Un archivo de configuración de root con permisos 0666 dentro de /etc sería una situación muy distinta.
10. Comprobar modificaciones recientes sin confundir cambio con ataque
Una búsqueda sencilla puede localizar archivos modificados durante los últimos siete días:
sudo find / -xdev -type f -mtime -7 \
! -path '/var/log/*' \
! -path '/var/cache/*' \
! -path '/tmp/*' \
2>/dev/null
Esta comprobación puede generar mucho ruido.
Actualizaciones, despliegues, rotaciones, herramientas de configuración y aplicaciones modifican legítimamente archivos. La fecha de modificación es una pista, no una prueba.
Puede ser especialmente útil cruzar un archivo inesperado con el gestor de paquetes.
En Debian y Ubuntu:
dpkg-query -S /ruta/al/archivo
En sistemas RPM:
rpm -qf /ruta/al/archivo
Si aparece un ejecutable dentro de /usr/bin, /usr/sbin o una ruta equivalente y ningún paquete reconoce el archivo, merece una explicación.
Para una vigilancia continuada de integridad existen herramientas como AIDE. Su utilidad es mucho mayor cuando la base de hashes se creó antes del posible incidente y se almacena de forma que el servidor comprometido no pueda modificarla.
Crear una línea base después de sospechar que la máquina ya está comprometida únicamente documenta el estado actual; no demuestra que ese estado sea bueno.
Kernel, controles de seguridad, logs y creación de una línea base fiable
11. Revisar el kernel y los módulos cargados
Una auditoría debería registrar al menos:
uname -r
cat /proc/cmdline
lsmod
cat /proc/modules
También interesa comprobar qué Linux Security Modules (LSM) están activos:
cat /sys/kernel/security/lsm 2>/dev/null
La presencia de un módulo desconocido no demuestra manipulación. Controladores de almacenamiento, red, virtualización, hardware específico o agentes corporativos pueden cargar módulos adicionales.
Cuando exista una línea base de una máquina equivalente, comparar ambos conjuntos puede ayudar mucho.
También puede consultarse:
sysctl kernel.modules_disabled
Si devuelve:
kernel.modules_disabled = 1
el kernel ya no permite cargar módulos adicionales hasta el siguiente arranque. Es una medida de endurecimiento útil en determinados servidores, pero no es universal porque algunos sistemas necesitan módulos cargados dinámicamente.
12. AppArmor en Debian y Ubuntu
AppArmor merece una sección propia porque tiene una presencia especialmente importante en las distribuciones basadas en Debian.
Ubuntu utiliza AppArmor como su sistema MAC (Mandatory Access Control) predeterminado, y Debian también lo integra en sus kernels y lo habilita de forma predeterminada desde Debian 10 en instalaciones estándar. Sin embargo, que AppArmor esté activo no significa que todos los procesos estén confinados.
La primera comprobación es:
sudo aa-status
También:
systemctl status apparmor
En Debian y Ubuntu los perfiles se encuentran normalmente en:
ls -la /etc/apparmor.d/
Hay que distinguir entre perfiles en modo enforce y complain.
enforce aplica realmente las restricciones.
complain registra lo que habría bloqueado, pero permite la operación.
Los eventos pueden consultarse mediante el journal:
sudo journalctl -k | grep -i apparmor
Que una aplicación importante aparezca sin perfil no significa automáticamente que la instalación sea vulnerable, pero sí ayuda a conocer el nivel real de confinamiento existente.
13. SELinux en RHEL, Fedora, Rocky Linux y AlmaLinux
En la familia Red Hat el equivalente habitual es SELinux.
La comprobación más rápida es:
getenforce
Y para obtener más información:
sestatus
Un servidor RHEL correctamente configurado suele trabajar con SELinux en modo:
Enforcing
Permissive mantiene las políticas y registra las infracciones, pero no bloquea las acciones. Disabled elimina esa capa de protección y además introduce complicaciones relacionadas con el etiquetado si posteriormente se pretende volver a activarla.
Para revisar denegaciones recientes:
sudo ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts today
Desactivar SELinux porque una aplicación deja de funcionar suele ser una mala solución. Primero debería averiguarse qué política está bloqueando la operación y si el comportamiento de la aplicación es realmente el esperado.
En Debian y Ubuntu también existe soporte para SELinux, y en otras distribuciones puede encontrarse AppArmor. La tabla siguiente refleja lo habitual, no una regla absoluta:
| Familia | Control MAC habitual |
|---|---|
| Ubuntu | AppArmor |
| Debian | AppArmor |
| RHEL | SELinux |
| Rocky Linux | SELinux |
| AlmaLinux | SELinux |
| Fedora | SELinux |
| SUSE/openSUSE | AppArmor |
| Arch Linux | Depende de la instalación |
14. Revisar ASLR, ptrace y otros sysctl de seguridad
Varios controles del kernel pueden inspeccionarse de una sola vez:
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.conf.all.accept_redirects \
net.ipv4.conf.default.accept_redirects \
net.ipv4.conf.all.send_redirects \
net.ipv6.conf.all.accept_redirects
Algunas referencias habituales para servidores son:
| Parámetro | Valor habitual de hardening | Precaución |
|---|---|---|
kernel.randomize_va_space | 2 | ASLR completo |
fs.protected_hardlinks | 1 | Normalmente recomendable |
fs.protected_symlinks | 1 | Normalmente recomendable |
kernel.kptr_restrict | 1 o superior | Puede afectar diagnóstico |
kernel.dmesg_restrict | 1 | Limita acceso no privilegiado |
kernel.yama.ptrace_scope | 1 o superior | Puede afectar depuración |
net.ipv4.ip_forward | 0 | Puede necesitar 1 un router, VPN o ciertos hosts de contenedores |
accept_redirects | 0 | Habitual en servidores |
send_redirects | 0 | Depende del papel de red |
Aquí no conviene copiar una plantilla y aplicarla ciegamente.
Un host Kubernetes, un router Linux, una VPN o una máquina utilizada para determinados contenedores puede necesitar parámetros que serían innecesarios en un servidor web convencional.
15. Seccomp y NoNewPrivileges: comprobar procesos concretos
Seccomp no es simplemente un interruptor global del servidor.
Es una protección que puede aplicarse a procesos concretos para limitar las llamadas al sistema que pueden ejecutar.
Para revisar un proceso:
PID=1842
grep -E 'NoNewPrivs|Seccomp|Seccomp_filters' /proc/$PID/status
El significado habitual de Seccomp es:
0 = sin seccomp
1 = strict
2 = filter
Pero encontrar:
Seccomp: 2
no demuestra por sí solo que el filtro sea bueno. Únicamente indica que existe un filtro.
Con systemd hay otra herramienta muy interesante para servidores modernos:
systemd-analyze security
Puede evaluarse un servicio concreto:
systemd-analyze security nginx.service
El resultado ayuda a descubrir servicios que podrían aprovechar opciones de aislamiento de systemd como NoNewPrivileges, ProtectSystem, PrivateTmp o restricciones sobre capacidades.
No debe interpretarse la puntuación como un escáner de vulnerabilidades. Evalúa principalmente propiedades de aislamiento de la unidad systemd.
16. Leer los logs como evidencia, no como verdad absoluta
La configuración muestra qué debería hacer el sistema. Los registros ayudan a reconstruir qué hizo realmente.
Para errores recientes:
sudo journalctl -p err..alert --since "7 days ago"
Para SSH puede utilizarse una orden compatible con los dos nombres de servicio habituales:
sudo journalctl -u ssh -u sshd --since "7 days ago"
En muchos Debian y Ubuntu con rsyslog también puede existir:
sudo grep -iE 'failed password|accepted password|accepted publickey' \
/var/log/auth.log 2>/dev/null | tail -100
Los accesos recientes:
last -Fai | head -30
Los intentos fallidos, cuando existe /var/log/btmp:
sudo lastb -Fai | head -30
También resulta útil comprobar arranques, apagados y reinicios:
last reboot | head -20
journalctl --list-boots
Si auditd está instalado:
systemctl status auditd
sudo auditctl -l
sudo aureport --summary
auditd puede proporcionar un registro mucho más detallado de determinadas actividades sensibles, pero solo si estaba instalado y tenía reglas adecuadas antes de aquello que se intenta investigar.
Instalarlo después no recuperará el pasado.
Los logs tampoco son una fuente infalible. Un atacante con privilegios suficientes puede eliminarlos o manipularlos. Los registros enviados previamente a un servidor remoto, SIEM o plataforma externa tienen mucho más valor durante una investigación.
17. CPU, disco, memoria e I/O también pueden revelar anomalías
La auditoría de seguridad y la de rendimiento no son lo mismo, pero a veces se cruzan.
Para una fotografía rápida:
free -h
df -hT
df -ih
uptime
Procesos por CPU:
ps -eo pid,ppid,user,%cpu,%mem,lstart,cmd --sort=-%cpu | head -30
Procesos por memoria:
ps -eo pid,ppid,user,%cpu,%mem,lstart,cmd --sort=-%mem | head -30
Directorios grandes:
sudo du -xhd1 /var 2>/dev/null | sort -h
sudo du -xhd1 /tmp 2>/dev/null | sort -h
sudo du -xhd1 /opt 2>/dev/null | sort -h
Si sysstat está instalado:
iostat -xz 1 3
Un proceso utilizando el 100 % de CPU no es automáticamente un criptominero, del mismo modo que varios gigabytes dentro de /tmp no demuestran preparación para exfiltrar información.
Pero ambos datos pueden señalar dónde seguir investigando.
18. No olvidar Alpine, Arch y servidores que no usan systemd
Buena parte de esta guía presupone systemd porque Debian, Ubuntu, Fedora, RHEL, Rocky Linux, AlmaLinux y muchas otras distribuciones lo utilizan.
No todos los Linux funcionan así.
Alpine Linux, muy utilizado en sistemas pequeños y contenedores, utiliza habitualmente OpenRC. En ese caso:
rc-status
rc-update show
sustituyen varias de las comprobaciones basadas en systemctl.
Arch Linux normalmente utiliza systemd, pero deja muchas más decisiones de seguridad al administrador. No debería darse por hecho que existe un firewall, un MAC concreto o una política equivalente a la instalación estándar de Ubuntu o RHEL.
Por eso detectar primero la distribución y el entorno no es un trámite. Determina cómo debe continuar el resto de la auditoría.
19. Qué revisar después de la auditoría
Una vez entendida la máquina puede comenzar el hardening.
El orden razonable consiste en eliminar accesos que ya no son necesarios, retirar servicios innecesarios, corregir reglas de firewall, revisar SSH y sudo, actualizar paquetes, solucionar configuraciones inseguras y activar los mecanismos de protección compatibles con la función del servidor.
Después conviene crear una línea base.
| Elemento | Qué debería documentarse |
|---|---|
| Sistema operativo | Distribución, versión y arquitectura |
| Kernel | Versión esperada y parámetros relevantes |
| Paquetes | Inventario y repositorios autorizados |
| Usuarios | Cuentas válidas y responsables |
| SSH | Claves, grupos y política de acceso |
| sudo | Usuarios y comandos autorizados |
| Red | Puertos y destinos permitidos |
| Firewall | Política y excepciones |
| Servicios | Unidades que deben estar activas |
| Persistencia | cron, timers y automatizaciones conocidas |
| MAC | AppArmor o SELinux y estado esperado |
| Integridad | Línea base desde una fuente confiable |
| Logs | Destino local y, preferiblemente, remoto |
| Actualizaciones | Política y responsable |
| Backups | Cobertura, retención y pruebas de restauración |
Esta fotografía convierte futuras auditorías en algo mucho más útil. En lugar de preguntarse si 37 servicios habilitados son normales, puede compararse el servidor con una situación conocida y descubrir que ayer había 36.
20. Cuándo dejar de auditar y empezar a tratarlo como un incidente
Hay un límite importante.
Si aparecen una cuenta UID 0 desconocida, una clave SSH no autorizada, un binario extraño con privilegios, un módulo del kernel inexplicable, mecanismos de persistencia ocultos o evidencias razonables de acceso no autorizado, el problema deja de ser simplemente de hardening.
A partir de ese momento modificar masivamente la máquina puede destruir información útil.
Según la criticidad del entorno puede ser necesario aislar el servidor, preservar discos o snapshots, recoger información volátil y seguir el procedimiento de respuesta a incidentes de la organización.
También cambia el concepto de confianza.
Encontrar y borrar un archivo malicioso no demuestra que el resto del servidor esté limpio. Si un atacante obtuvo root durante un periodo desconocido, en muchos escenarios resulta más seguro reconstruir la máquina desde imágenes y paquetes confiables, restaurar únicamente datos verificados y rotar las credenciales potencialmente expuestas.
Una auditoría inicial sirve precisamente para tomar esa decisión con más información.
Un servidor que responde al ping, ofrece correctamente una web y lleva 300 días sin reiniciarse puede estar perfectamente administrado o ser una máquina abandonada con años de configuración acumulada. Exteriormente ambos pueden parecer iguales.
La confianza comienza cuando usuarios, paquetes, servicios, puertos, procesos, logs y mecanismos de seguridad tienen una explicación coherente. Hasta entonces, el hecho de que Linux esté funcionando solo demuestra una cosa: que Linux está funcionando.
Preguntas frecuentes
¿Qué es lo primero que hay que revisar al recibir un servidor Linux?
Primero conviene identificar distribución, versión, kernel, arquitectura, fecha y hora, historial de arranques, tipo de virtualización, discos y repositorios. Después puede analizarse acceso, red, procesos y persistencia antes de modificar el sistema.
¿Cómo verificar archivos de paquetes en Debian y Ubuntu?
dpkg --verify permite comprobar archivos instalados frente a la información mantenida por dpkg. debsums también puede localizar cambios mediante sumas MD5, aunque Debian advierte de que tiene limitaciones como herramienta de seguridad y no demuestra que una máquina no haya sido comprometida.
¿Qué diferencia hay entre AppArmor y SELinux al auditar Linux?
Ambos son mecanismos de control de acceso obligatorio del kernel Linux. Ubuntu y Debian utilizan habitualmente AppArmor, mientras que RHEL, Fedora, Rocky Linux y AlmaLinux emplean principalmente SELinux. Durante una auditoría importa comprobar no solo si están instalados, sino si realmente están activos y aplicando políticas.
¿Es suficiente actualizar un servidor Linux para considerarlo seguro?
No. Las actualizaciones corrigen vulnerabilidades conocidas, pero no eliminan cuentas olvidadas, reglas sudo excesivas, claves SSH antiguas, servicios innecesarios, puertos expuestos o una intrusión previa. La actualización forma parte del hardening, no sustituye a la auditoría.
Fuentes:
- Debian Administrator’s Handbook, capítulo de seguridad, supervisión,
dpkg --verify,debsumsy AppArmor. - Debian Manpages, documentación actual de
debsumsy AppArmor. - Debian Wiki, documentación de uso de AppArmor en Debian.
- Ubuntu Server Documentation, recomendaciones de seguridad y actualizaciones automáticas con
unattended-upgrades. - Ubuntu Security Documentation, AppArmor y características de seguridad de Ubuntu 22.04, 24.04 y 26.04 LTS.
- Red Hat Enterprise Linux 10, documentación de SELinux y firewalld.

