--- title: "Logs de auditoría con auditd y retención S3 en Ubuntu 24.04" description: "Configura auditd en Ubuntu 24.04, rota sus logs de forma segura y archívalos a diario en S3 con Object Lock y sumas SHA-256 para conservarlos sin cambios." category: "Gestión de Logs" language: es source: https://cubepath.com/es/docs/gestión-de-logs/gestion-de-logs-de-auditoria-y-retencion updated: 2026-09-25 --- # Logs de auditoría con auditd y retención S3 en Ubuntu 24.04 Los logs de auditoría registran quién hizo qué en un servidor: cambios en usuarios y contraseñas, uso de `sudo`, modificaciones de configuración críticas. Normas como PCI DSS, ISO 27001 o SOC 2 exigen conservarlos durante un periodo mínimo y demostrar que no se han alterado. En este tutorial configurarás `auditd` en Ubuntu 24.04 con un conjunto de reglas útil, ajustarás la rotación local y crearás un archivado diario a un bucket S3 con Object Lock, que impide borrar o modificar los archivos durante el periodo de retención. También aprenderás a buscar eventos en los logs locales y archivados. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath, con un usuario no root con privilegios `sudo`. - Un bucket S3 (en AWS o en un proveedor compatible con S3 que soporte Object Lock) y unas credenciales de acceso con permiso para subir objetos a él. El paso 5 muestra cómo crear el bucket en AWS. - Unos cientos de MB libres en `/var` para los logs locales. El volumen depende de las reglas y de la actividad del servidor. ## Paso 1: Instalar auditd Instala el demonio de auditoría y sus plugins: ```bash sudo apt update sudo apt install auditd audispd-plugins ``` El servicio queda activo al terminar la instalación. Compruébalo: ```bash sudo systemctl status auditd --no-pager sudo auditctl -s ``` ```output enabled 1 failure 1 pid 1234 rate_limit 0 backlog_limit 8192 lost 0 backlog 0 ... ``` `enabled 1` indica que la auditoría del kernel está activa. Los eventos se escriben en `/var/log/audit/audit.log`. ## Paso 2: Añadir reglas de auditoría Sin reglas, auditd solo registra eventos básicos como inicios de sesión. Las reglas se guardan en archivos `.rules` dentro de `/etc/audit/rules.d/` y `augenrules` las combina al cargarlas. Crea un archivo de reglas: ```bash sudo nano /etc/audit/rules.d/50-cumplimiento.rules ``` Añade estas reglas, basadas en las recomendaciones de CIS: ```text ## Cambios en usuarios, grupos y contraseñas -w /etc/passwd -p wa -k identity -w /etc/group -p wa -k identity -w /etc/shadow -p wa -k identity -w /etc/gshadow -p wa -k identity -w /etc/security/opasswd -p wa -k identity ## Cambios en la configuración de sudo -w /etc/sudoers -p wa -k scope -w /etc/sudoers.d/ -p wa -k scope ## Configuración de SSH -w /etc/ssh/sshd_config -p wa -k sshd -w /etc/ssh/sshd_config.d/ -p wa -k sshd ## Cambios de hora del sistema -a always,exit -F arch=b64 -S adjtimex,settimeofday,clock_settime -k time-change -w /etc/localtime -p wa -k time-change ## Uso de comandos privilegiados por usuarios reales -a always,exit -F path=/usr/bin/sudo -F perm=x -F auid>=1000 -F auid!=unset -k privileged -a always,exit -F path=/usr/bin/su -F perm=x -F auid>=1000 -F auid!=unset -k privileged -a always,exit -F path=/usr/bin/passwd -F perm=x -F auid>=1000 -F auid!=unset -k privileged ## Carga y descarga de módulos del kernel -a always,exit -F arch=b64 -S init_module,finit_module,delete_module -k modules ## Accesos denegados a archivos -a always,exit -F arch=b64 -S open,openat,truncate,ftruncate -F exit=-EACCES -F auid>=1000 -F auid!=unset -k access -a always,exit -F arch=b64 -S open,openat,truncate,ftruncate -F exit=-EPERM -F auid>=1000 -F auid!=unset -k access ``` Cada regla tiene una clave (`-k`) que después sirve para buscar sus eventos. Las reglas `-w` vigilan archivos (`w` = escritura, `a` = cambio de atributos), y las `-a always,exit` registran llamadas al sistema. `auid` es el ID del usuario que inició la sesión, que se conserva aunque luego use `sudo`; `auid!=unset` excluye procesos del sistema que nunca iniciaron sesión. Carga las reglas y lístalas: ```bash sudo augenrules --load sudo auditctl -l ``` ```output -w /etc/passwd -p wa -k identity -w /etc/group -p wa -k identity ... -a always,exit -F arch=b64 -S open,truncate,ftruncate,openat -F exit=-EACCES -F auid>=1000 -F auid!=-1 -F key=access ``` Comprueba que funcionan creando y borrando un usuario de prueba: ```bash sudo useradd auditprueba sudo userdel auditprueba sudo ausearch -k identity -i --start recent | tail -n 5 ``` Deberías ver eventos `SYSCALL` con `comm=useradd` y `comm=userdel`, y tu usuario en el campo `auid`. ## Paso 3: Ajustar el almacenamiento y la rotación local auditd rota sus propios logs según `/etc/audit/auditd.conf`. No uses logrotate sobre `/var/log/audit/audit.log`: auditd no se enteraría del cambio de archivo y podría perder eventos. Abre el archivo de configuración: ```bash sudo nano /etc/audit/auditd.conf ``` Localiza y ajusta estas claves (el resto déjalas como están): ```ini log_group = adm max_log_file = 100 num_logs = 10 max_log_file_action = ROTATE space_left = 500 space_left_action = SYSLOG admin_space_left = 100 admin_space_left_action = SUSPEND disk_full_action = SUSPEND ``` Qué controla cada una: - `max_log_file` es el tamaño máximo de cada archivo en MB; al alcanzarlo, `ROTATE` lo renombra a `audit.log.1` y conserva hasta `num_logs` archivos (1 GB en total con estos valores). - `space_left` y `admin_space_left` son umbrales de espacio libre en MB en la partición de logs. Al bajar del primero se envía un aviso a syslog; al bajar del segundo auditd deja de escribir (`SUSPEND`) para no llenar el disco. - `log_group = adm` permite a los administradores del grupo `adm` leer los logs sin `sudo`. > Nota: algunas normas exigen detener el sistema antes que perder eventos de auditoría (`admin_space_left_action = HALT`). Es una decisión de cumplimiento, no técnica: valora si prefieres que el servidor se pare o que siga funcionando sin auditoría. Pide a auditd que relea su configuración enviándole la señal `HUP`, sin detener la auditoría: ```bash sudo kill -HUP "$(pidof auditd)" sudo grep DAEMON_CONFIG /var/log/audit/audit.log | tail -n 1 ``` La línea mostrada es el último evento `DAEMON_CONFIG` y debe incluir `res=success`. Si ves `res=failed`, revisa la sintaxis del archivo. Para forzar una rotación manual en cualquier momento, envía la señal `USR1` al demonio: ```bash sudo kill -USR1 "$(pidof auditd)" ls -l /var/log/audit/ ``` ```output -rw-r----- 1 root adm 1204 Sep 25 10:20 audit.log -rw-r----- 1 root adm 482317 Sep 25 10:20 audit.log.1 ``` ## Paso 4: Instalar AWS CLI y configurar las credenciales Ubuntu 24.04 no incluye AWS CLI en sus repositorios. Instala la versión 2 con el instalador oficial: ```bash sudo apt install unzip curl -fsSL "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o awscliv2.zip unzip -q awscliv2.zip sudo ./aws/install aws --version ``` ```output aws-cli/2.x.x Python/3.x.x Linux/6.8.0-xx-generic exe/x86_64.ubuntu.24 ``` En servidores arm64 usa `awscli-exe-linux-aarch64.zip`. El archivado se ejecutará como root, así que configura las credenciales para root: ```bash sudo aws configure ``` Introduce la clave de acceso, la clave secreta y la región (por ejemplo `eu-west-1`). Usa unas credenciales dedicadas cuyo único permiso sea `s3:PutObject` sobre el bucket de auditoría: si el servidor se ve comprometido, no deben servir para borrar el histórico. Si usas un proveedor compatible con S3 distinto de AWS, anota la URL de su endpoint: la usarás en el paso 6. ## Paso 5: Crear un bucket con Object Lock Object Lock aplica un modelo WORM (escribir una vez, leer muchas): mientras dure la retención, nadie puede borrar ni sobrescribir los objetos. Solo se puede activar al crear el bucket. Si ya tienes un bucket con Object Lock, salta al paso 6. Crea el bucket en AWS, sustituyendo **`your_audit_bucket`** por un nombre único. En regiones distintas de `us-east-1` añade `--create-bucket-configuration LocationConstraint=`: ```bash aws s3api create-bucket \ --bucket your_audit_bucket \ --region us-east-1 \ --object-lock-enabled-for-bucket ``` Define una retención por defecto para todos los objetos nuevos. PCI DSS exige conservar al menos 12 meses de logs de auditoría; ajusta los días a la norma que te aplique: ```bash aws s3api put-object-lock-configuration \ --bucket your_audit_bucket \ --object-lock-configuration '{"ObjectLockEnabled":"Enabled","Rule":{"DefaultRetention":{"Mode":"GOVERNANCE","Days":365}}}' ``` Comprueba la configuración: ```bash aws s3api get-object-lock-configuration --bucket your_audit_bucket ``` > Advertencia: en modo `GOVERNANCE`, un usuario con el permiso `s3:BypassGovernanceRetention` todavía puede borrar objetos, lo que es útil mientras pruebas. En modo `COMPLIANCE` nadie puede borrarlos antes de que venza la retención, ni siquiera la cuenta raíz de AWS. Cambia a `COMPLIANCE` solo cuando el proceso esté validado. ## Paso 6: Crear el script de archivado diario El script rota el log de auditoría, comprime el archivo recién rotado con un nombre que incluye servidor y fecha, calcula su suma SHA-256, sube ambos al bucket y borra las copias locales de más de 30 días. Primero crea un archivo de configuración con el nombre del bucket: ```bash sudo nano /etc/default/audit-archive ``` ```ini AUDIT_BUCKET=your_audit_bucket # Solo para proveedores compatibles con S3 distintos de AWS: # AWS_ENDPOINT_URL=https://s3.your_provider.example ``` Crea el script: ```bash sudo nano /usr/local/sbin/audit-archive ``` ```bash #!/usr/bin/env bash # Rota el log de auditd y archiva el archivo rotado en S3 con su suma SHA-256. set -euo pipefail : "${AUDIT_BUCKET:?AUDIT_BUCKET no está definido}" LOG_DIR=/var/log/audit ARCHIVE_DIR=/var/lib/audit-archive LOCAL_DAYS=30 host="$(hostname -s)" stamp="$(date -u +%Y%m%dT%H%M%SZ)" name="${host}-audit-${stamp}.log.gz" mkdir -p "$ARCHIVE_DIR" chmod 700 "$ARCHIVE_DIR" # Pedir a auditd que rote y esperar a que aparezca el archivo rotado kill -USR1 "$(pidof auditd)" sleep 5 gzip -c "${LOG_DIR}/audit.log.1" > "${ARCHIVE_DIR}/${name}" (cd "$ARCHIVE_DIR" && sha256sum "$name" > "${name}.sha256") dest="s3://${AUDIT_BUCKET}/${host}/$(date -u +%Y/%m)/" aws s3 cp --only-show-errors "${ARCHIVE_DIR}/${name}" "$dest" aws s3 cp --only-show-errors "${ARCHIVE_DIR}/${name}.sha256" "$dest" find "$ARCHIVE_DIR" -type f -mtime "+${LOCAL_DAYS}" -delete echo "Archivado ${name} en ${dest}" ``` Hazlo ejecutable solo para root y pruébalo a mano, cargando la configuración como hará systemd: ```bash sudo chmod 700 /usr/local/sbin/audit-archive sudo bash -c 'set -a; . /etc/default/audit-archive; set +a; /usr/local/sbin/audit-archive' ``` ```output Archivado web01-audit-20260925T103000Z.log.gz en s3://your_audit_bucket/web01/2026/09/ ``` Comprueba que el objeto está en el bucket y tiene retención: ```bash sudo aws s3 ls s3://your_audit_bucket/web01/2026/09/ sudo aws s3api get-object-retention --bucket your_audit_bucket --key web01/2026/09/web01-audit-20260925T103000Z.log.gz ``` ```output { "Retention": { "Mode": "GOVERNANCE", "RetainUntilDate": "2027-09-25T10:30:00.000Z" } } ``` > Nota: auditd también rota por tamaño al llegar a `max_log_file`. Si un servidor genera más de 100 MB de auditoría al día, algún archivo rotado podría no archivarse. Aumenta `max_log_file` o programa el archivado con más frecuencia. ## Paso 7: Programar el archivado con un timer de systemd Crea el servicio: ```bash sudo nano /etc/systemd/system/audit-archive.service ``` ```ini [Unit] Description=Archivar logs de auditd en S3 After=network-online.target auditd.service Wants=network-online.target [Service] Type=oneshot EnvironmentFile=/etc/default/audit-archive ExecStart=/usr/local/sbin/audit-archive ``` Crea el timer, que lo ejecuta cada día a las 00:05: ```bash sudo nano /etc/systemd/system/audit-archive.timer ``` ```ini [Unit] Description=Archivado diario de logs de auditd [Timer] OnCalendar=*-*-* 00:05:00 Persistent=true RandomizedDelaySec=300 [Install] WantedBy=timers.target ``` `Persistent=true` hace que, si el servidor estaba apagado a esa hora, el archivado se ejecute al arrancar. Activa el timer y comprueba la próxima ejecución: ```bash sudo systemctl daemon-reload sudo systemctl enable --now audit-archive.timer systemctl list-timers audit-archive.timer ``` ```output NEXT LEFT LAST PASSED UNIT ACTIVATES Fri 2026-09-26 00:07:12 UTC 13h left - - audit-archive.timer audit-archive.service ``` Tras la primera ejecución automática, revisa el resultado con `sudo journalctl -u audit-archive.service -n 20`. ## Paso 8: Verificar la integridad de un archivo archivado Para demostrar que un log no se ha modificado, descárgalo junto con su suma y compruébala: ```bash mkdir -p ~/verificacion && cd ~/verificacion sudo aws s3 cp s3://your_audit_bucket/web01/2026/09/web01-audit-20260925T103000Z.log.gz . sudo aws s3 cp s3://your_audit_bucket/web01/2026/09/web01-audit-20260925T103000Z.log.gz.sha256 . sha256sum -c web01-audit-20260925T103000Z.log.gz.sha256 ``` ```output web01-audit-20260925T103000Z.log.gz: OK ``` La suma protege frente a corrupción, y Object Lock frente a borrados y sobrescrituras: juntos cubren el requisito de integridad de la mayoría de auditorías. ## Paso 9: Buscar eventos en los logs `ausearch` busca en los logs de `/var/log/audit/` y `-i` traduce IDs numéricos a nombres. Algunos ejemplos útiles: ```bash sudo ausearch -k privileged -i --start today sudo ausearch -k identity -i --start this-week sudo ausearch -ua 1000 -i --start yesterday ``` `aureport` genera resúmenes. Por ejemplo, intentos de autenticación y eventos por clave de regla: ```bash sudo aureport -au --start today sudo aureport -k --summary ``` ```output Key Summary Report =========================== total key =========================== 412 access 37 privileged 6 identity ``` Para buscar en un archivo archivado, descomprímelo y pásalo a `ausearch` con `-if`: ```bash gunzip -k web01-audit-20260925T103000Z.log.gz sudo ausearch -if web01-audit-20260925T103000Z.log -k privileged -i ``` ## Paso 10 (opcional): Hacer las reglas inmutables Un atacante con acceso root podría desactivar las reglas con `auditctl -D` antes de actuar. Para evitarlo, añade como última regla `-e 2`, que bloquea la configuración hasta el siguiente reinicio: ```bash sudo nano /etc/audit/rules.d/99-finalize.rules ``` ```text -e 2 ``` Carga las reglas y comprueba el estado: ```bash sudo augenrules --load sudo auditctl -s | head -n 1 ``` ```output enabled 2 ``` > Importante: con `enabled 2`, cualquier cambio en las reglas requiere reiniciar el servidor. Activa este paso solo cuando las reglas estén estabilizadas. ## Solución de problemas **`ausearch` no encuentra eventos de una clave.** Comprueba con `sudo auditctl -l` que la regla está cargada. Si editaste los archivos de `rules.d` pero no ejecutaste `augenrules --load`, las reglas nuevas no están activas. **El log crece demasiado deprisa.** Averigua qué regla genera más eventos con `sudo aureport -k --summary`. La regla `access` suele ser la más ruidosa en servidores con aplicaciones que prueban rutas sin permiso; elimínala o limítala a directorios concretos con `-F dir=`. **El archivado falla con `AccessDenied` o `InvalidRequest`.** Revisa `sudo journalctl -u audit-archive.service`. `AccessDenied` indica que las credenciales no tienen `s3:PutObject` sobre el bucket. En proveedores compatibles con S3, un `InvalidRequest` al subir a un bucket con Object Lock suele deberse a que falta `AWS_ENDPOINT_URL` o a que el proveedor no soporta Object Lock. **`gzip: /var/log/audit/audit.log.1: No such file or directory`.** auditd no rotó a tiempo o `max_log_file_action` no es `ROTATE`. Revisa `auditd.conf` y aumenta el `sleep` del script si el disco es lento. ## Conclusión Has configurado auditd con reglas orientadas a cumplimiento, una rotación local que no pierde eventos y un archivado diario a S3 con Object Lock y sumas SHA-256 que protege el histórico frente a borrados y alteraciones. Como siguientes pasos puedes añadir una regla de ciclo de vida en el bucket para mover los objetos antiguos a una clase de almacenamiento más barata, enviar los eventos en tiempo real a un SIEM con un plugin de `audispd-plugins` como `au-remote`, o revisar periódicamente los informes de `aureport` en busca de actividad inesperada.