
¿Qué es Journald?
Journald es un servicio (como componente de systemd) de registro de eventos, es decir, un recopilador de logs del sistema.
Es una buena alternativa a syslog, ya que almacena los registros del sistema en un formato binario, lo que permite un acceso más rápido, en comparación con el formato de texto plano utilizado por syslog.
Además, journald tiene características adicionales, como la indexación de datos del registro y la posibilidad de agregarle metadatos adicionales a los eventos registrados.
Journald también proporciona una estructura de registro más detallada que syslog. Cada registro en journald contiene información como la hora de creación, el identificador de la sesión, el identificador de la unidad (UUID), el identificador del servicio, el identificador del proceso y otros metadatos adicionales.
Objetivo:
La misión de este artículo es la implementación en un escenario con varias máquinas, un sistema de recolección de logs mediante journald en lugar de syslog.
Todo esto será posible, gracias al paquete systemd-journal-remote.
Requisitos Previos:
El escenario que he usado ha sido el disponible en OpenStack, que consiste en una máquina servidor donde se implementará el sistema de recolección de logs, y una máquina cliente independiente conectada en la misma red.
-
Servidor: máquina Odin (Debian 12).
-
Cliente: máquina Hela (Rocky Linux).
Empezamos!
En el Servidor (Debian 12):
Para poder llevar a cabo todo lo planteado, el primer paso es instalar la herramienta systemd-journal-remote tanto en Odin (servidor) como en Hela (cliente), aunque primero veremos la parte del servidor y luego pasaremos al cliente. Así que hay que instalar en Odin:
sudo apt install systemd-journal-remote
Al ser una red privada no he usado https, sino http y para hacerlo lo primero es copiar el servicio para poder tener una versión editable sin que afecte al original:
cp /lib/systemd/system/systemd-journal-remote.service /etc/systemd/system/
Ahora en lo que acabamos de copiar que es /etc/systemd/system/systemd-journal-remote.service hay que modificarlo para que quede de la siguiente manera:
# SPDX-License-Identifier: LGPL-2.1-or-later # # This file is part of systemd. # # systemd is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. [Unit] Description=Journal Remote Sink Service Documentation=man:systemd-journal-remote(8) man:journal-remote.conf(5) Requires=systemd-journal-remote.socket [Service] #ExecStart=/lib/systemd/systemd-journal-remote --listen-http=-3 --output=/mnt (esta linea es que lo intente con un volumen pero no habia manera, me daba error de read-only filesystem, pero estaba montado con lectura y escritura, en el fstab tambien, lo hice varias veces y nada) ExecStart=/lib/systemd/systemd-journal-remote --listen-http=-3 --output=/var/log/journal/remote/ LockPersonality=yes LogsDirectory=journal/remote MemoryDenyWriteExecute=yes NoNewPrivileges=yes PrivateDevices=yes PrivateNetwork=yes PrivateTmp=yes ProtectProc=invisible ProtectClock=yes ProtectControlGroups=yes ProtectHome=yes ProtectHostname=yes ProtectKernelLogs=yes ProtectKernelModules=yes ProtectKernelTunables=yes ProtectSystem=strict RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 RestrictNamespaces=yes RestrictRealtime=yes RestrictSUIDSGID=yes SystemCallArchitectures=native User=systemd-journal-remote WatchdogSec=3min # If there are many split up journal files we need a lot of fds to access them # all in parallel. LimitNOFILE=524288 [Install] Also=systemd-journal-remote.socket
Nota:
LockPersonality=yes: Bloquea el cambio de "personalidad" (modo de compatibilidad) del proceso, aumentando la seguridad. LogsDirectory=journal/remote: Define un directorio especial donde se almacenarán los logs generados por este servicio. MemoryDenyWriteExecute=yes: Impide que los procesos asignen memoria que sea a la vez ejecutable y escribible, lo que previene ciertos tipos de exploits. NoNewPrivileges=yes: Garantiza que el proceso y todos sus subprocesos no puedan obtener nuevos privilegios (por ejemplo, elevar privilegios). PrivateDevices=yes: Aísla el servicio de los dispositivos del sistema, creando una vista privada de /dev. PrivateNetwork=yes: Aísla el servicio en su propio espacio de red, evitando que acceda a la red del host directamente. PrivateTmp=yes: Proporciona un directorio temporal privado (/tmp) que no es compartido con otros servicios. ProtectProc=invisible: Hace que los procesos del sistema sean invisibles al servicio, aumentando la seguridad. ProtectSystem=strict: Proporciona un entorno de archivos de sistema de sólo lectura, restringiendo aún más lo que el servicio puede modificar. RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6: Limita las familias de direcciones a las que el servicio puede acceder, reduciendo la superficie de ataque. User=systemd-journal-remote: Especifica que el servicio se ejecutará bajo el usuario systemd-journal-remote, reduciendo el riesgo de daños si es comprometido. WatchdogSec=3min: Define un intervalo de tiempo después del cual systemd reiniciará el servicio si no recibe una señal de "vivo" (watchdog) del proceso.
Luego he creado el directorio /var/log/journal/remote y le he cambiado el propietario porque este servicio, debe tener privilegios de escritura en el directorio para poder almacenar los logs que vaya recopilando. Para hacer esto es:
mkdir -p /var/log/journal/remote
chown systemd-journal-remote /var/log/journal/remote
Hecho esto, recargo la configuración de systemd para que se aplique e inicio el servicio:
systemctl daemon-reload
systemctl start systemd-journal-remote
En el cliente (Rocky Linux):
Hecho esto, ahora en Hela, instalo el mismo paquete que con Odin, pero como es Rocky, se emplea dnf, en lugar de apt. Si tu equipo cliente no es Rocky, hazlo como en Odin.
sudo dnf install systemd-journal-remote

Instalada la herramienta, el siguiente paso que hay que hacer es crear un usuario llamado systemd-journal-upload con:
adduser --system --home /run/systemd --no-create-home --user-group systemd-journal-upload
Ahora hay que especificarle al cliente, el FQDN de la máquina servidor (que en este caso es odin.andres.gonzalonazareno.org) y el puerto 19532 (si se usa OpenStack hay que abrirlo).
Para indicar estos datos hay que ir al archivo /etc/systemd/journal-upload.conf, añadiendo en la sección de Upload:
URL=http://odin.andres.gonzalonazareno.org:19532

Y reiniciar el servicio para que se aplique la nueva configuración:
sudo systemctl restart systemd-journal-upload.service
Comprobaciones:
Ahora en Odin, si voy al directorio /var/log/journal/remote se ha creado un archivo de log, del uso del equipo cliente:

Para poder ver lo que contiene y revisar que no haya problemas (ese ese el nombre de mi archivo generado):
sudo journalctl --file=/var/log/journal/remote/remote-172.22.201.174.journal

Nota Importante:
A la hora de realizar este sistema de recolección de logs, hay que tener en cuenta el espacio del sistema del servidor donde vaya a realizarse.
Este sistema seguirá emitiendo logs sin parar, y esto provoca que se consuma el espacio en disco. Lo más conveniente seria, anexarle un volumen al servidor y que se guarden los logs ahí, porque si se llena la memoria del sistema completamente, no podremos iniciar sesión y una larga lista de errores y problemas como es obvio.
Por todo lo anterior, lo que recomiendo es o anexar un volumen extra para ello, o dejar la unidad parada mientras que no se vaya a utilizar o mientras no sea necesario.
Esto es para un entorno didáctico, ya que en un entorno profesional no es para nada recomendable estar parando la unidad, ya que habria movimientos de logs de los clientes que no se registrarian durante el tiempo que estuviese apagado.