Há três mistérios que aparecem semana sim, semana não a quem administra sistemas Linux: um serviço que não arranca porque «o porto já está ocupado», um disco que o df jura estar cheio mas cujos ficheiros o du não encontra, e a dúvida sobre que processo está a segurar um determinado ficheiro. Os três têm a mesma resposta: lsof. O nome vem de list open files — e, como em Linux quase tudo é um ficheiro (diretórios, dispositivos, sockets, pipes), o lsof é na prática uma radiografia completa do que cada processo tem entre mãos.
A seguir percorremos as opções que realmente se usam e os cenários de segurança em que o lsof brilha — com um simulador interativo para praticar sem sair da página.
O que faz o lsof
O lsof lista os descritores de ficheiro abertos de todos os processos: o binário em execução, o diretório de trabalho, as bibliotecas, os logs abertos para escrita e os sockets de rede. A informação vem do que o kernel expõe em /proc/PID/fd, organizada numa tabela com o comando, o PID, o utilizador, o tipo e o nome de cada recurso.
lsof [opções] [nomes de ficheiros]
Duas regras poupam surpresas. Primeira: sem argumentos, o lsof lista tudo — milhares de linhas num servidor real, por isso o dia a dia é feito de filtros. Segunda: vários critérios de seleção juntam-se com OU por omissão; para obter a interseção é preciso -a. E ver processos de outros utilizadores exige root: sem privilégios, a ausência de resultados não prova a ausência de processos.
As opções que interessam
Escolher o alvo
lsof /caminho/ficheiro— mostra os processos que têm esse ficheiro aberto. É o primeiro comando antes de desmontar um sistema de ficheiros «ocupado» ou de mexer num log em uso.-p PID— tudo o que um processo tem aberto: binário, bibliotecas, logs, sockets. Um raio-X completo; aceita listas separadas por vírgulas.-u UTILIZADOR— os ficheiros abertos pelos processos de um utilizador. O prefixo^nega:-u ^rootexclui o root.-c NOME— filtra pelo início do nome do comando:-c sshapanhasshesshd.+D /diretório— desce o diretório recursivamente e mostra tudo o que está aberto lá dentro. Muito útil em/var/log; pode ser lento em árvores grandes.
lsof /var/log/syslog
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
rsyslogd 702 root 5w REG 8,1 1834022 262401 /var/log/syslog
Na coluna FD, cwd é o diretório de trabalho, txt o próprio executável, e os números são descritores seguidos do modo de acesso — r leitura, w escrita, u ambos. A coluna NODE é o inode.
Rede: a opção -i
-i— restringe a sockets de rede: quem escuta em que porto e quem está ligado a quem.-i :8080— sockets que envolvem um porto concreto, à escuta ou ligados. Aceita variantes como-i tcp:443,-i @192.0.2.7(por endereço) e-i 4/-i 6(família IP).-ne-P— desligam a resolução de endereços e a tradução de portos em nomes de serviço. Além de acelerar, evitam consultas DNS; em investigação,-nPdeve ser reflexo.-t— devolve apenas os PID, um por linha, pronto a encaixar em scripts.
# Quem tem o porto 8080?
lsof -nP -i :8080
# Libertar o porto (depois de perceber quem o ocupa e porquê)
kill $(lsof -t -i :8080)
Combinar critérios com -a
Um exemplo torna a diferença óbvia: lsof -u www-data -i devolve os ficheiros do www-data mais todos os sockets do sistema (OU). Já lsof -a -u www-data -i devolve apenas os sockets abertos por processos do www-data (E) — exatamente a pergunta que se faz quando se suspeita de uma conta de serviço comprometida.
Ficheiros apagados mas abertos: +L1
Quando se apaga um ficheiro que um processo mantém aberto, o nome desaparece do diretório mas os blocos continuam ocupados até o último descritor fechar. É por isso que o rm de um log gigante às vezes «não liberta espaço»: o df continua a mostrar o disco cheio e o du, que só vê nomes, não encontra a diferença. O lsof marca estes casos com (deleted), e a opção +L1 — ficheiros com contagem de ligações inferior a um — lista-os todos de uma vez:
lsof +L1
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NLINK NODE NAME
java 2330 aluno 6w REG 8,1 2147483648 0 262601 /var/log/app/app.log.1 (deleted)
A solução limpa é reiniciar ou recarregar o serviço que segura o ficheiro; em alternativa, pode truncar-se o conteúdo através do descritor exposto em /proc/PID/fd, sem parar o processo.
lsof em cibersegurança
Sockets inesperados. Uma conta de serviço como o www-data deve abrir sockets muito previsíveis. O comando lsof -a -u www-data -i -nP mostra a interseção exata — e uma ligação estabelecida para um endereço externo num porto invulgar, mantida por um processo que não é o servidor web, é a assinatura típica de uma reverse shell lançada a partir de uma aplicação comprometida.
Binários apagados em execução. Uma técnica clássica de malware é executar o binário e apagá-lo de seguida: o disco fica «limpo» para os antivírus, mas o processo continua vivo. No lsof, o executável aparece como txt ... (deleted) — e lsof +L1 encontra-o em segundos. Para recuperar o binário para análise, o atalho /proc/PID/exe continua a apontar para ele mesmo depois de apagado.
Resposta a incidentes. Perante um PID suspeito, lsof -p PID responde de uma vez às perguntas essenciais: que binário está a correr, que ficheiros está a ler e a escrever, e com quem está a falar na rede. Cruzando o inode da coluna NODE com o ss -e e com o /proc, reconstrói-se a cadeia completa processo–ficheiro–ligação antes de conter a ameaça.
Disco cheio como sintoma. Um disco que enche depressa nem sempre é inocente: pode ser um log a explodir com um ataque de força bruta em curso, ou a área de preparação de uma exfiltração. O par +D e +L1 localiza o que cresce e quem o escreve.
Experimente no simulador interativo
A simulação abaixo recria uma máquina com 21 descritores abertos — serviços legítimos, um log apagado de 2 GB e um processo suspeito com o binário removido. No painel esquerdo vê tudo o que existe no kernel; no terminal, o que sobrevive aos filtros. Clique nas opções (-p, -u, -i, +D, +L1, -a…) para compor o seu próprio comando, use Demonstrar tudo para a sequência guiada completa — que resolve o mistério do porto 8080 e o do disco que não esvazia — ou navegue passo a passo com Anterior e Seguinte. A nota por baixo dos botões explica cada opção.
Erros comuns e boas práticas
- Esquecer que os critérios se juntam com OU:
lsof -u alice -inão mostra «os sockets da alice» — mostra os ficheiros da alice mais todos os sockets. Habitue-se ao-a. - Correr sem root e confiar no vazio: sem privilégios só vê os seus próprios processos; conclusões sobre a máquina inteira exigem
sudo. - Matar às cegas com
kill $(lsof -t ...): primeiro perceber que processo é e porque está ali; num incidente, terminar o processo pode destruir evidência valiosa. - Ignorar o
-nP: a resolução de nomes atrasa o resultado e gera tráfego DNS — que numa investigação pode avisar o adversário. - Usar
+Dna raiz de árvores enormes: é recursivo e pesado; aponte-o ao diretório mais específico possível. - Apagar logs gigantes e esperar espaço imediato: se o serviço os mantém abertos, o espaço só volta quando o descritor fechar — verifique com
+L1antes de reiniciar seja o que for.
Conclusão
O lsof é a ponte entre três mundos que costumam ser investigados em separado: processos, ficheiros e rede. Meia dúzia de combinações — lsof -nP -i :porto para portos ocupados, lsof -a -u utilizador -i para sockets suspeitos, lsof +L1 para espaço fantasma e binários apagados — resolvem em segundos problemas que de outra forma consomem horas. Se está a construir a sua caixa de ferramentas de administração, veja também o nosso artigo sobre o useradd.
Quer levar estas competências mais longe, ou precisa de apoio especializado em segurança e administração de sistemas? Conheça os serviços de formação e consultoria da HJFR no nosso catálogo de serviços — desenhamos percursos práticos para equipas técnicas e programas à medida para empresas.
Este artigo faz parte da série «Comandos Linux, um a um» do blog HJFR — fique atento aos próximos comandos.
