Localizando o processo do proprietário das conexões TCP de curta duração

15

Executando tcpdumpem conexões locais com um servidor apache, encontrei conexões TCP sendo estabelecidas e fechadas imediatamente a cada 2 segundos. Como encontro qual processo é responsável por eles? netstat -ctpnão ajudou, as conexões foram muito rápidas e o identificador do processo não é exibido para as TIME_WAIT.

Acabaram sendo sondas de haproxy, com as quais pude verificar strace, mas ainda não sei como identificar haproxy em primeiro lugar.

pmezard
fonte

Respostas:

20

Você pode usar a estrutura auditd para esse tipo de coisa. Eles não são muito "amigáveis" ou intuitivos, por isso requer um pouco de pesquisa da sua parte.

Primeiro, verifique se o auditd está instalado, em execução e se o seu kernel suporta.
Para o Ubuntu, você pode instalá-lo, apt-get install auditdpor exemplo.

Em seguida, adicione uma política de auditoria para monitorar todos os connectsyscalls como este:

auditctl -a exit,always -F arch=b64 -S connect -k MYCONNECT

Se você estiver usando uma instalação de 32 bits do Linux, precisará alterar b64 para b32.

Este comando irá inserir uma política na estrutura de auditoria, e qualquer syscalls connect () agora será registrado nos seus arquivos de log de auditoria (geralmente /var/log/audit/audit.log) para você examinar.

Por exemplo, uma conexão com o netcat à porta 80 news.ycombinator.com resultará em algo assim:

type=SYSCALL msg=audit(1326872512.453:12752): arch=c000003e syscall=42 success=no exit=-115 a0=3 a1=24e8fa0 a2=10 a3=7fff07a44cd0 items=0 ppid=5675 pid=7270 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts4 ses=4294967295 comm="nc" exe="/bin/nc.openbsd" key="MYCONNECT"
type=SOCKADDR msg=audit(1326872512.453:12752): saddr=02000050AE84E16A0000000000000000

Aqui você pode ver que o aplicativo /bin/nc.openbsd iniciou uma chamada connect (), se você receber muitas chamadas de conexão e desejar apenas receber um determinado ip ou porta, precisará fazer alguma conversão. A linha SOCKADDR contém um argumento saddr, começa com 0200, seguido pelo número da porta em hexadecimal (0050), o que significa 80, e o IP em hexadecimal (AE84E16A), que é o IP 174.132.225.106 do news.ycombinator.com.

A estrutura de auditoria pode gerar muitos logs; lembre-se de desativá-la quando concluir sua missão. Para desabilitar a política acima, basta substituir -a por -d, como tal:

auditctl -d exit,always -F arch=b64 -S connect -k MYCONNECT

Boa documentação sobre a estrutura auditd:
http://doc.opensuse.org/products/draft/SLES/SLES-security_sd_draft/part.audit.html

Converta endereços IP de / para hex, dec, binário, etc em:
http://www.kloth.net/services/iplocate.php

Conversor hex / dec geral:
http://www.statman.info/conversions/hexadecimal.html

Uma breve introdução ao auditd, do IT Security Stack Exchange. http://security.blogoverflow.com/2013/01/a-brief-introduction-to-auditd/

Edit 1 :
Outra maneira rápida (sueca: fulhack) de fazer isso é criar um loop rápido que despeja os dados de conexão para você, assim:

while true;do
  ss -ntap -o state established '( dport = :80 )'
  sleep 1
done

Este comando usa o sscomando (estatísticas do soquete) para despejar as conexões estabelecidas atualmente na porta 80, incluindo o processo que o iniciou. Se houver muitos dados, você pode adicionar | tee /tmp/outputdepois de feito, para mostrar a saída na tela e também gravá-la em / tmp / output para processamento / escavação posterior. Se ele não capturar a conexão rápida haproxy, tente remover, sleep 1mas tenha cuidado com o registro extensivo, se for uma máquina muito utilizada. Modifique conforme necessário!

Mattias Ahnberg
fonte
Obrigado pela resposta detalhada. Aceitarei sua palavra para a solução auditd, pois o kernel host não a suporta e não tenho tempo agora para encontrar uma adequada para experimentação, mas vou manter isso em mente. Quanto à solução de votação, comecei a fazer algo semelhante com lsof, mas parei rapidamente, pois não era ... satisfatório.
Pmezard 22/01/12
2
Você também pode usar ausearch -iessas saddrdecodificações automáticas para o seu.
SCH
ss é mais satisfatório que lsof porque é mais rápido e possui boas regras de filtragem - não é necessário grep. Posso apreciar os problemas com o suporte: O Systemtap é outra ferramenta excelente, mas executá-lo em um servidor de produção pode ser ... não satisfatório.
Max Murphy
1

Você também pode receber os enormes logs obtidos em "ausearch -i" para ver apenas os soquetes que foram conectados com sucesso a outro host na Internet. Eu escrevi um script simplista para obter cada processo e comando que criou um soquete para conectar-se a um host na Internet, juntamente com o endereço de conexão desse host de destino e a hora atual em que o soquete foi "criado". Aqui está:

#!/bin/bash

if [[ $EUID -ne 0 ]]; then

    echo "You must run this script as root boy!"
    exit 1  

fi

> proccessConnections.dat

connections=`ausearch -i | grep host: | awk -F "msg=audit" '{print $2}' | awk -F ": saddr" '{print $1}'`

connectionsNumber=`echo "$connections" | wc -l`

echo "Number of connections: $connectionsNumber"

echo "$connections" > conTemp.dat

let counter=1
while read connectInfo; do

    success=`ausearch -i | grep "$connectInfo" | grep "type=SYSCALL" | grep success=yes`    
    addressInfo=`ausearch -i | grep "$connectInfo" | grep type=SOCKADDR | awk -F ': ' '{print $2}'`
    processInfo=`ausearch -i | grep "$connectInfo" | grep "type=SYSCALL" | awk -F 'comm=' '{print $2}' | awk -F 'key' '{print $1}'` 

    if [[ $success != "" ]]
    then    
        echo "[$counter - $connectionsNumber] (success)     comm=$processInfo - $addressInfo - $connectInfo"
        echo "[$counter - $connectionsNumber] (success)     comm=$processInfo - $addressInfo - $connectInfo" >> proccessConnections.dat
    else
        echo "[$counter - $connectionsNumber] (no success)  comm=$processInfo - $addressInfo - $connectInfo"
        echo "[$counter - $connectionsNumber] (no success)  comm=$processInfo - $addressInfo - $connectInfo" >> proccessConnections.dat
    fi

    let counter++


done < conTemp.dat
Marcelo Silva
fonte