--- title: "Rotación y retención de logs con logrotate y journald" description: "Configura logrotate y systemd-journald en Ubuntu 24.04 para rotar, comprimir y conservar logs el tiempo que exige tu política de retención, sin llenar el disco." category: "Cumplimiento de las normas" language: es source: https://cubepath.com/es/docs/cumplimiento-de-las-normas/retencion-y-rotacion-de-logs updated: 2026-09-25 --- # Rotación y retención de logs con logrotate y journald Los logs de un servidor crecen sin parar: si no se rotan acaban llenando el disco, y si se borran demasiado pronto no estarán disponibles cuando tengas que investigar un incidente o responder a una auditoría. En Linux hay dos piezas que controlan esto: **logrotate**, que rota los ficheros de texto de `/var/log`, y **systemd-journald**, que gestiona su propio almacén binario. En este tutorial definirás una política de retención y la aplicarás con ambas herramientas en Ubuntu 24.04: una aplicación propia, los logs de autenticación con retención de un año y el journal con un límite de tamaño y antigüedad. ## Requisitos previos - Un servidor con Ubuntu 24.04 LTS, por ejemplo un VPS de CubePath. En Debian 12 los comandos son los mismos. - Un usuario no root con privilegios `sudo`. - Espacio libre suficiente en disco para la retención que elijas (en el paso 1 verás cómo estimarlo). ## Paso 1: Definir la política de retención Antes de tocar configuración, decide cuánto tiempo necesitas conservar cada tipo de log y dónde. Las normativas más habituales fijan estos mínimos: | Norma | Qué exige sobre los logs | |-------|--------------------------| | PCI DSS v4.0 (requisito 10.5.1) | Conservar el historial de auditoría al menos 12 meses, con los últimos 3 meses disponibles de inmediato | | RGPD | No fija un plazo: los logs con datos personales solo se conservan el tiempo necesario para su finalidad | | ISO/IEC 27001 | No fija un plazo: debe estar definido en tu política y aplicarse de forma consistente | > Nota: Consulta con tu responsable de cumplimiento el plazo exacto que aplica a tu caso. Esta guía usa un ejemplo habitual: 30 días para logs de aplicación y 12 meses para los de autenticación. Para estimar cuánto ocupará, mira el tamaño actual de los logs y cuánto crecen al día: ```bash sudo du -sh /var/log/*.log /var/log/*/ 2>/dev/null | sort -h | tail -n 10 ``` Un log de texto comprimido con gzip suele quedarse en un 5-10 % de su tamaño original, así que 12 meses de `auth.log` rara vez superan unos pocos cientos de megabytes. ## Paso 2: Revisar cómo funciona logrotate en Ubuntu logrotate viene instalado en Ubuntu. Comprueba la versión y que el temporizador de systemd que lo ejecuta cada día está activo: ```bash logrotate --version systemctl list-timers logrotate.timer ``` ```output logrotate 3.21.0 ... NEXT LEFT LAST PASSED UNIT ACTIVATES Fri 2026-09-26 00:00:00 UTC 13h left Thu 2026-09-25 00:00:03 UTC 10h ago logrotate.timer logrotate.service ``` La configuración se reparte en dos sitios: - `/etc/logrotate.conf`: valores por defecto globales (en Ubuntu, rotación semanal y 4 copias) y la línea `include /etc/logrotate.d`. - `/etc/logrotate.d/`: un fichero por paquete o aplicación (`rsyslog`, `nginx`, `apt`...). Las directivas de cada bloque sustituyen a las globales. logrotate guarda la fecha de la última rotación de cada fichero en `/var/lib/logrotate/status`. Así sabe si toca rotar, aunque el servidor haya estado apagado. Las directivas que vas a usar en esta guía son: | Directiva | Qué hace | |-----------|----------| | `daily`, `weekly`, `monthly` | Frecuencia de rotación | | `rotate N` | Número de ficheros rotados que se conservan; el más antiguo se borra | | `maxsize 100M` | Rota antes de tiempo si el fichero supera ese tamaño (se evalúa cada vez que se ejecuta logrotate) | | `compress` / `delaycompress` | Comprime con gzip los rotados, dejando sin comprimir el más reciente | | `dateext` | Añade la fecha al nombre en lugar de un número (`app.log-20260925`) | | `missingok` / `notifempty` | No da error si falta el fichero y no rota ficheros vacíos | | `create 0640 usuario grupo` | Crea el fichero nuevo con esos permisos tras rotar | | `copytruncate` | Copia el fichero y lo vacía, para aplicaciones que no saben reabrir su log | | `postrotate` ... `endscript` | Comando que se ejecuta tras rotar, normalmente para que el servicio reabra el log | ## Paso 3: Rotar los logs de una aplicación propia Supón una aplicación que se ejecuta como servicio systemd `miapp.service`, con el usuario `miapp`, y escribe en `/var/log/miapp/`. Sustituye estos nombres por los de tu aplicación. Si todavía no existe, crea el directorio con el propietario correcto: ```bash sudo install -d -m 0750 -o miapp -g adm /var/log/miapp ``` Crea el fichero de configuración de logrotate: ```bash sudo nano /etc/logrotate.d/miapp ``` Añade este bloque: ```text /var/log/miapp/*.log { daily rotate 30 maxsize 100M missingok notifempty compress delaycompress dateext dateformat -%Y%m%d-%s create 0640 miapp adm su miapp adm sharedscripts postrotate systemctl kill --signal=HUP miapp.service >/dev/null 2>&1 || true endscript } ``` Qué hace cada parte importante: - `daily` con `rotate 30` conserva 30 días. `maxsize 100M` rota antes si un día hay un pico de tráfico. - `dateformat -%Y%m%d-%s` incluye la marca de tiempo en segundos, para que dos rotaciones el mismo día (por `maxsize`) no choquen de nombre. - `su miapp adm` hace que logrotate trabaje con ese usuario. Es necesario cuando el directorio no pertenece a root; sin él, logrotate se niega a rotar por seguridad. - El bloque `postrotate` envía `SIGHUP` al servicio para que reabra el fichero. `sharedscripts` hace que se ejecute una sola vez aunque haya varios `.log`. Si tu aplicación no reabre el log con `SIGHUP`, elimina el bloque `postrotate` ... `endscript` y la línea `create`, y añade `copytruncate`. Funciona con cualquier programa, a cambio de poder perder las líneas escritas justo entre la copia y el vaciado. Comprueba la configuración en modo de prueba. La opción `-d` muestra lo que haría sin tocar nada: ```bash sudo logrotate -d /etc/logrotate.d/miapp ``` ```output reading config file /etc/logrotate.d/miapp ... rotating pattern: /var/log/miapp/*.log after 1 days (30 rotations) empty log files are not rotated, old logs are removed switching euid from 0 to 999 and egid from 0 to 4 considering log /var/log/miapp/app.log Now: 2026-09-25 10:20 Last rotated at 2026-09-25 10:00 log does not need rotating (log has already been rotated) ``` Fuerza una rotación real para verificar que el servicio sigue escribiendo en el fichero nuevo: ```bash sudo logrotate -f -v /etc/logrotate.d/miapp ls -l /var/log/miapp/ ``` ```output -rw-r----- 1 miapp adm 0 Sep 25 10:21 app.log -rw-r----- 1 miapp adm 48213 Sep 25 10:21 app.log-20260925-1758795660 ``` Tras la siguiente rotación, `app.log-20260925-...` se comprimirá como `.gz` por el efecto de `delaycompress`. Espera a que la aplicación registre algo y confirma que `app.log` vuelve a crecer. ## Paso 4: Conservar los logs de autenticación durante 12 meses En Ubuntu, `/var/log/auth.log` lo escribe rsyslog y lo rota el bloque de `/etc/logrotate.d/rsyslog`, que solo guarda 4 semanas. No puedes declarar el mismo fichero en dos bloques (logrotate falla con `duplicate log entry`), así que primero quítalo del bloque de rsyslog: ```bash sudo nano /etc/logrotate.d/rsyslog ``` Borra la línea `/var/log/auth.log` de la lista de ficheros y guarda. El resto del bloque queda igual. > Nota: `/etc/logrotate.d/rsyslog` es un fichero de configuración del paquete. Si una actualización de rsyslog trae una versión nueva, apt te preguntará si conservas la tuya: responde que sí para no perder el cambio. Crea un bloque propio para `auth.log`: ```bash sudo nano /etc/logrotate.d/auth-retention ``` ```text /var/log/auth.log { weekly rotate 53 missingok notifempty compress delaycompress dateext postrotate /usr/lib/rsyslog/rsyslog-rotate endscript } ``` Con rotación semanal y 53 copias conservas algo más de 12 meses. El script `rsyslog-rotate` es el mismo que usa el bloque original para que rsyslog reabra sus ficheros. Valida toda la configuración de logrotate, no solo el fichero nuevo, para detectar duplicados: ```bash sudo logrotate -d /etc/logrotate.conf 2>&1 | grep -iE 'error|duplicate' || echo "Configuración correcta" ``` ```output Configuración correcta ``` ## Paso 5: Limitar el tamaño y la antigüedad del journal Además de los ficheros de texto, systemd-journald guarda los logs de todos los servicios en `/var/log/journal/`. Por defecto no borra nada hasta ocupar el 10 % del sistema de ficheros (con un máximo de 4 GB), sin límite de antigüedad. Mira cuánto ocupa ahora: ```bash journalctl --disk-usage ``` ```output Archived and active journals take 612.0M in the file system. ``` Crea un fichero de configuración adicional en lugar de editar el principal, para que las actualizaciones no lo sobrescriban: ```bash sudo mkdir -p /etc/systemd/journald.conf.d sudo nano /etc/systemd/journald.conf.d/retention.conf ``` ```ini [Journal] Storage=persistent SystemMaxUse=1G SystemKeepFree=2G MaxRetentionSec=90d ``` - `Storage=persistent` garantiza que el journal se guarda en disco y sobrevive a los reinicios. - `SystemMaxUse` limita el espacio total, y `SystemKeepFree` deja siempre ese margen libre en el disco. - `MaxRetentionSec=90d` borra las entradas de más de 90 días aunque quede espacio. Aplica los cambios reiniciando el servicio: ```bash sudo systemctl restart systemd-journald ``` Para limpiar de inmediato lo que ya supera el nuevo límite, usa `--vacuum-time` o `--vacuum-size`: ```bash sudo journalctl --vacuum-time=90d ``` ```output Vacuuming done, freed 0B of archived journals from /var/log/journal/... ``` Comprueba cuál es la entrada más antigua que se conserva: ```bash journalctl -q -o short-iso --no-pager | head -n 1 ``` ```output 2026-06-27T08:14:02+00:00 servidor kernel: Linux version 6.8.0-84-generic ... ``` Si necesitas que el journal cubra 12 meses, sube `MaxRetentionSec` a `1year` y ajusta `SystemMaxUse` a lo que estimaste en el paso 1. El journal no se comprime tan bien como gzip, así que para retenciones largas suele ser más eficiente conservar los ficheros de texto rotados y dejar el journal en unas semanas. ## Paso 6: Verificar la política con el tiempo La primera rotación no demuestra que la retención funciona: lo que importa es que los ficheros antiguos se borren al llegar al límite. Pasadas unas semanas, revisa: ```bash ls -1 /var/log/miapp/ | wc -l ls -1 /var/log/auth.log* | head -n 3 sudo grep -E 'miapp|auth.log' /var/lib/logrotate/status ``` ```output 31 /var/log/auth.log /var/log/auth.log-20260920 /var/log/auth.log-20260913.gz "/var/log/miapp/app.log" 2026-9-25-0:0:3 "/var/log/auth.log" 2026-9-20-0:0:2 ``` Si se ejecuta logrotate con errores, aparecerán en su servicio: ```bash journalctl -u logrotate.service --since "7 days ago" ``` Recuerda que los logs de un único servidor desaparecen con él. Para cumplir retenciones largas de forma fiable, copia los ficheros rotados (`*.gz`) a otro sistema, por ejemplo un servidor de backups o almacenamiento de objetos, y aplica allí también la política de borrado. ## Solución de problemas - **`error: skipping "/var/log/miapp/app.log" because parent directory has insecure permissions`**: el directorio no pertenece a root o es escribible por un grupo distinto de root. Añade la directiva `su usuario grupo` con el propietario del directorio, como en el paso 3. - **`error: duplicate log entry for /var/log/auth.log`**: el mismo fichero aparece en dos bloques. Elimínalo de uno de ellos. - **La aplicación sigue escribiendo en el fichero rotado** (`app.log-2026...` crece y `app.log` se queda vacío): el servicio no reabre el log. Revisa que responde a `SIGHUP` o cambia a `copytruncate`. - **`maxsize` no rota a tiempo**: logrotate solo se ejecuta una vez al día. Si necesitas comprobarlo más a menudo, crea un override con `sudo systemctl edit logrotate.timer` y define `[Timer]` con una línea `OnCalendar=` vacía seguida de `OnCalendar=hourly`. ## Conclusión Tienes una política de retención definida y aplicada: 30 días con límite de tamaño para la aplicación, 12 meses para los logs de autenticación y el journal acotado en espacio y antigüedad. Como siguientes pasos, puedes registrar las acciones administrativas con auditd, eliminar datos personales de los logs antes de conservarlos con la guía de anonimización de logs, y centralizar los logs de varios servidores en un único sistema con su propia retención.