Home Comunidade Eventos YouTube Networks Desafios // produtos Academy News CTI | CVE Contato

05 - Journald (Coleta de Logs)

video explicativo
Video explicativoEspaco reservado para o video desta anotação — adicione video: https://youtu.be/... no frontmatter da nota.

1. A Ruptura com o Paradigma de Texto Plano (Syslog)

Por mais de três décadas, o padrão de logging no ecossistema UNIX foi ditado pelo protocolo syslog e suas implementações clássicas (como syslogd, rsyslog e syslog-ng). Sob este modelo, os logs eram essencialmente fluxos de strings de texto plano gravados em arquivos espalhados pelo diretório /var/log/ (messages, auth.log, secure, daemon.log).

Este paradigma arquitetural apresentava deficiências críticas intransponíveis para infraestruturas modernas em larga escala:

  • Falta de Estruturação: Um administrador dependia inteiramente de expressões regulares (grep, awk, sed) para extrair informações. Uma mudança no formato da string de saída por parte do desenvolvedor do aplicativo quebrava silenciosamente todos os scripts de monitoramento.
  • Fragilidade Forense (Spoofing): No modelo clássico, o aplicativo gerador do log era responsável por declarar seu próprio nome, timestamp e PID na mensagem enviada ao soquete local. Um processo malicioso comprometido poderia facilmente falsificar sua identidade, injetando logs se passando pelo sshd ou pelo kernel.
  • Isolamento de Contexto: Arquivos de texto não capturavam o estado global do sistema. Uma mensagem de erro raramente informava o cgroup ao qual o processo pertencia, seu contexto SELinux/AppArmor, ou se ele fazia parte de uma sessão interativa ou de um daemon automatizado.

O systemd-journald foi projetado para resolver estas falhas estruturais, movendo a coleta de logs para um modelo de Eventos Estruturados. Nele, uma mensagem de log não é apenas uma linha de texto, mas um dicionário de metadados tipados e indexados nativamente em árvores B+ (B+ Trees) no momento exato de sua geração.


2. A Arquitetura de Interceptação Unificada (Multiplexação de Fontes)

A genialidade operacional do journald reside na sua capacidade de atuar como um funil central (um buraco negro de telemetria) que captura absolutamente todos os fluxos de saída de uma máquina Linux, independentemente de como foram gerados. O systemd-journald expõe múltiplos vetores de ingestão simultaneamente:

  1. Interceptação de Stdout/Stderr (Pipes Anônimos): Quando o PID 1 (systemd) inicia uma unidade .service, ele não conecta a saída padrão (FD 1) e o erro padrão (FD 2) do processo ao /dev/null (como faziam os scripts SysVinit). Ele cria um pipe anônimo entre o processo recém-nascido e o journald. Isso significa que desenvolvedores de software não precisam mais integrar bibliotecas complexas de syslog (como a função C syslog()). Qualquer printf(), echo ou console.log() lançado pela aplicação é capturado cirurgicamente e roteado para o journal.
  2. Soquete de Compatibilidade Syslog (/dev/log): Para manter retrocompatibilidade absoluta com aplicações legadas, o journald sequestra o soquete UNIX padrão /dev/log. Quando um binário antigo tenta enviar uma mensagem via protocolo Syslog tradicional, o journald recebe o pacote, extrai a Facility e a Priority (nível de erro), e o converte internamente para a sua estrutura nativa.
  3. Buffer de Mensagens do Kernel (/dev/kmsg): O journald consome continuamente as mensagens do anel de buffer do kernel (Kernel Ring Buffer, o mesmo lido pelo comando dmesg). Isso unifica a linha do tempo: falhas de drivers de hardware e segfaults de espaço de kernel aparecem na mesma interface cronológica que os logs de espaço de usuário, perfeitamente sincronizados.
  4. API Nativa (sd-journal): Aplicações modernas compiladas contra a libsystemd podem enviar dicionários de dados complexos diretamente via IPC. Em vez de enviar "Erro ao abrir arquivo", a aplicação pode enviar o equivalente a { "MESSAGE": "Falha de I/O", "FILE_NAME": "/etc/config", "ERROR_CODE": "EACCES" }.
  5. Subsistema de Auditoria (Auditd): O journald pode se integrar ao auditd do kernel via netlink socket, coletando os registros de segurança granulares do sistema operacional.

3. Injeção de Metadados e Integridade Forense (Implicit Metadata)

A propriedade mais valiosa do systemd-journald é a injeção implícita de metadados confiáveis (Trusted Metadata).

Quando um processo escreve no pipe do journald ou no soquete /dev/log, o daemon coletor imediatamente interroga o kernel Linux utilizando a estrutura de credenciais (struct ucred) passada através do soquete UNIX (SCM_CREDENTIALS). O processo remetente não pode falsificar essas informações, pois elas são chanceladas pelo próprio kernel Ring 0.

Para cada linha de log gerada, o journald anexa nativamente dezenas de campos ocultos, que incluem (mas não se limitam a):

  • _PID e _UID: O identificador do processo e o identificador do usuário que efetivamente gerou o log.
  • _SYSTEMD_UNIT: O arquivo .service ou escopo exato responsável por aquele processo. Se um binário do Apache realizar um sub-fork malicioso, o log ainda estará inexoravelmente atrelado a apache2.service.
  • _SYSTEMD_CGROUP: O caminho completo da árvore de processos (Control Group).
  • _BOOT_ID: Um hash UUID gerado pelo kernel no momento da inicialização do sistema (lido de /proc/sys/kernel/random/boot_id). Isso permite consultas temporais absolutas (ex: "Mostre-me os logs do nginx de três reboots atrás"), eliminando a ambiguidade de timestamps repetidos em arquivos reciclados.
  • _MACHINE_ID: O UUID da instalação física da máquina (lido de /etc/machine-id), essencial para agregação de logs em arquiteturas de cluster e sistemas distribuídos.
  • _SELINUX_CONTEXT: O rótulo de segurança mandatório ativo no milissegundo em que o log foi emitido.

Esta riqueza semântica destrói a dependência de expressões regulares. Um administrador não precisa mais fazer um grep por uma string instável; ele pode emitir uma consulta binária matemática: "Retorne todos os logs onde _SYSTEMD_UNIT=ssh.service E PRIORITY=4 E _UID=0".


4. O Formato Binário e a Criptografia FSS (Forward Secure Sealing)

A decisão de arquitetar o banco de dados do journal como um arquivo binário proprietário (.journal) foi o aspecto mais controverso da implementação do systemd, pois violava a máxima do UNIX de que "tudo deve ser texto puro". No entanto, do ponto de vista de engenharia de dados, arquivos binários permitem otimizações impossíveis no texto plano.

O formato .journal utiliza estruturas semelhantes a tabelas hash e B-Trees, permitindo buscas em tempo O(1) ou O(log N), da cauda do arquivo para a cabeça (busca reversa instantânea), algo que exige a leitura exaustiva do disco (full table scan) ao se usar o comando tac ou tail em arquivos gigabytes de texto. Além disso, o formato aplica deduplicação de strings nativa: se uma variável de ambiente ou mensagem idêntica for repetida 10.000 vezes, o journald armazena a string física apenas uma vez e cria ponteiros lógicos para ela, reduzindo drasticamente a exaustão de I/O em discos SSD.

O Selo Criptográfico (FSS)

Arquiteturas de segurança governamentais ou de alta conformidade (PCI-DSS, HIPAA) exigem que arquivos de log sejam invioláveis. Se um invasor escalar privilégios para root, a primeira ação tática é apagar ou modificar os arquivos /var/log/auth.log para encobrir rastros.

O journald neutraliza esta ameaça implementando o Forward Secure Sealing (FSS). Baseado na pesquisa criptográfica de Forward Secrecy, o administrador pode inicializar o journal com chaves assimétricas. A cada intervalo de tempo (por padrão, 15 minutos), o journald gera um selo criptográfico (um HMAC gerado a partir do conteúdo dos logs e do hash do bloco anterior) e rotaciona a chave de selamento de forma irreversível na memória, descartando a chave antiga.

Se um hacker obtiver o nível root, ele poderá deletar o arquivo do journal inteiro ou interromper o serviço, o que acionará alarmes imediatos de indisponibilidade. Mas se ele tentar modificar furtivamente uma linha de log do passado, o selo criptográfico será invalidado (pois a chave necessária para recomputar o hash daquele intervalo de tempo de 15 minutos atrás já foi destruída pelo sistema e não reside mais em RAM nem no disco). Qualquer auditoria posterior via journalctl --verify relatará matematicamente o milissegundo exato da violação estrutural, garantindo integridade forense perfeita e incontestável em tribunais de auditoria de segurança da informação.


5. Arquitetura de Roteamento e Coexistência (Forwarding)

Adoções de novas tecnologias sistêmicas não podem romper arquiteturas legadas da noite para o dia. Os engenheiros do systemd desenharam o journald não apenas como um repositório final, mas como um roteador de alta velocidade.

Muitas organizações possuem agentes sofisticados como Splunk, Filebeat, ou lógicas de roteamento avançado já consolidadas em regras do syslog-ng que não entendem a API do journald. Para suprir essa lacuna sistêmica, o arquivo de configuração master /etc/systemd/journald.conf oferece as diretivas de encaminhamento.

A opção ForwardToSyslog=yes instrui o journald a clonar cada entrada que recebe, transformá-la de volta em uma string Syslog clássica, e injetá-la em um soquete dedicado (/run/systemd/journal/syslog). O daemon tradicional (como o rsyslog) escuta neste soquete em vez do clássico /dev/log, recebendo a cópia do evento de forma transparente. Assim, o sistema desfruta simultaneamente da pesquisa binária indexada avançada no servidor local e mantém os coletores remotos (log forwarders) baseados em texto em pleno funcionamento. Outras diretivas como ForwardToConsole=, ForwardToKMsg= e ForwardToWall= permitem alertar administradores logados em terminais diretamente em eventos catastróficos.