Com o iptables do Linux, é possível registrar o nome do processo / comando que inicia uma conexão de saída?

27

Gostaria de acompanhar os processos que iniciam as conexões de saída em um desktop Linux. O melhor que posso apresentar é o seguinte:

iptables -A OUTPUT -m state --state NEW -j LOG --log-uid

Isso registra o uid / gid que inicia a conexão, mas não o nome do processo / comando ou mesmo o pid. Se eu pudesse obter o pid, provavelmente poderia criar um script que puxa o nome do processo quando o log é gravado, mas parece que isso nem é possível.

Idealmente, eu também gostaria de registrar os processos que também aceitam conexões de entrada.

Alguma idéia de como isso pode ser possível com o iptables [ou qualquer outra coisa] em uma caixa Linux?

Nack
fonte
Acredito (não tenho certeza) que esta pergunta foi respondida em serverfault, procure-a.
NiXar 18/09/09
Pessoalmente, eu usaria o sysdig para este trabalho.
Charles Duffy

Respostas:

7

Você pode escrever um programa para monitorar / proc / net / tcp, cuja saída se parece com isso:

obi-wan ~ # cat /proc/net/tcp
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
   0: 00000000:0050 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 4847458 1 e6060560 300 0 0 2 -1
   1: 00000000:04D2 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 4847477 1 f2e64da0 300 0 0 2 -1
   2: 00000000:0016 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 7109 1 f2e65ac0 300 0 0 2 -1
   3: 0100007F:177A 00000000:0000 0A 00000000:00000000 00:00000000 00000000  1000        0 4864457 1 d2726540 300 0 0 2 -1
   4: 00000000:01BB 00000000:0000 0A 00000000:00000000 00:00000000 00000000     0        0 4847462 1 e60609c0 300 0 0 2 -1
   5: 6B00A8C0:0016 30F4B5CA:C3AB 01 00000044:00000000 01:00000031 00000000     0        0 4982752 3 f2e64940 55 4 0 2 -1
   6: 0100007F:B143 0100007F:BC5E 01 00000000:00000000 00:00000000 00000000  1000        0 2130283 1 d59cce40 21 4 1 2 -1
   7: 0100007F:BC5E 0100007F:B143 01 00000000:00000000 00:00000000 00000000  1000        0 2130285 1 d59cd2a0 21 4 0 2 -1
   8: 6B00A8C0:0016 3276C35B:8E11 01 00000000:00000000 02:000ADAB1 00000000     0        0 4982629 2 d2727260 40 4 8 2 2
   9: 6B00A8C0:0016 6500A8C0:DD5D 01 00000538:00000000 01:00000029 00000000     0        0 4864416 5 e6061b40 42 12 27 3 -1

Em seguida, você pode relacionar portas abertas a inodes, que podem ser relacionados a processos e descritores de arquivos, fazendo o readlink nos descritores de arquivos listados para cada processo:

obi-wan ~ # readlink /proc/28850/fd/3
socket:[4847458]

Veja aqui que o inode 4847458 corresponde ao primeiro soquete TCP na lista acima. A saída do netstat -tapn verifica isso para mim (e lembre-se de que 0x50 == 80):

obi-wan ~ # netstat -tapn
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN     28850/cherokee-work

Quando o programa do monitor perceber uma alteração em / proc / net / tcp, analise os dados e determine se a alteração é um soquete aberto recentemente. Então você pode apenas enumerar todos os descritores de arquivo para cada processo listado em / proc, fazendo o readlink em cada um deles para encontrar o inode correspondente. Depois de descobrir isso, você tem o pid proprietário, do qual pode obter qualquer outra coisa que desejar, principalmente se tiver contabilidade de processo.

Se você não precisar que sua notificação seja instantânea, o programa do seu monitor poderá usar uma pesquisa lenta (talvez um período de 50ms ou 100ms, ou mesmo 1000ms).

Ben Collins
fonte
2
Obrigado por fornecer uma opção! Mas exigir pesquisa e consulta a cada descritor de arquivo aberto a cada vez não é muito robusto e é ineficiente. Ainda espero que alguém encontre uma solução melhor ou esclareça por que isso não faz mais parte do iptables e por que --cmd-owner é considerado impossível de corrigir.
Nealmcb
A menos que o kernel altere seu layout de / proc ou a menos que netstat e readlink ou ps mudem (improvável), eu diria que isso é bastante robusto. Com que tipo de problemas de eficiência você se preocupa? Se você deseja processamento instantâneo, precisará escrever um módulo do kernel para uso com o iptables.
Ben Collins
Se eu estiver registrando conexões rejeitadas, o soquete será destruído imediatamente pelo kernel, então eu tenho muito pouca chance de vê-lo em / proc. Talvez só mudam o REJEITAR cair para ter o tempo de conexão para fora ...
Marki555
Isso não ajuda nesse cenário, pois a janela de tempo super pequena, mas no que diz respeito à fragilidade da análise / proc, também é possível usar apenas "lsof -F -i" e obter um despejo bem abstrato da rede dados. Isso também pode ser filtrado (digamos, apenas em uma porta específica) e já foi feito todo o mapeamento de nome de arquivo / pid / usuário para você.
22415 Dannysauer
9

Você deseja o módulo de correspondência do proprietário, que funciona apenas na cadeia OUTPUT (e talvez PREROUTING ...?). Leia os documentos, mas funcionará mais ou menos assim:

iptables --append OUTPUT -m owner --cmd-owner "$app" \
--jump LOG --log-level DEBUG --log-prefix "OUTPUT $app packet died: "

fonte
1
Um comando iptables log pode definir e interpolar uma variável dessa maneira? Não parece funcionar para mim. Além disso, parece que a opção --cmd-owner foi removida no kernel> = 2.6.15. Isso é lamentável, porque parece ser uma opção útil.
4
Sim, --cmd-owner foi removido: "quebrado não
corrigível
1
Obrigado pela informação, @ guettli. Há mais detalhes em permalink.gmane.org/…, que citam mais do registro de alterações: "[NETFILTER]: Remova o abuso tasklist_lock no proprietário do ipt {, 6}; Retire a correspondência de cmd / sid / pid, pois está quebrado e não pode ser fixado em a maneira de bloquear muda para tasklist_lock ". Mas ainda gostaria de ter mais informações, ou melhores alternativas.
Nealmcb
5

Nada a ver com iptables ou log; mas aqui está uma interface do tipo "top", que pesquisa o diretório / proc / e exibe largura de banda por programa / pid:

http://sourceforge.net/projects/nethogs

"O NetHogs é uma pequena ferramenta 'net top'. Em vez de quebrar o tráfego por protocolo ou por sub-rede, como a maioria das ferramentas, agrupa a largura de banda por processo. O NetHogs não depende de um módulo de kernel especial para ser carregado."

Lokal
fonte
Descobri que o nethogs fornece estatísticas não confiáveis, mas no topo de 2 (+ netatop) isso funciona bem.
Tobu
1

Como estou procurando uma pergunta semelhante, tentando limitar o skype, descobri

$ netstat -p | grep <mycmdname>

é uma boa maneira de vincular o número da porta ao pid / cmd, agora que o pid-owner / cmd-owner não é mais suportado diretamente no iptables; você precisará analisar o resultado e adicionar a regra iptables de acordo com a porta; naturalmente você precisará de algum código de limpeza posteriormente / no desligamento / reinicialização do sistema, etc; salve o número da porta em um arquivo para referência no momento da limpeza

de fato, uma boa resposta para a questão dos números de porta é

$ sudo netstat -p | grep "tcp.*<mycmdname>" | sed -r "s/.*<MYCOMPUTER>:([0-9]+).*/\1/"`

pode ser necessário ajustar o elemento grep tcp de acordo com suas necessidades

então, para meus propósitos, era mais simples adicionar filtros tc u32 de acordo com os números de porta, entradas do iptables de acordo com números de porta semelhantes

Marca
fonte