ISO/IEC 27001:2022 define en su Anexo A 93 controles agrupados en cuatro temas: organizativos, de personas, físicos y tecnológicos. En un servidor Linux, los que se implementan con configuración son sobre todo los tecnológicos (sección A.8). En este tutorial aplicarás en Ubuntu 24.04 un conjunto de controles concretos, cada uno asociado a su número del Anexo A, y reunirás las evidencias que un auditor te pedirá para demostrar que funcionan.
La norma no exige comandos concretos: exige que tus controles cumplan tu política y que puedas demostrarlo. Adapta los valores de esta guía (longitud de contraseña, retención de logs, puertos abiertos) a lo que diga la política de tu SGSI.
Requisitos previos
- Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath.
- Un usuario no root con privilegios
sudoy acceso por clave SSH ya configurado. - Acceso a la consola del proveedor (VNC/KVM) por si un cambio de SSH o firewall te deja fuera.
- La política de seguridad y el alcance del SGSI, para saber qué valores aplicar.
Estos son los controles que cubre la guía:
| Control del Anexo A | Qué aplicas en el servidor |
|---|---|
| A.8.2 Derechos de acceso privilegiado | Registro de sudo en un log propio |
| A.8.5 Autenticación segura | Política de contraseñas con pwquality y SSH solo con claves |
| A.8.20 Seguridad de redes | UFW con denegación por defecto y parámetros de red en sysctl |
| A.8.15 Registro de eventos | Reglas de auditd sobre identidades, sudo y SSH |
| A.8.8 Gestión de vulnerabilidades técnicas | Actualizaciones automáticas de seguridad |
| A.8.9 Gestión de la configuración | Detección de cambios en ficheros con AIDE |
| A.8.16 Actividades de seguimiento | Evidencias periódicas para la auditoría |
Paso 1: Registrar el uso de sudo (A.8.2)
El control A.8.2 pide restringir y gestionar los accesos privilegiados. Empieza revisando quién puede usar sudo:
getent group sudo
sudo ls -l /etc/sudoers.d/
sudo:x:27:your_user
Cada miembro de ese grupo debe tener una justificación documentada. Después, envía la actividad de sudo a un fichero propio con fecha completa y host, y reduce a 5 minutos el tiempo que sudo recuerda la contraseña. Crea el fichero siempre con visudo, que valida la sintaxis antes de guardar:
sudo visudo -f /etc/sudoers.d/iso27001
Defaults logfile="/var/log/sudo.log"
Defaults log_year, log_host
Defaults timestamp_timeout=5
Comprueba que la sintaxis es correcta y lanza un comando para generar una entrada:
sudo visudo -c
sudo -k; sudo true
sudo tail -n 2 /var/log/sudo.log
Sep 25 10:14:02 2026 : your_user : HOST=srv01 : TTY=pts/0 ; PWD=/home/your_user ; USER=root ; COMMAND=/usr/bin/true
Configura la rotación de este log para conservarlo el tiempo que marque tu política (aquí, un año):
sudo nano /etc/logrotate.d/sudo-iso27001
/var/log/sudo.log {
weekly
rotate 52
compress
missingok
notifempty
create 0600 root root
}
Valida la configuración con una ejecución en seco:
sudo logrotate -d /etc/logrotate.d/sudo-iso27001
Paso 2: Aplicar una política de contraseñas (A.8.5)
Aunque el acceso por SSH sea solo con claves, las contraseñas locales siguen usándose para sudo y la consola. Instala el módulo PAM pwquality y la herramienta pwscore para probarlo:
sudo apt update
sudo apt install libpam-pwquality libpwquality-tools
Al instalarse, el paquete añade pam_pwquality a /etc/pam.d/common-password automáticamente. Define la política en un fichero propio dentro de pwquality.conf.d, así no se pisa con futuras actualizaciones:
sudo nano /etc/security/pwquality.conf.d/iso27001.conf
minlen = 14
minclass = 3
maxrepeat = 3
maxsequence = 3
usercheck = 1
dictcheck = 1
enforce_for_root
Comprueba que la política rechaza contraseñas débiles. pwscore lee la contraseña de la entrada estándar:
echo 'Verano2026' | pwscore
Password quality check failed:
The password is shorter than 14 characters
Si tu política exige caducidad de contraseñas, ajusta PASS_MAX_DAYS en /etc/login.defs para los usuarios nuevos y aplícala a los existentes con chage. Ten en cuenta que la guía actual de NIST desaconseja la caducidad periódica si no hay indicios de compromiso, así que documenta la decisión en tu SGSI:
sudo chage -M 365 -W 14 your_user
sudo chage -l your_user
Paso 3: Permitir SSH solo con claves (A.8.5)
La autenticación con clave pública elimina los ataques de fuerza bruta contra contraseñas por SSH. Antes de continuar, confirma que puedes entrar con tu clave desde otra terminal. Después crea un fichero de configuración adicional; Ubuntu 24.04 carga todo lo que haya en /etc/ssh/sshd_config.d/:
sudo nano /etc/ssh/sshd_config.d/10-iso27001.conf
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
MaxAuthTries 3
LoginGraceTime 30
Valida la configuración y recarga el servicio:
sudo sshd -t
sudo systemctl reload ssh
sshd -t no muestra nada si todo es correcto. Confirma los valores efectivos:
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication|maxauthtries'
permitrootlogin no
passwordauthentication no
maxauthtries 3
Advertenciano cierres tu sesión actual hasta haber abierto una nueva conexión SSH con éxito. Si algo falla, corrige el fichero desde la sesión que sigue abierta o desde la consola VNC.
Paso 4: Filtrar el tráfico de red (A.8.20)
El control A.8.20 pide proteger las redes y los servicios que las usan. Configura UFW para denegar todo el tráfico entrante salvo lo que el servidor necesita. Permite SSH antes de activarlo:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw limit OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
ufw limit bloquea temporalmente una IP que abre 6 o más conexiones en 30 segundos. Abre 80 y 443 solo si el servidor publica un servicio web. Comprueba el resultado:
sudo ufw status verbose
Status: active
Default: deny (incoming), allow (outgoing), deny (routed)
To Action From
-- ------ ----
22/tcp (OpenSSH) LIMIT IN Anywhere
80/tcp ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
Añade además unos parámetros de red del kernel que rechazan redirecciones ICMP y paquetes con origen falsificado. Si el servidor hace de router, VPN o host de contenedores, no desactives el reenvío:
sudo nano /etc/sysctl.d/99-iso27001.conf
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0
net.ipv6.conf.default.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.tcp_syncookies = 1
Carga todos los ficheros de sysctl.d y verifica un valor:
sudo sysctl --system
sysctl net.ipv4.conf.all.accept_redirects
net.ipv4.conf.all.accept_redirects = 0
Paso 5: Auditar eventos con auditd (A.8.15)
El control A.8.15 exige producir, guardar y proteger registros de actividad. auditd registra en el kernel los cambios en ficheros sensibles y la ejecución de comandos con privilegios. Instálalo:
sudo apt install auditd
Crea un fichero de reglas. Cada regla lleva una clave (-k) para poder buscar sus eventos después:
sudo nano /etc/audit/rules.d/50-iso27001.rules
## Identidades y privilegios
-w /etc/passwd -p wa -k identidad
-w /etc/shadow -p wa -k identidad
-w /etc/group -p wa -k identidad
-w /etc/gshadow -p wa -k identidad
-w /etc/sudoers -p wa -k privilegios
-w /etc/sudoers.d/ -p wa -k privilegios
## Configuración de acceso
-w /etc/ssh/sshd_config -p wa -k ssh
-w /etc/ssh/sshd_config.d/ -p wa -k ssh
-w /etc/pam.d/ -p wa -k pam
## Tareas programadas
-w /etc/cron.d/ -p wa -k cron
-w /etc/crontab -p wa -k cron
-w /var/spool/cron/ -p wa -k cron
## Comandos ejecutados como root por un usuario real
-a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -F auid!=unset -k comandos_root
Carga las reglas y comprueba que el kernel las tiene activas:
sudo augenrules --load
sudo auditctl -l | head -n 5
-w /etc/passwd -p wa -k identidad
-w /etc/shadow -p wa -k identidad
-w /etc/group -p wa -k identidad
-w /etc/gshadow -p wa -k identidad
-w /etc/sudoers -p wa -k privilegios
Provoca un evento y búscalo por su clave:
sudo touch /etc/sudoers.d/iso27001
sudo ausearch -k privilegios -ts recent -i | tail -n 3
La salida muestra el usuario original (auid), el comando y el fichero modificado. Por defecto auditd guarda los registros en /var/log/audit/audit.log y rota con los parámetros max_log_file y num_logs de /etc/audit/auditd.conf. Si tu política exige conservar los logs fuera del servidor, envíalos a un sistema centralizado con rsyslog o tu agente de SIEM.
Paso 6: Aplicar parches de seguridad automáticamente (A.8.8)
El control A.8.8 pide identificar y corregir vulnerabilidades técnicas a tiempo. Ubuntu 24.04 trae unattended-upgrades, que por defecto instala solo las actualizaciones del origen -security. Asegúrate de que está instalado y activado:
sudo apt install unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
Responde Yes a la pregunta. Esto escribe /etc/apt/apt.conf.d/20auto-upgrades. Comprueba su contenido:
cat /etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
Para cambiar opciones sin tocar el fichero principal del paquete, crea uno propio que se lea después:
sudo nano /etc/apt/apt.conf.d/52iso27001
Unattended-Upgrade::Remove-Unused-Kernel-Packages "true";
Unattended-Upgrade::Automatic-Reboot "false";
Deja el reinicio automático desactivado si tus reinicios deben pasar por gestión de cambios, y revisa el fichero /var/run/reboot-required, que aparece cuando un parche del kernel lo necesita. Haz una prueba en seco:
sudo unattended-upgrade --dry-run --debug 2>&1 | grep -i 'allowed origins'
Allowed origins are: o=Ubuntu,a=noble, o=Ubuntu,a=noble-security, o=UbuntuESMApps,a=noble-apps-security, o=UbuntuESM,a=noble-infra-security
El historial de lo instalado queda en /var/log/unattended-upgrades/unattended-upgrades.log, una evidencia directa para este control.
Paso 7: Detectar cambios no autorizados con AIDE (A.8.9)
El control A.8.9 pide establecer, documentar y supervisar las configuraciones. AIDE guarda una base de datos con los hashes y atributos de los ficheros del sistema y avisa de cualquier diferencia posterior. Instálalo:
sudo apt install aide
Genera la base de datos inicial. Tarda unos minutos, porque recorre todo el sistema:
sudo aideinit
El comando crea la base de referencia en /var/lib/aide/aide.db. Comprueba que existe y lanza una verificación manual:
sudo ls -lh /var/lib/aide/aide.db
sudo aide --config /etc/aide/aide.conf --check
Si no ha cambiado nada, la salida termina con un resumen sin diferencias. Tras modificar ficheros (por ejemplo, las reglas de los pasos anteriores), AIDE los listará como changed. El paquete instala además una comprobación diaria que envía su informe al usuario root por correo, así que configura un agente de correo o la redirección de root si quieres recibirlo.
Cada vez que hagas un cambio aprobado, actualiza la referencia para que el siguiente informe solo muestre cambios nuevos:
sudo aide --config /etc/aide/aide.conf --update
sudo cp /var/lib/aide/aide.db.new /var/lib/aide/aide.db
Paso 8: Reunir evidencias para la auditoría (A.8.16)
Un auditor no se conforma con que digas que el control existe: pide pruebas fechadas. Este script guarda en un directorio con la fecha del día el estado de los controles anteriores. Créalo:
sudo nano /usr/local/sbin/iso27001-evidencias
#!/usr/bin/env bash
set -euo pipefail
destino="/var/lib/iso27001/$(date +%F)"
install -d -m 0700 "$destino"
getent group sudo > "$destino/grupo-sudo.txt"
sshd -T > "$destino/sshd-efectivo.txt"
ufw status verbose > "$destino/ufw.txt"
auditctl -l > "$destino/auditd-reglas.txt"
aureport --summary --start today > "$destino/auditd-resumen.txt" || true
apt list --upgradable 2>/dev/null > "$destino/pendientes.txt"
systemctl list-units --state=failed --no-legend > "$destino/servicios-fallidos.txt"
sha256sum "$destino"/*.txt > "$destino/SHA256SUMS"
Hazlo ejecutable y pruébalo:
sudo chmod 0750 /usr/local/sbin/iso27001-evidencias
sudo /usr/local/sbin/iso27001-evidencias
sudo ls /var/lib/iso27001/$(date +%F)
SHA256SUMS auditd-reglas.txt auditd-resumen.txt grupo-sudo.txt pendientes.txt servicios-fallidos.txt sshd-efectivo.txt ufw.txt
Prográmalo cada semana con un temporizador de systemd. Primero el servicio:
sudo nano /etc/systemd/system/iso27001-evidencias.service
[Unit]
Description=Recogida de evidencias ISO 27001
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/iso27001-evidencias
Después el temporizador:
sudo nano /etc/systemd/system/iso27001-evidencias.timer
[Unit]
Description=Recogida semanal de evidencias ISO 27001
[Timer]
OnCalendar=Mon *-*-* 06:00:00
Persistent=true
[Install]
WantedBy=timers.target
Actívalo y comprueba la próxima ejecución:
sudo systemctl daemon-reload
sudo systemctl enable --now iso27001-evidencias.timer
systemctl list-timers iso27001-evidencias.timer
Copia periódicamente /var/lib/iso27001/ fuera del servidor para que las evidencias sobrevivan a un incidente.
Solución de problemas
Te has quedado sin acceso SSH. Entra por la consola VNC del proveedor, revisa /etc/ssh/sshd_config.d/10-iso27001.conf y ejecuta sudo sshd -t. Si el bloqueo viene de UFW, comprueba que existe la regla con sudo ufw status y añádela con sudo ufw limit OpenSSH.
augenrules --load no aplica las reglas. Si la configuración contiene -e 2, las reglas son inmutables hasta el siguiente reinicio. Comprueba el estado con sudo auditctl -s (campo enabled 2) y reinicia el servidor para cargar las nuevas.
AIDE informa de cientos de cambios tras una actualización. Es normal cuando unattended-upgrades actualiza paquetes. Revisa que los ficheros cambiados corresponden a paquetes del log de actualizaciones y regenera la referencia con aide --update.
pwscore acepta contraseñas que deberían fallar. Comprueba que el fichero está en /etc/security/pwquality.conf.d/ con extensión .conf y que /etc/pam.d/common-password contiene una línea con pam_pwquality.so.
Conclusión
Has aplicado en Ubuntu 24.04 siete controles tecnológicos del Anexo A de ISO 27001 y tienes una recogida automática de evidencias fechadas para demostrar que siguen activos. Como siguientes pasos, documenta cada control en tu Declaración de Aplicabilidad con su responsable y su evidencia, centraliza los logs de auditd y sudo en un SIEM, y automatiza esta configuración con Ansible para aplicarla igual en todos los servidores del alcance.
