Série CSI do Linux
- Parte 01: Montando seu servidor de logs com Graylog
- Parte 02: Gravando sessões de terminal com tlog (você está aqui)
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:

O tlog grava a sessão e manda pro syslog local. O rsyslog pega essas mensagens e encaminha pro Graylog. Robusto 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 43, RHEL 10, 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íficostlog-rec-session: Atua como shell de login, gravando toda a sessão do usuáriotlog-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
syslogpra 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
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.
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:
# Fedora/RHEL (geralmente vai pro journal)
sudo journalctl -t tlog
# RHEL/CentOS (se configurado pra arquivo)
sudo grep tlog /var/log/messages
# Debian/Ubuntu
sudo grep tlog /var/log/syslog
Se aparecerem mensagens JSON gigantes, está funcionando. Cada mensagem contém um pedaço da sessão, timing, output, e metadados.
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, ouall - 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
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.
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
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 (umcatem 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.

Se quiser filtrar só as mensagens do tlog:
application_name:tlog-rec-session
Ou buscar por um usuário específico:
full_message:"TLOG_USER=root"

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 específica. Procure pelo ID da sessão (campo TLOG_REC) e exporte como JSON ou texto.
Depois, localmente:
# Se exportou como texto, precisa extrair só o JSON
grep -o '{.*}' mensagens_exportadas.txt > 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 b5bc59..."
exit 1
fi
SESSION_ID="$1"
TEMP_FILE=$(mktemp)
# Tenta extrair do journal primeiro
if journalctl -o cat TLOG_REC="$SESSION_ID" > "$TEMP_FILE" 2>/dev/null && [ -s "$TEMP_FILE" ]; then
echo "Sessão encontrada no journal. Reproduzindo..."
tlog-play -r file --file-path "$TEMP_FILE"
else
# Tenta do /var/log/messages ou /var/log/secure
for log in /var/log/messages /var/log/secure /var/log/syslog; do
if [ -f "$log" ]; then
grep "$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:
sudo chmod +x /usr/local/bin/extract-session.sh
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 robusta, considere usar jq — ele lida melhor com edge cases e 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 TLOG_REC. No Graylog, você pode criar um extractor pra facilitar a busca.
Vá em System > Inputs > clique no seu input Syslog > Manage extractors > Add extractor
Configure um extractor do tipo Regular expression com:
- Regular expression:
"rec":"([a-f0-9-]+)" - Target field:
tlog_session_id
Agora você pode buscar sessões específicas com:
tlog_session_id:b5bc59a1-xxxx-xxxx-xxxx-xxxxxxxxxxxx
Dashboard de auditoria
Vale a pena criar um dashboard no Graylog pra ter visibilidade das sessões. Algumas visualizações úteis:
- Sessões por usuário: Agregação por
TLOG_USER - Sessões por host: Agregação por
source - Timeline de atividade: Histograma de mensagens tlog ao longo do tempo
- Usuários mais ativos: Top 10 por quantidade de sessões
Isso 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:
-
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.
-
Proteja o Graylog: Os logs de sessão contêm informação sensível. Garanta que o acesso ao Graylog é restrito e auditado.
-
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.
-
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.
-
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.
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
- Documentação oficial do tlog no GitHub
- Red Hat – Recording Sessions
- Guia do Graylog para Syslog Linux
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.





Deixe um comentário