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:

NormaQué 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
RGPDNo fija un plazo: los logs con datos personales solo se conservan el tiempo necesario para su finalidad
ISO/IEC 27001No fija un plazo: debe estar definido en tu política y aplicarse de forma consistente

Para estimar cuánto ocupará, mira el tamaño actual de los logs y cuánto crecen al día:

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:

logrotate --version
systemctl list-timers logrotate.timer
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:

DirectivaQué hace
daily, weekly, monthlyFrecuencia de rotación
rotate NNúmero de ficheros rotados que se conservan; el más antiguo se borra
maxsize 100MRota antes de tiempo si el fichero supera ese tamaño (se evalúa cada vez que se ejecuta logrotate)
compress / delaycompressComprime con gzip los rotados, dejando sin comprimir el más reciente
dateextAñade la fecha al nombre en lugar de un número (app.log-20260925)
missingok / notifemptyNo da error si falta el fichero y no rota ficheros vacíos
create 0640 usuario grupoCrea el fichero nuevo con esos permisos tras rotar
copytruncateCopia el fichero y lo vacía, para aplicaciones que no saben reabrir su log
postrotate ... endscriptComando 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:

sudo install -d -m 0750 -o miapp -g adm /var/log/miapp

Crea el fichero de configuración de logrotate:

sudo nano /etc/logrotate.d/miapp

Añade este bloque:

/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:

sudo logrotate -d /etc/logrotate.d/miapp
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:

sudo logrotate -f -v /etc/logrotate.d/miapp
ls -l /var/log/miapp/
-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:

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.

Crea un bloque propio para auth.log:

sudo nano /etc/logrotate.d/auth-retention
/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:

sudo logrotate -d /etc/logrotate.conf 2>&1 | grep -iE 'error|duplicate' || echo "Configuración correcta"
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:

journalctl --disk-usage
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:

sudo mkdir -p /etc/systemd/journald.conf.d
sudo nano /etc/systemd/journald.conf.d/retention.conf
[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:

sudo systemctl restart systemd-journald

Para limpiar de inmediato lo que ya supera el nuevo límite, usa --vacuum-time o --vacuum-size:

sudo journalctl --vacuum-time=90d
Vacuuming done, freed 0B of archived journals from /var/log/journal/...

Comprueba cuál es la entrada más antigua que se conserva:

journalctl -q -o short-iso --no-pager | head -n 1
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:

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
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:

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.