Comando lsof: ficheiros e portos abertos no Linux

Terminal Linux a mostrar o resultado do comando lsof com processos, ficheiros e sockets abertos

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 ^root exclui o root.
  • -c NOME — filtra pelo início do nome do comando: -c ssh apanha ssh e sshd.
  • +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).
  • -n e -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, -nP deve 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 -i nã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 +D na 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 +L1 antes 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.