Há um momento em que qualquer administrador de sistemas ou analista de segurança se encontra sozinho com um ficheiro de log de milhares de linhas e uma pergunta urgente: quem está a fazer isto ao meu servidor? Não é preciso uma plataforma de análise, nem sequer sair do terminal. Com meia dúzia de utilitários minúsculos — cut, sort, uniq, wc, tr — ligados por pipes, o log em bruto transforma-se numa resposta em segundos.
Este artigo explica como funciona o operador |, percorre as opções que realmente interessam em cada um destes comandos e mostra o pipeline clássico da resposta a incidentes: o «top de IPs» de um access log. No fim, há um simulador interativo onde pode montar o funil, estágio a estágio, e ver o output intermédio de cada fase.
O que faz um pipeline
O pipe (|) liga a saída padrão de um comando à entrada padrão do seguinte. Cada programa faz uma única coisa bem feita — extrair um campo, ordenar, remover duplicados, contar — e o pipe encadeia-os num funil onde os dados fluem da esquerda para a direita. É a filosofia Unix em ação: em vez de uma ferramenta gigante que faz tudo, várias ferramentas pequenas que se combinam.
comando1 [ficheiro] | comando2 | comando3 > resultado.txt
O primeiro comando lê de um ficheiro (ou do teclado); os seguintes recebem sempre o que o anterior produziu. Um detalhe importante: alguns utilitários, como o tr, não aceitam ficheiros como argumento — leem apenas da entrada padrão, pelo que se usa o redirecionamento tr -s ' ' < ficheiro ou um comando antes deles no pipeline.
As opções que interessam
cut — extrair campos
O cut corta cada linha em campos e devolve só os que interessam. As duas opções essenciais andam sempre juntas: -d define o separador (por omissão é a tabulação) e -f escolhe os campos.
-d' ' -f1— separa pelo espaço e fica com o primeiro campo. Num access log, é o IP do cliente.-f1,3e-f2-4— aceita listas e intervalos de campos.-c 1-15— corta por posição de carácter em vez de campo.--complement— inverte a seleção: devolve tudo menos os campos indicados.-s— suprime as linhas que não contêm o separador (por omissão passam inteiras).
Uma armadilha clássica: o cut trata cada separador como uma fronteira de campo. Dois espaços seguidos criam um campo vazio e desviam todos os seguintes. Para dados irregulares, normalize primeiro com tr -s ' ' ou prefira awk, que trata sequências de espaços como um único separador.
sort — ordenar (e porquê antes do uniq)
sort— ordena as linhas como texto. É o passo obrigatório antes douniq, porque este só agrega linhas repetidas consecutivas.-n— compara como números. Sem ele,10vem antes de9, porque «1» é menor do que «9» como carácter.-r— inverte a ordem;-rné o remate clássico de qualquer contagem (do mais frequente para o menos).-k Ne-t SEP— ordenam por uma coluna específica com um separador à escolha.-u— remove duplicados ao ordenar, um atalho parasort | uniq.-h— ordena tamanhos «humanos» como2K,15Mou1G.
uniq — agregar e contar
uniq— remove linhas duplicadas consecutivas.-c— prefixa cada linha com o número de ocorrências. É a base de qualquer contagem em shell.-d/-u— mostram só as linhas repetidas, ou só as que ocorrem uma única vez.-i— ignora maiúsculas e minúsculas na comparação.
wc, tr e head — rematar o funil
wc -l— conta linhas;-wconta palavras e-cconta bytes. No fim de um pipeline, transforma uma lista numa métrica.tr -s ' '— comprime sequências de espaços num só;tr -d '\r'apaga os retornos de carro do Windows;tr 'A-Z' 'a-z'normaliza para minúsculas.head -5— fica com as cinco primeiras linhas;tailfaz o mesmo com as últimas.
Pipelines em cibersegurança
O top de IPs de um access log. É o pipeline mais famoso da resposta a incidentes. Extrai o IP de cada pedido, ordena para juntar os iguais, conta, reordena pelas contagens e fica com o topo:
cut -d' ' -f1 access.log | sort | uniq -c | sort -rn | head -5
10 203.0.113.66
4 198.51.100.23
3 192.0.2.14
2 198.51.100.7
2 192.0.2.55
Um IP com dez vezes mais pedidos do que os restantes, num intervalo curto, é a assinatura típica de um scan, de scraping agressivo ou do início de um ataque de negação de serviço. A mesma receita, trocando o campo, responde a outras perguntas: com o campo do código HTTP conta-se quantos 404 (enumeração de ficheiros) e 401 (força bruta em páginas de autenticação) o servidor devolveu; num log de autenticação, extrai-se o utilizador ou a origem das tentativas falhadas.
Triagem sem SIEM. Nem todos os incidentes acontecem onde há um SIEM a indexar tudo. Num servidor isolado, numa máquina virtual esquecida ou num sistema comprometido em que só há acesso por consola, estes cinco utilitários existem sempre — fazem parte de qualquer instalação mínima. Saber montá-los de cor é a diferença entre responder em minutos ou esperar por ferramentas.
Medir a dimensão do problema. Antes de decidir bloquear, convém quantificar: wc -l diz quantos pedidos houve no total, e cut ... | sort -u | wc -l diz quantas origens distintas. Se 80% do tráfego vem de meia dúzia de endereços, um bloqueio cirúrgico na firewall resolve; se vem de milhares, o cenário é outro — provavelmente uma botnet — e a resposta também.
Experimente no simulador interativo
A simulação abaixo mostra um access log fictício à esquerda e um terminal à direita. Cada chip acrescenta um estágio ao pipeline — pela ordem em que clicar — e a faixa de fases mostra quantas linhas saem de cada estágio; clique numa fase para ver o output intermédio que o comando seguinte recebe. O botão Demonstrar tudo percorre uma investigação guiada, do log em bruto ao top de IPs, e os botões Anterior/Seguinte permitem avançar ao seu ritmo.
Erros comuns e boas práticas
- Usar
uniqsemsortantes. Ouniqsó agrega repetidos consecutivos; sem ordenar primeiro, as contagens saem fragmentadas e erradas. - Esquecer o
-nnosort. Ordenar números como texto põe964depois de8123. Contagens, bytes e tamanhos pedem sempresort -n(ou-hpara unidades humanas). - Confiar cegamente nos separadores. Uma linha com dois espaços seguidos desvia os campos do
cut. Normalize comtr -s ' 'ou valide o resultado antes de tirar conclusões — dados reais são sujos. - O
catinútil.cat ficheiro | cut ...funciona, mas ocut(tal comosort,uniq,headewc) aceita o ficheiro diretamente como argumento — um processo a menos. - Ignorar a localização (locale). A ordem do
sortdepende da locale; em scripts e análises reprodutíveis, useLC_ALL=C sort— além de previsível, é bastante mais rápido em ficheiros grandes. - Concluir sem quantificar. Um
head -5mostra o topo, mas convém sempre juntar o total (wc -l) para perceber o peso real desses primeiros lugares.
Conclusão
O poder desta família de comandos não está em nenhum deles individualmente — está no pipe que os liga. cut extrai, sort ordena, uniq -c conta, sort -rn hierarquiza e head remata: cinco estágios que transformam qualquer log num relatório instantâneo, em qualquer máquina Linux, sem instalar nada. Se quer levar estas competências mais longe — da linha de comandos à análise de incidentes e ao hardening de servidores — conheça os serviços de formação e consultoria da HJFR no nosso catálogo de serviços, e reveja também o artigo sobre o useradd desta mesma série.
Este artigo faz parte da série “Comandos Linux, um a um” do blog HJFR — fique atento aos próximos comandos.
