Pular para o conteúdo
, ,

Gravando sessões de terminal com tlog: Auditoria que funciona [pt.2]

Aprenda a gravar sessões de terminal no Linux com tlog e enviar para o Graylog. Substitua o rootsh por uma solução moderna com reprodução fiel e logs centralizados.

Avatar de DK
DKTrabalha com Linux e Unix a mais de 23 anos e possui as certificações LPI 3, RHCE, AIX e VIO.

25 dez, 2025
18 min de leitura

Atualizado em 24/05/2026; Graylog 7.0.7

Série CSI do Linux


Lembra do rootsh? Aquele keylogger de terminal que eu escrevi sobre há mais de 15 anos atrás? A ideia era simples: gravar tudo que o usuário digitava no terminal pra fins de auditoria. Funcionava… mais ou menos.

O problema é que o rootsh tinha algumas limitações sérias. Ele gravava num arquivo local (fácil de apagar), não lidava bem com sessões interativas tipo vim ou top, e a reprodução era… digamos… criativa. Você precisava de paciência e imaginação pra entender o que tinha acontecido.

Mas o conceito era sólido. Em ambientes onde várias pessoas têm acesso root, ou onde terceiros fazem manutenção, saber exatamente o que foi digitado pode ser a diferença entre resolver um incidente em minutos ou passar dias tentando reproduzir o problema.

A evolução: tlog

O tlog é a resposta moderna pra esse problema. Desenvolvido pela Red Hat como parte do projeto Scribery, ele faz o que o rootsh tentava fazer, só que direito:

  • Grava em JSON: Formato estruturado, pesquisável, indexável
  • Suporta journald e syslog: Integra com a infraestrutura de logs que você já tem
  • Reprodução fiel: Funciona como um “vídeo em texto”, você vê exatamente o que o usuário viu
  • Integração com SSSD: Gerenciamento centralizado de quem é gravado
  • Interface web: Via Cockpit, dá pra assistir as sessões no navegador

E o melhor: como vamos mandar tudo pro Graylog que montamos no artigo anterior, os logs saem da máquina em tempo real. Se alguém ganhar root e tentar apagar os rastros… tarde demais.

O que vamos montar

A arquitetura segue um padrão bem estabelecido:

Screenshot 2026-05-24 at 10.18.14

O tlog grava a sessão e manda pro syslog local. O rsyslog pega essas mensagens e encaminha pro Graylog. Simples, confiável, e usa ferramentas que já existem em qualquer Linux.

Pré-requisitos

  • Graylog funcionando: Se você ainda não montou, volta pro artigo anterior
  • Um servidor Linux pra testar: Fedora 44+, RHEL 9+, ou Ubuntu 24.04 funcionam bem
  • Acesso root: Vamos mexer em configurações de sistema

Instalação do tlog

No Fedora/RHEL, o tlog já está nos repositórios oficiais:

sudo dnf install tlog

No Debian/Ubuntu, o pacote também está disponível:

sudo apt install tlog

Depois da instalação, temos três comandos principais:

  • tlog-rec: Grava sessões de programas específicos
  • tlog-rec-session: Atua como shell de login, gravando toda a sessão do usuário
  • tlog-play: Reproduz as gravações

Configurando o tlog para usar syslog

Por padrão, o tlog grava no journald. Funciona, mas pra enviar pro Graylog de forma simples, o syslog é mais direto.

O arquivo de configuração fica em /etc/tlog/tlog-rec-session.conf. Vamos editá-lo:

sudo vi /etc/tlog/tlog-rec-session.conf

O arquivo é um JSON. Precisamos mudar o writer de journal para syslog:

{
    "shell": "/bin/bash",
    "notice": "\nATENÇÃO: Sua sessão está sendo gravada para fins de auditoria.\n\n",
    "writer": "syslog",
    "log": {
        "input": false
    }
}

Algumas observações importantes:

  • shell: Define qual shell será executado dentro da sessão gravada
  • notice: Mensagem exibida ao usuário antes do shell iniciar. O usuário vê o aviso e depois o prompt aparece normalmente. Boa prática avisar que está sendo gravado. Se usar acentos, garanta que o arquivo está salvo em UTF-8
  • writer: Mudamos pra syslog pra poder encaminhar pro Graylog
  • log.input: Por padrão é false, ou seja, não grava o que o usuário digita, só a saída. Isso evita capturar senhas em texto puro
Comportamento do terminal
O tlog simula um pseudo-terminal (PTY) entre o usuário e o shell real. Em alguns casos, isso pode afetar o redimensionamento da janela do terminal ou o comportamento de programas que dependem de detecção de TTY. Se algum programa se comportar de forma estranha durante uma sessão gravada, esse é o motivo.
Sobre gravar input
Se você habilitar "input": true, tudo que o usuário digitar será gravado, incluindo senhas. Em alguns contextos de auditoria isso é necessário, mas pense bem antes de ativar. E avise os usuários.

Testando localmente

Antes de configurar o envio remoto, vale testar se o tlog está funcionando. Basta executar:

tlog-rec-session

Você vai ver a mensagem de aviso que configuramos, e então um shell normal. Faça algumas coisas, ls, pwd, echo "teste", e depois saia com exit.

Pra verificar se gravou, olhamos o log. O caminho varia por distro:

# Funciona em qualquer distro com systemd
sudo journalctl -t tlog

# Fedora/RHEL (tlog usa facility authpriv)
sudo grep tlog /var/log/secure

# Debian/Ubuntu
sudo grep tlog /var/log/auth.log

Se aparecerem mensagens JSON gigantes, está funcionando. Cada mensagem contém um pedaço da sessão, timing, output, e metadados.

Ubuntu 24.04 e o syslog
Algumas imagens cloud/server do Ubuntu 24.04 não incluem o rsyslog por padrão; tudo fica apenas no journald. Se o arquivo /var/log/syslog não existir, use journalctl -t tlog ou instale o rsyslog com sudo apt install rsyslog.

Configurando usuários para gravação automática

Tem duas formas de fazer um usuário ter suas sessões gravadas automaticamente:

Método 1: Trocar o shell do usuário

O jeito mais simples é mudar o shell de login do usuário pra tlog-rec-session:

sudo usermod -s /usr/bin/tlog-rec-session auditado

A partir de agora, toda vez que o usuário auditado fizer login, a sessão será gravada automaticamente.

Pra reverter:

sudo usermod -s /bin/bash auditado

Método 2: Usar SSSD (para ambientes com LDAP/AD)

O SSSD permite gerenciar centralmente quais usuários ou grupos são gravados, sem precisar trocar o shell de cada um manualmente. Mas tem um detalhe importante: o SSSD session recording só funciona quando o SSSD é responsável pela autenticação do usuário.

Na prática, isso significa que o método funciona bem em ambientes onde:

  • Usuários vêm do Active Directory ou LDAP
  • O SSSD já está configurado como provedor de identidade
  • O PAM está configurado para usar SSSD (via authselect)

Para usuários puramente locais (apenas /etc/passwd), o SSSD não está no caminho da autenticação, e a seção [session_recording] é ignorada. Nesses casos, o Método 1 (trocar o shell) é mais direto e confiável.

Se você já usa SSSD para autenticação centralizada, adicione a seção de session recording ao seu /etc/sssd/sssd.conf:

[session_recording]
scope = some
users = root, admin
groups = wheel

A seção [session_recording] controla:

  • scope: Pode ser none, some, ou all
  • users: Lista de usuários pra gravar (quando scope é some)
  • groups: Lista de grupos pra gravar (quando scope é some)

Depois de editar, reinicie o SSSD:

sudo systemctl restart sssd
Quando usar cada método?
Método 1 (trocar shell): Funciona sempre, independente de como os usuários são gerenciados. Ideal para servidores isolados ou com poucos usuários.

Método 2 (SSSD): Ideal quando você já tem SSSD integrado com AD/LDAP e quer gerenciar a gravação centralmente sem tocar no shell de cada usuário.

Enviando pro Graylog via rsyslog

Agora a parte que conecta tudo: fazer o rsyslog encaminhar as mensagens do tlog pro Graylog.

Criando o input TCP no Graylog

No artigo anterior, criamos apenas o input Syslog UDP. As mensagens do tlog podem ser grandes (sessões com muito output geram payloads JSON extensos), e pacotes UDP têm limite de tamanho. Mensagens maiores chegam truncadas ou se perdem.

Pra resolver isso, vamos usar TCP. No Graylog, acesse:

System > Inputs > selecionar Syslog TCP no dropdown > Launch new input

Configure:

  • Title: Syslog TCP - tlog
  • Port: 1514
  • Bind address: 0.0.0.0

As demais opções podem ficar no padrão. Confirme com Launch input e aguarde o indicador ficar verde.

03-inputs-tcp-udp
Mesma porta, protocolos diferentes
TCP e UDP são protocolos distintos, então podem compartilhar o mesmo número de porta sem conflito. O input UDP que criamos antes continua funcionando normalmente na 1514. Agora temos os dois escutando.

Configurando o rsyslog

Antes de criar a regra de encaminhamento, precisamos aumentar o limite de tamanho de mensagem do rsyslog. O padrão é 8KB, mas os payloads JSON do tlog frequentemente excedem isso em sessões reais.

Edite o arquivo principal do rsyslog:

sudo vi /etc/rsyslog.conf

Adicione no início do arquivo (antes de qualquer outra configuração):

$MaxMessageSize 64k
Posição importa
O $MaxMessageSize precisa estar antes das diretivas de módulo e regras do rsyslog. Se colocar no final do arquivo, o limite já foi definido como 8KB quando os módulos carregaram, e sessões com muito output vão chegar truncadas no Graylog sem explicação óbvia.

Agora vamos criar a regra de encaminhamento:

sudo vi /etc/rsyslog.d/10-graylog.conf

O conteúdo:

# Encaminha logs do tlog pro Graylog (TCP)
if $programname == 'tlog' then @@IP_DO_GRAYLOG:1514;RSYSLOG_SyslogProtocol23Format

# Alternativa: encaminhar TODOS os logs (não só tlog)
# *.* @@IP_DO_GRAYLOG:1514;RSYSLOG_SyslogProtocol23Format

Algumas explicações:

  • @@: Dois @ significa TCP (um @ seria UDP). Usamos TCP porque os payloads JSON do tlog podem ser grandes. Sessões com muito output (um cat em arquivo grande, por exemplo) facilmente estouram o limite de pacote UDP e chegam truncados no Graylog
  • $programname == ‘tlog’: Filtra só as mensagens do tlog, evitando poluir o Graylog com logs de cron, mail, kernel, etc. Se você quer monitoramento completo do servidor, descomente a linha alternativa
  • IP_DO_GRAYLOG:1514: O IP e porta do seu servidor Graylog (a porta 1514 que configuramos no artigo anterior)
  • RSYSLOG_SyslogProtocol23Format: Formato RFC 5424, mais estruturado que o antigo BSD syslog

Reinicie o rsyslog:

sudo systemctl restart rsyslog

Testando a integração

Hora de ver se tudo funciona junto. Na máquina cliente:

tlog-rec-session

Faça algumas coisas no terminal, depois saia com exit.

Agora vá na interface do Graylog (Search) e procure por mensagens recentes. Você deve ver as mensagens JSON do tlog aparecendo.

01-search-tlog

Se quiser filtrar só as mensagens do tlog:

application_name:tlog

Ou buscar por um usuário específico:

application_name:tlog AND full_message:auditado
02-search-tlog-user

Checklist de verificação

Se as mensagens apareceram no Graylog, vale confirmar que tudo está no lugar:

  • rsyslog encaminhando: sudo journalctl -u rsyslog sem erros de Permission denied ou Connection refused
  • Mensagens com JSON completo: o campo full_message contém o JSON do tlog (não aparece truncado)
  • Campo application_name: aparece como tlog (não como tlog-rec-session)
  • Múltiplos usuários: se testou com mais de um usuário, o campo "user" dentro do JSON reflete o usuário correto

Se o JSON aparecer cortado, verifique se o $MaxMessageSize 64k está no início do /etc/rsyslog.conf (antes de qualquer outra diretiva) e reinicie o rsyslog.

Reproduzindo as sessões

Aqui vem um ponto importante: o tlog-play foi feito pra ler do journald ou de arquivos locais. Quando os logs estão no Graylog, precisamos de um passo extra.

Opção 1: Exportar do Graylog e reproduzir localmente

No Graylog, você pode exportar as mensagens de uma sessão e reproduzir no terminal. O passo a passo:

  1. Na tela de Search, filtre pelo ID da sessão: tlog_session_id:7eeedfc2... (se criou o extractor) ou busque pelo rec ID no full_message
  2. No widget All Messages, clique no ícone de download (Export all search results)
  3. No dialog de exportação, adicione o campo full_message na lista de campos (é ele que contém o JSON do tlog)
    04-export-dialog
  4. Clique em Start Download. O Graylog vai baixar um arquivo CSV

Depois, no terminal:

# Extrai o JSON do CSV exportado
tail -n +2 mensagens_exportadas.csv | grep -o '{.*}' > sessao.json
tlog-play -r file --file-path sessao.json

Opção 2: Script de extração

Pra facilitar a vida, um script que extrai sessões do syslog local (antes de ir pro Graylog) ou de um arquivo exportado:

#!/bin/bash
# extract-session.sh - Extrai e reproduz uma sessão tlog

if [ -z "$1" ]; then
    echo "Uso: $0 tlog_rec_id"
    echo "Exemplo: $0 7eeedfc2..."
    exit 1
fi

SESSION_ID="$1"
TEMP_FILE=$(mktemp)

# Tenta extrair do journal primeiro (funciona com writer syslog e journal)
if journalctl -t tlog -o cat --no-pager 2>/dev/null | grep "$SESSION_ID" > "$TEMP_FILE" && [ -s "$TEMP_FILE" ]; then
    echo "Sessão encontrada no journal. Reproduzindo..."
    tlog-play -r file --file-path "$TEMP_FILE"
else
    # Tenta dos arquivos de log (authpriv vai pro /var/log/secure no RHEL)
    for log in /var/log/secure /var/log/messages /var/log/auth.log /var/log/syslog; do
        if [ -f "$log" ]; then
            grep "tlog.*$SESSION_ID" "$log" | sed 's/^.*\({.*}\).*$/\1/' > "$TEMP_FILE"
            if [ -s "$TEMP_FILE" ]; then
                echo "Sessão encontrada em $log. Reproduzindo..."
                tlog-play -r file --file-path "$TEMP_FILE"
                break
            fi
        fi
    done
fi

rm -f "$TEMP_FILE"

Salve como /usr/local/bin/extract-session.sh e dê permissão de execução. O script precisa ser executado como root (ou com sudo), porque o journalctl e os arquivos de log em /var/log/secure exigem permissão elevada:

sudo chmod +x /usr/local/bin/extract-session.sh
Sobre o script
O sed assume o formato padrão de log do journal/syslog. Se você customizou o template do rsyslog (mudou o formato da linha), vai precisar ajustar a expressão regular pra extrair o JSON corretamente. Pra uma solução mais completa, considere usar jq, que lida melhor com formatos variados de JSON.

Opção 3: Interface web com Cockpit (opcional)

Se você instalou o Cockpit no servidor, pode adicionar o módulo de session recording:

sudo dnf install cockpit-session-recording

Acesse https://seu-servidor:9090 e vá em Session Recording. Lá você consegue ver e reproduzir sessões diretamente no navegador, mas só as que estão no journal local, não as que já foram pro Graylog.

Identificando sessões no Graylog

Cada sessão do tlog tem um identificador único no campo rec dentro do JSON. No Graylog, você pode criar um extractor pra isolar esse ID e facilitar a busca.

Vá em System > Inputs > clique no seu input Syslog TCP > Manage extractors > Add extractor

Configure um extractor do tipo Regular expression com:

  • Source field: full_message
  • Regular expression: "rec":"([a-f0-9-]+)"
  • Target field: tlog_session_id
  • Condition: Only attempt extraction if field contains string tlog

Agora você pode buscar sessões específicas com:

tlog_session_id:7eeedfc2326849e7880e93e64cb40071-1a46-ae0f7

Dashboard de auditoria

Antes de criar o dashboard, vale a pena adicionar mais um extractor no input TCP para isolar o campo user do JSON. Siga o mesmo processo que usamos pro rec:

  • Source field: full_message
  • Regular expression: "user":"([^"]+)"
  • Target field: tlog_user
  • Condition: Only attempt extraction if field contains string tlog

Com isso pronto, vamos montar o dashboard.

Criando o dashboard

  1. Vá em Dashboards > Create new dashboard
    02-tlog_dashboard-list
  2. No campo de busca no topo, digite application_name:tlog e pressione Enter
    02-tlog_dashboard-query
  3. Na barra lateral esquerda, clique no ícone + (Create) para abrir o painel de widgets
    02-tlog_dashboard-create-sidebar

Adicionando um histograma de atividade

  1. No painel Create, clique em Aggregation
    02-tlog_dashboard-aggregation-empty
  2. Na configuração do widget:
    • Rows: selecione timestamp
    • Visualization: selecione Bar Chart
      02-tlog_dashboard-histogram-preview
  3. Clique em Create e o histograma aparece no dashboard

Adicionando sessões por usuário

  1. Clique novamente em Aggregation no painel Create
  2. Configure:
    • Rows: selecione tlog_user
    • Metrics: mantenha count()
      02-tlog_dashboard-aggregation-config
    • Sort: Descending
    • Visualization: Data Table ou Pie Chart
  3. Clique em Create
    02-tlog_dashboard-widget-saved

Adicionando sessões por host

  1. Mais uma Aggregation:
    • Rows: selecione source
    • Metrics: count()
    • Visualization: Data Table
  2. Clique em Create

Salvando

Clique em Save as no canto superior direito,

02-tlog_dashboard-save-dialog

dê o nome Auditoria tlog e confirme.

02-tlog_dashboard-final

Esse dashboard facilita identificar padrões, tipo um usuário que só faz login às 1 da manhã, ou um aumento súbito de atividade root.

Considerações de segurança

Algumas coisas pra ter em mente:

  1. Avise os usuários: Além da mensagem de aviso do tlog, documente a política de gravação. Em alguns países, gravar sem aviso pode ter implicações legais.

  2. Proteja o Graylog: Os logs de sessão contêm informação sensível. Garanta que o acesso ao Graylog é restrito e auditado.

  3. Retenção: Defina por quanto tempo guardar as gravações. Muito tempo ocupa disco e pode criar problemas de compliance. Pouco tempo e você perde evidências.

  4. Input desabilitado por padrão: O tlog não grava o que o usuário digita por padrão (só a saída). Isso é proposital, evita capturar senhas. Pense bem antes de mudar.

  5. Transporte: Os logs estão indo via TCP sem criptografia. Pra ambientes de produção, considere configurar TLS no rsyslog ou usar uma VPN entre os servidores.

Troubleshooting

Sessão não está sendo gravada

Verifique se o shell do usuário é tlog-rec-session:

getent passwd usuario | cut -d: -f7

Se estiver usando SSSD, verifique se o serviço está rodando e a configuração está correta:

sudo systemctl status sssd
sudo sssctl config-check

Logs não chegam no Graylog

Teste a conectividade (TCP):

nc -zv IP_DO_GRAYLOG 1514

Verifique se o rsyslog está encaminhando:

sudo journalctl -u rsyslog -f

E confirme que o firewall permite a saída na porta 1514/TCP.

SELinux bloqueia conexão na porta 1514

Se ao verificar o status do rsyslog você encontrar erros assim:

cannot connect to 192.168.11.86:1514 (took 0.00 seconds): Permission denied

O problema é o SELinux. A porta 1514 não está na lista de portas permitidas para o syslog por padrão. Podemos confirmar verificando quais portas o SELinux reconhece como válidas para syslog:

sudo semanage port -l | grep syslog

A saída mostra algo como:

syslog_tls_port_t              tcp      6514, 10514
syslog_tls_port_t              udp      6514, 10514
syslogd_port_t                 tcp      601, 20514
syslogd_port_t                 udp      514, 601, 20514

A porta 1514 não está na lista. Pra resolver, adicionamos ela ao contexto correto:

sudo semanage port -a -t syslogd_port_t -p tcp 1514
sudo semanage port -a -t syslogd_port_t -p udp 1514

Depois, basta reiniciar o rsyslog:

sudo systemctl restart rsyslog

Agora o erro deve mudar de Permission denied para Connection refused (se o Graylog não estiver escutando) ou simplesmente funcionar.

Não desative o SELinux
A tentação de rodar setenforce 0 é grande, mas resista. O SELinux existe pra proteger o sistema, e desativá-lo remove uma camada importante de segurança. A solução correta é sempre ajustar as políticas, não desativar o mecanismo.

Conclusão

Temos agora um sistema de auditoria de terminal funcionando. Todo comando executado pelos usuários monitorados é gravado, enviado pro servidor central, e fica disponível pra pesquisa e reprodução.

Isso resolve o problema original do rootsh:

  • Logs centralizados: Saem da máquina em tempo real
  • Formato estruturado: JSON pesquisável no Graylog
  • Reprodução fiel: Não precisa mais imaginar o que aconteceu
  • Gerenciamento centralizado: Via SSSD, você controla quem é gravado

A fundação está pronta. No próximo artigo, vamos explorar como usar esses dados pra detectar comportamentos suspeitos e criar alertas automáticos.

Recursos adicionais

Este artigo faz parte de uma série sobre auditoria em ambientes Linux. No próximo, vamos configurar alertas e dashboards avançados para transformar esses dados em inteligência de segurança.

Avatar de DK

Comentários

Comentários fechados para visitantes. Entre ou registre-se para comentar.

Ir para