Un servidor Linux puede estar respondiendo correctamente, servir tráfico y llevar meses sin errores aparentes y, aun así, arrastrar cuentas olvidadas, claves SSH antiguas, repositorios desconocidos, servicios innecesarios o configuraciones que nadie sabe explicar. Cuando un administrador recibe una máquina Debian, Ubuntu, RHEL, Rocky Linux, AlmaLinux, Fedora, SUSE o cualquier otra distribución, la primera tarea no debería ser actualizarla o endurecerla, sino entender qué sistema tiene delante.
Las claves de una auditoría Linux en 20 segundos
- Antes de modificar nada conviene identificar distribución, kernel, paquetes, usuarios, servicios, red y mecanismos de persistencia.
- Debian y Ubuntu requieren especial atención a APT, dpkg, SSH y AppArmor.
- En sistemas RHEL y derivados entran además RPM, DNF, SELinux y firewalld.
- Una anomalía aislada no demuestra compromiso: hay que contrastarla con la función real del servidor.
Actualizar inmediatamente con apt upgrade o dnf upgrade puede parecer lo más prudente, pero también cambia cientos de archivos, fechas, paquetes y registros. Si se está intentando descubrir qué ha ocurrido en un servidor heredado, conviene recopilar primero una fotografía suficientemente completa.
Tampoco existe un comando capaz de responder a la pregunta «¿está limpio este servidor?». Una auditoría consiste en relacionar numerosas señales y comprobar si todas tienen una explicación coherente.
Crear una fotografía fiable del servidor antes de cambiarlo
1. Identificar exactamente qué Linux se ha recibido
La primera comprobación es básica, pero determina buena parte de lo que vendrá después.
hostnamectl
cat /etc/os-release
uname -a
uname -r
uname -m
uptime
last reboot | head -10
journalctl --list-boots
timedatectl
systemd-detect-virtLenguaje del código: PHP (php)
/etc/os-release permite identificar la distribución y versión. uname muestra el kernel realmente cargado, algo que no siempre coincide con el último kernel instalado.
systemd-detect-virt también merece atención. No es lo mismo auditar un servidor físico que una máquina virtual, un contenedor LXC o un entorno Docker. Dentro de un contenedor, muchas características del kernel pertenecen al host y no al sistema que se está inspeccionando.
También conviene comprobar discos, montajes, espacio disponible e inodos:
lsblk -f
findmnt
df -hT
df -ih
Un servidor con un filesystem al 70 % puede parecer sano mientras se aproxima al agotamiento de inodos por millones de archivos pequeños.
La hora también debe ser coherente. Logs con timestamps incorrectos complican cualquier investigación posterior.
timedatectl
2. Revisar paquetes y repositorios en Debian y Ubuntu
En servidores Debian y Ubuntu la auditoría debería incluir tanto los paquetes instalados como los repositorios configurados.
dpkg-query -W -f='${Package}\t${Version}\n'
apt-cache policy
apt list --upgradable 2>/dev/nullLenguaje del código: JavaScript (javascript)
Para localizar repositorios:
grep -RhsE '^(deb |URIs:|Suites:|Components:|Signed-By:)' \
/etc/apt/sources.list /etc/apt/sources.list.d/ 2>/dev/nullLenguaje del código: PHP (php)
Las versiones recientes de Debian y Ubuntu también utilizan archivos .sources en formato deb822, así que revisar únicamente /etc/apt/sources.list puede dejar información fuera.
La pregunta relevante no es únicamente si existen actualizaciones pendientes. Hay que saber de dónde se están instalando los paquetes.
Un repositorio de terceros abandonado, una rama testing añadida temporalmente, un mirror desconocido o un repositorio de un proveedor que ya no se utiliza pueden introducir problemas de mantenimiento y seguridad.
Para las actualizaciones automáticas:
systemctl status apt-daily.timer apt-daily-upgrade.timer
systemctl list-timers | grep aptLenguaje del código: PHP (php)
Y cuando exista unattended-upgrades:
dpkg -l unattended-upgrades
grep -R "Unattended-Upgrade" /etc/apt/apt.conf.d/ 2>/dev/null
ls -la /var/log/unattended-upgrades/ 2>/dev/nullLenguaje del código: JavaScript (javascript)
En Ubuntu con Ubuntu Pro:
pro status
En distribuciones basadas en RPM las herramientas cambian.
RHEL, Rocky Linux, AlmaLinux y Fedora:
dnf repolist
dnf check-update
rpm -qa --last | head -30
SUSE y openSUSE:
zypper repos
zypper list-updatesLenguaje del código: PHP (php)
Arch Linux:
pacman -Q
pacman -Qu
La idea es la misma independientemente del gestor: saber qué está instalado, quién proporciona esos paquetes y cuánto tiempo lleva el sistema sin mantenimiento.
3. Usuarios: no limitarse a mirar /home
Una cuenta puede existir sin directorio en /home, y un usuario de servicio puede convertirse en un acceso interactivo si alguien cambia su shell.
Una primera visión:
getent passwd
Para mostrar cuentas con shell potencialmente interactiva:
getent passwd | awk -F: '$7 !~ /(nologin|false)$/ {print $1, $3, $6, $7}'Lenguaje del código: JavaScript (javascript)
Una comprobación especialmente importante es localizar cuentas con UID 0:
getent passwd | awk -F: '$3 == 0 {print $1, $6, $7}'Lenguaje del código: JavaScript (javascript)
En la mayoría de los servidores debería aparecer únicamente root.
También conviene revisar /etc/shadow:
sudo awk -F: '$2 == "" {print $1}' /etc/shadowLenguaje del código: JavaScript (javascript)
Un campo de contraseña vacío requiere investigación inmediata, aunque su existencia no implique automáticamente que SSH permita entrar sin contraseña.
Las cuentas administrativas también varían entre distribuciones.
Debian y Ubuntu:
getent group sudo
RHEL, Fedora, Rocky Linux y AlmaLinux:
getent group wheel
Pero los privilegios reales están en sudoers:
sudo visudo -c
sudo grep -RniE 'NOPASSWD|ALL=\(ALL' \
/etc/sudoers /etc/sudoers.d 2>/dev/nullLenguaje del código: JavaScript (javascript)
Encontrar NOPASSWD tampoco es automáticamente un problema. Puede ser necesario para automatización, configuración o despliegues. Lo importante es poder justificar cada regla.
4. SSH: comprobar la configuración efectiva
Una auditoría de SSH no debería consistir únicamente en abrir:
/etc/ssh/sshd_config
OpenSSH puede cargar ficheros adicionales y aplicar reglas diferentes mediante Match.
Es mucho más útil pedir al daemon su configuración efectiva:
sudo sshd -T
Para centrarse en algunos parámetros:
sudo sshd -T | grep -Ei \
'permitrootlogin|passwordauthentication|pubkeyauthentication|maxauthtries|authorizedkeysfile|authorizedkeyscommand|allowusers|allowgroups'Lenguaje del código: JavaScript (javascript)
Después conviene localizar configuraciones adicionales:
grep -RniE '^(Include|Match|PermitRootLogin|PasswordAuthentication|AllowUsers|AllowGroups|AuthorizedKeys)' \
/etc/ssh/sshd_config /etc/ssh/sshd_config.d/ 2>/dev/nullLenguaje del código: JavaScript (javascript)
Las reglas Match pueden hacer que la política cambie según usuario o dirección de origen. OpenSSH permite simular una conexión:
sudo sshd -T -C user=admin,host=server,addr=192.0.2.10
Los valores deben sustituirse por los correspondientes al entorno real.
Las claves SSH tampoco deberían darse por buenas por el mero hecho de estar en un authorized_keys.
sudo find /root /home -xdev -type f -name authorized_keys -ls 2>/dev/nullLenguaje del código: JavaScript (javascript)
Cada clave debería poder asociarse a una persona, automatización o sistema concreto.
También hay que comprobar si SSH obtiene claves mediante un comando externo:
sudo sshd -T | grep authorizedkeyscommand
Un servidor puede tener perfectamente acceso SSH autorizado sin que todas sus claves estén guardadas físicamente en /home.
De la red a la persistencia: descubrir qué está haciendo realmente
5. Ver qué está escuchando y quién lo abrió
Una de las comprobaciones con mejor relación entre tiempo invertido e información obtenida es:
sudo ss -lntup
Muestra sockets TCP y UDP en escucha y, con privilegios suficientes, el proceso asociado.
Después pueden revisarse conexiones activas:
sudo ss -tpn state established
Hay que relacionar cada servicio con la función del servidor.
Un PostgreSQL escuchando únicamente en localhost:
127.0.0.1:5432Lenguaje del código: CSS (css)
tiene una superficie de exposición distinta a:
0.0.0.0:5432Lenguaje del código: CSS (css)
o:
[::]:5432Lenguaje del código: CSS (css)
Pero escuchar en todas las interfaces tampoco significa necesariamente que el servicio pueda alcanzarse desde Internet. Falta comprobar el firewall.
En sistemas con nftables:
sudo nft list rulesetLenguaje del código: PHP (php)
Ubuntu puede utilizar UFW:
sudo ufw status verbose
RHEL, Fedora, Rocky Linux y AlmaLinux utilizan habitualmente firewalld:
sudo firewall-cmd --state
sudo firewall-cmd --get-active-zones
sudo firewall-cmd --list-allLenguaje del código: JavaScript (javascript)
Y todavía pueden encontrarse sistemas donde resulte útil revisar iptables:
sudo iptables -L -n -v
sudo ip6tables -L -n -v
En muchos Linux modernos iptables funciona sobre el backend nftables, por lo que conviene entender qué implementación está realmente utilizando la distribución.
Además, si el servidor está en AWS, Azure, Google Cloud, OpenStack o cualquier plataforma similar, la auditoría de red no termina dentro de Linux. También existen security groups, ACL, firewalls externos, balanceadores y reglas del proveedor.
6. Verificar qué binario hay detrás de cada PID
Los nombres de proceso pueden engañar.
Para estudiar un PID concreto:
PID=1842
sudo readlink -f /proc/$PID/exe
sudo tr '\0' ' ' < /proc/$PID/cmdline
echo
sudo cat /proc/$PID/status
sudo readlink -f /proc/$PID/cwdLenguaje del código: PHP (php)
También pueden inspeccionarse los descriptores abiertos:
sudo ls -la /proc/$PID/fd 2>/dev/null | head -50Lenguaje del código: JavaScript (javascript)
Un proceso llamado nginx no debería darse automáticamente por legítimo si su ejecutable real está en:
/tmp/.cache/nginx
También es interesante buscar procesos que continúan ejecutando binarios eliminados:
sudo find /proc/[0-9]*/exe -lname '* (deleted)' -ls 2>/dev/nullLenguaje del código: JavaScript (javascript)
El resultado (deleted) no significa malware.
Después de actualizar un paquete puede existir un proceso antiguo que todavía tenga abierto el ejecutable eliminado. Herramientas como needrestart, especialmente habituales en Debian y Ubuntu, pueden ayudar a detectar servicios que utilizan versiones antiguas tras una actualización.
La anomalía aparece cuando nadie puede explicar por qué sigue ejecutándose ese binario.
7. Auditar persistencia en systemd
Cron ya no es el único lugar donde buscar ejecución automática.
En cualquier distribución con systemd:
systemctl list-unit-files --state=enabled
systemctl list-timers --all
systemctl --failedLenguaje del código: PHP (php)
Una herramienta especialmente útil y poco utilizada es:
systemd-delta
Muestra configuraciones locales que modifican las unidades proporcionadas por los paquetes.
Puede descubrir, por ejemplo, que /usr/lib/systemd/system/nginx.service ha recibido un override en:
/etc/systemd/system/nginx.service.d/
Para revisar configuraciones locales:
sudo find /etc/systemd/system -maxdepth 3 \( -type f -o -type l \) -ls
También merece la pena inspeccionar servicios concretos:
systemctl cat ssh.service
systemctl cat nginx.serviceLenguaje del código: CSS (css)
Según la distribución el daemon SSH puede llamarse ssh.service o sshd.service.
8. Cron, at y otros puntos de persistencia
Cron continúa siendo imprescindible:
sudo crontab -l -u root
Para recorrer las cuentas:
for user in $(cut -d: -f1 /etc/passwd); do
sudo crontab -l -u "$user" 2>/dev/null
doneLenguaje del código: JavaScript (javascript)
Después:
sudo cat /etc/crontab
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/
Las colas at también cuentan:
atq
En una investigación más profunda pueden revisarse otros puntos:
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 cat /etc/rc.local 2>/dev/null
sudo cat /etc/ld.so.preload 2>/dev/nullLenguaje del código: JavaScript (javascript)
/etc/ld.so.preload merece especial atención si existe y contiene una biblioteca inesperada, ya que permite precargar librerías en programas enlazados dinámicamente.
En hosts con Docker o Podman también hay persistencia fuera de cron y systemd:
docker ps --no-trunc
docker ps -a --no-trunc
o:
podman ps --all
Aquí conviene relacionar cada contenedor con su imagen, montajes, red y política de reinicio.
Integridad, kernel y evidencias: cuándo dejar de confiar en la máquina
9. Verificar paquetes en Debian y Ubuntu
En Debian y Ubuntu puede utilizarse:
sudo dpkg --verify
Otra herramienta tradicional es debsums:
sudo debsums -s
Si no está instalada:
sudo apt install debsums
Pero esta última orden plantea un problema durante una investigación: instalar software altera el sistema que se está auditando.
Por eso debsums es mucho más útil si ya estaba disponible.
También tiene una limitación conceptual importante. Comparar checksums puede encontrar modificaciones, pero no demuestra que un servidor sea confiable. Si un atacante consiguió suficiente control, la información utilizada como referencia podría haber sido manipulada.
Para averiguar a qué paquete pertenece un archivo:
dpkg-query -S /usr/bin/ssh
En RHEL, Rocky Linux, AlmaLinux, Fedora y otros sistemas RPM:
sudo rpm -Va
Para un fichero concreto:
rpm -qf /usr/bin/ssh
En Arch:
pacman -Qkk
Una salida de rpm -Va, dpkg --verify o debsums necesita interpretación. Los archivos de configuración pueden modificarse legítimamente.
10. Revisar SUID, SGID y Linux capabilities
Los permisos especiales siguen siendo importantes.
SUID:
sudo find / -xdev -type f -perm -4000 -exec ls -l {} + 2>/dev/nullLenguaje del código: JavaScript (javascript)
SGID:
sudo find / -xdev -type f -perm -2000 -exec ls -l {} + 2>/dev/nullLenguaje del código: JavaScript (javascript)
Un listado largo no significa necesariamente que algo esté mal. Hay binarios legítimos que necesitan estos permisos.
La pregunta es cuáles son conocidos y cuáles no.
Linux capabilities también permiten otorgar privilegios concretos sin utilizar SUID:
sudo getcap -r / 2>/dev/nullLenguaje del código: JavaScript (javascript)
Capacidades como:
cap_sys_admin
cap_sys_ptrace
cap_dac_override
cap_net_admin
cap_sys_module
cap_sys_rawio
merecen una explicación clara cuando aparecen asignadas a ejecutables poco habituales.
Los archivos escribibles por cualquier usuario también son útiles para detectar malas configuraciones:
sudo find / -xdev -type f -perm -0002 -ls 2>/dev/nullLenguaje del código: JavaScript (javascript)
Y directorios world-writable sin sticky bit:
sudo find / -xdev -type d -perm -0002 ! -perm -1000 -ls 2>/dev/nullLenguaje del código: JavaScript (javascript)
11. AppArmor en Debian y Ubuntu
En Debian y Ubuntu una auditoría debería incluir AppArmor.
Para conocer su estado:
sudo aa-status
Y comprobar el servicio:
systemctl status apparmor
Los perfiles suelen encontrarse en:
ls -la /etc/apparmor.d/
Hay una diferencia importante entre un perfil en modo enforce y otro en modo complain.
enforce aplica las restricciones.
complain registra las acciones que habrían sido bloqueadas, pero no las impide.
Los eventos pueden buscarse en el journal:
sudo journalctl -k | grep -i apparmor
Ubuntu utiliza AppArmor como una de sus principales capas de Mandatory Access Control. Debian también lo integra y lo habilita de forma predeterminada en sus instalaciones estándar desde hace varias versiones.
Que AppArmor esté activo tampoco significa que todos los servicios estén confinados. aa-status permite comprobar cuántos perfiles están cargados y qué procesos están realmente sujetos a ellos.
12. SELinux en RHEL, Rocky, AlmaLinux y Fedora
En Red Hat Enterprise Linux y sus derivados el mecanismo habitual es SELinux.
getenforce
sestatus
Los estados principales son:
Enforcing
Permissive
Disabled
Enforcing aplica las políticas.
Permissive registra las infracciones pero no las bloquea.
Para buscar eventos:
sudo ausearch -m AVC,USER_AVC -ts today
Si una aplicación «solo funciona al desactivar SELinux», el problema todavía no está resuelto. Lo correcto es averiguar qué operación está bloqueando la política y si esa operación debería estar permitida.
13. Revisar parámetros de seguridad del kernel
Una comprobación compacta:
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_redirectsLenguaje del código: CSS (css)
Una referencia habitual sería:
| Parámetro | Valor habitual en servidor |
|---|---|
kernel.randomize_va_space | 2 |
fs.protected_hardlinks | 1 |
fs.protected_symlinks | 1 |
kernel.dmesg_restrict | 1 |
net.ipv4.ip_forward | 0 si no enruta tráfico |
accept_redirects | 0 en la mayoría de servidores |
send_redirects | 0 en la mayoría de servidores |
Estos valores no deben copiarse ciegamente.
Un servidor VPN, un router Linux, Kubernetes, determinados hosts Docker o plataformas de virtualización pueden necesitar parámetros diferentes.
La auditoría debe descubrir primero la función del nodo.
14. Módulos del kernel
Los módulos cargados pueden revisarse con:
lsmod
cat /proc/modules
También:
cat /proc/cmdline
Para saber si el sistema permite cargar más módulos:
sysctl kernel.modules_disabledLenguaje del código: CSS (css)
Un valor:
kernel.modules_disabled = 1
impide nuevas cargas de módulos hasta el siguiente reinicio.
Puede ser una buena medida de hardening para servidores muy estáticos, pero no es apropiada para todos los entornos.
También conviene saber qué LSM están activos:
cat /sys/kernel/security/lsm 2>/dev/nullLenguaje del código: JavaScript (javascript)
La mejor forma de encontrar un módulo extraño es comparar la máquina con una línea base conocida para ese tipo de servidor.
Sin una referencia, un módulo desconocido puede ser tanto un controlador perfectamente legítimo como algo que merece investigación.
15. Seccomp y NoNewPrivileges
Seccomp se aplica a procesos, no al servidor entero.
Para un PID concreto:
PID=1842
grep -E 'NoNewPrivs|Seccomp|Seccomp_filters' /proc/$PID/statusLenguaje del código: PHP (php)
El campo Seccomp suele mostrar:
0
1
2
donde 0 significa que no está habilitado, 1 corresponde a modo estricto y 2 a filtros.
Pero Seccomp: 2 no significa que el filtro esté bien diseñado. Solo confirma que existe.
En sistemas systemd hay otra herramienta muy interesante:
systemd-analyze security
Y para una unidad determinada:
systemd-analyze security nginx.serviceLenguaje del código: CSS (css)
Permite evaluar medidas como ProtectSystem, PrivateTmp, restricciones de namespaces, capabilities o NoNewPrivileges.
No es un escáner de vulnerabilidades. Sirve para ver cuánto aislamiento proporciona la unidad.
16. Logs de autenticación y sistema
En sistemas con systemd:
sudo journalctl -p err..alert --since "7 days ago"Lenguaje del código: JavaScript (javascript)
Para SSH:
sudo journalctl -u ssh -u sshd --since "7 days ago"Lenguaje del código: JavaScript (javascript)
En Debian y Ubuntu con /var/log/auth.log:
sudo grep -iE 'failed password|accepted password|accepted publickey' \
/var/log/auth.log 2>/dev/null | tail -100Lenguaje del código: JavaScript (javascript)
Accesos recientes:
last -Fai | head -30
Intentos fallidos:
sudo lastb -Fai | head -30
Reinicios:
last reboot | head -20
journalctl --list-bootsLenguaje del código: PHP (php)
Si auditd está disponible:
systemctl status auditd
sudo auditctl -l
sudo aureport --summary
auditd puede ofrecer información muy valiosa, pero solamente sobre aquello que estaba configurado para registrar.
Instalarlo hoy no permite reconstruir lo ocurrido la semana pasada.
Y existe otra limitación: los logs locales están dentro del propio sistema investigado. Si alguien obtuvo root, podría haberlos eliminado o modificado.
Por eso los logs centralizados y enviados en tiempo real a otro host o a un SIEM tienen mucho más valor durante un incidente.
17. Revisar recursos sin convertir cualquier consumo en un IOC
CPU:
ps -eo pid,ppid,user,%cpu,%mem,lstart,cmd --sort=-%cpu | head -30
Memoria:
ps -eo pid,ppid,user,%cpu,%mem,lstart,cmd --sort=-%mem | head -30
Disco:
df -hT
df -ih
Directorios:
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 -hLenguaje del código: JavaScript (javascript)
I/O, si sysstat está instalado:
iostat -xz 1 3
Un proceso usando mucha CPU no es automáticamente un criptominero. Un /tmp grande tampoco demuestra exfiltración.
Estas métricas sirven para encontrar anomalías que después hay que explicar.
18. No todos los servidores Linux utilizan systemd
Aunque Debian, Ubuntu, RHEL, Rocky, AlmaLinux, Fedora y muchas otras distribuciones utilizan systemd, no debería darse por hecho.
Alpine Linux utiliza normalmente OpenRC.
En ese caso:
rc-status
rc-update show
son más útiles que systemctl.
Arch Linux sí utiliza systemd normalmente, pero deja una parte importante de la configuración al administrador.
Tampoco debería asumirse que existe UFW, firewalld, AppArmor, SELinux o cualquier política concreta sin comprobarlo.
19. Una tabla de referencia rápida para varias distribuciones
| Área | Debian / Ubuntu | RHEL / Rocky / Alma / Fedora | SUSE / openSUSE | Arch |
|---|---|---|---|---|
| Paquetes | APT + dpkg | DNF + RPM | Zypper + RPM | pacman |
| Verificación | dpkg --verify, debsums | rpm -Va | rpm -Va | pacman -Qkk |
| MAC habitual | AppArmor | SELinux | AppArmor | Según configuración |
| Firewall frecuente | nftables / UFW | firewalld / nftables | firewalld / nftables | Según configuración |
| Servicios | systemd | systemd | systemd | systemd |
| Logs | journal + syslog según configuración | journal | journal | journal |
| SSH | OpenSSH | OpenSSH | OpenSSH | OpenSSH |
La tabla sirve como orientación. Linux permite sustituir prácticamente todos estos componentes y una instalación real puede no seguir el comportamiento habitual de su distribución.
20. Cuándo dejar de hacer hardening y pasar a respuesta a incidentes
Este es probablemente el punto más importante de toda la auditoría.
Encontrar un PermitRootLogin permisivo es un problema de configuración.
Encontrar una cuenta UID 0 que nadie reconoce es otra situación.
Encontrar un timer de systemd que ejecuta periódicamente un binario oculto en /tmp, una clave SSH desconocida, una biblioteca inesperada en /etc/ld.so.preload o un módulo del kernel sin explicación puede indicar algo más serio.
En ese momento empezar a «limpiar» la máquina puede ser contraproducente.
Reiniciar elimina procesos y memoria.
Actualizar sustituye archivos.
Borrar una cuenta destruye información.
Eliminar un binario puede hacer desaparecer una evidencia.
Si existe una sospecha razonable de compromiso, la prioridad debería pasar a aislar, preservar y analizar, siguiendo el procedimiento de respuesta a incidentes de la organización.
Y si un atacante pudo conseguir root, recuperar la confianza únicamente eliminando lo que parece malicioso resulta complicado.
En numerosos entornos será preferible reconstruir el servidor desde una imagen conocida, instalar paquetes desde repositorios confiables, restaurar únicamente los datos necesarios y rotar claves, contraseñas, tokens y secretos que hayan podido quedar expuestos.
Crear una línea base después de la auditoría
Cuando finalmente se ha decidido que el servidor puede mantenerse, merece la pena registrar su estado conocido.
| Elemento | Línea base que interesa conservar |
|---|---|
| Distribución | Versión y ciclo de soporte |
| Kernel | Versión esperada |
| Paquetes | Inventario y repositorios autorizados |
| Usuarios | Cuentas válidas |
| SSH | Claves y política |
| sudo | Privilegios autorizados |
| Servicios | Unidades habilitadas |
| Red | Puertos esperados |
| Firewall | Política y excepciones |
| Cron/systemd | Jobs y timers conocidos |
| AppArmor/SELinux | Estado y perfiles esperados |
| Integridad | Checksums desde una fuente confiable |
| Logs | Ubicación y retención |
| Backups | Política y última restauración probada |
Ahí cambia por completo la siguiente auditoría.
La primera vez hay que preguntarse qué significan 42 servicios habilitados.
La siguiente puede reducirse a algo mucho más útil: ayer había 41, ¿qué servicio nuevo ha aparecido y quién lo instaló?
Esa comparación es lo que convierte una colección de comandos en una política de administración.
Un servidor Linux no debería considerarse confiable porque lleve 300 días encendido, porque top tenga buen aspecto o porque no aparezca nada extraño en ss.
Empieza a ser confiable cuando cada cuenta, paquete, servicio, puerto, repositorio, mecanismo de persistencia y excepción de seguridad tiene una explicación y existe una referencia con la que comparar los cambios futuros.
Preguntas frecuentes
¿Qué debería revisar primero un administrador al recibir un servidor Linux?
Distribución, kernel, virtualización, discos, hora, repositorios y paquetes instalados deberían registrarse antes de realizar cambios. Después conviene revisar usuarios, SSH, sudo, servicios, red, persistencia y controles de seguridad.
¿Qué comandos son especialmente útiles para auditar Debian y Ubuntu?
Entre los más útiles están dpkg --verify, apt-cache policy, sshd -T, aa-status, systemctl list-timers, systemd-delta, ss -lntup y las consultas a journalctl. debsums puede complementar la verificación si ya está instalado.
¿Qué cambia al auditar Rocky Linux, AlmaLinux o RHEL?
La metodología es prácticamente la misma, pero APT y dpkg se sustituyen por DNF y RPM, SELinux suele ocupar el lugar de AppArmor y firewalld es habitual para gestionar el firewall.
¿Se puede asegurar que un servidor Linux está limpio después de una auditoría?
No de forma absoluta. Una auditoría ayuda a detectar anomalías y crear una línea base, pero un compromiso con privilegios elevados puede haber afectado a herramientas, kernel o logs. Cuando existen evidencias suficientes de intrusión, reconstruir desde fuentes confiables puede ser preferible a intentar limpiar el sistema.
Fuentes:
- Debian Administrator’s Handbook, administración y seguridad de sistemas Debian.
- Debian Manpages, documentación de
dpkg,debsums, systemd y AppArmor. - Ubuntu Server Documentation, seguridad, actualizaciones y administración de Ubuntu Server.
- Ubuntu Security Documentation, AppArmor y mecanismos de endurecimiento.
- Red Hat Enterprise Linux Documentation, SELinux, firewalld, RPM y auditoría.
- Arch Linux Wiki, administración de paquetes, systemd y seguridad.
- Alpine Linux Documentation, gestión de servicios con OpenRC.
- OpenSecurity







