Como posso encontrar o número total de conexões TCP para uma determinada porta e período de tempo por IP?

5

Em um sistema Linux, existem vários métodos para listar as conexões TCP atuais para uma determinada porta, conectando o IP, mas: como posso contar o número total de conexões para uma porta por IP de origem por período de tempo?

    
por Dave Forgac 11.03.2014 / 18:46

6 respostas

13

Ative o iptables e defina-o como LOG para conexões de entrada. Exemplo de regra:

 -A INPUT --state NEW -p tcp --dport 4711 -j LOG

(onde 4711 é a porta que você deseja rastrear).

Em seguida, execute o log resultante através de qualquer script que você goste que possa fazer o resumo para você.

    
por 14.03.2014 / 15:39
7

Você pode usar o tcpdump para registrar todos os pacotes SYN (sem ACK):

tcpdump "dst port 4711 and tcp[tcpflags] & (tcp-syn|tcp-ack) == tcp-syn"

ou registre todos os pacotes SYN + ACK (conexões estabelecidas):

tcpdump "src port 4711 and tcp[tcpflags] & (tcp-syn|tcp-ack) == (tcp-syn|tcp-ack)"

Em seguida, combine-o com um wc -l para contar todas as linhas

Você também precisaria de uma maneira de medir períodos de tempo fixos (você poderia ter um cron apenas enviando um SIGINT em intervalos regulares, o tcpdump contaria bytes e pacotes, mas somente o tempo de logs)

Atualização: não é necessário dizer, dê uma olhada na página man do tcpdump e considere usar algumas opções como: -i (ouça somente uma interface), -p (desabilite o modo promíscuo; menos invasivo), ou algumas opções de saída. O Tcpdump precisa de permissões de root e seu chefe pode não gostar dele porque é uma espécie de ferramenta hacker. Por outro lado, você não precisa tocar em nada no seu sistema para executá-lo (em contraste com a iptables LOG solution)

Por favor, também observe a pequena diferença src / dsk no filtro. Se você pegar pacotes SYN + ACK e quiser contar as conexões para um servidor na porta 4711, você precisa de src. Se você está pegando pacotes SYN +! ACK para o mesmo resultado, você precisa de dst. Se você contar conexões no próprio servidor, você sempre terá que usar o contrário.

    
por 15.03.2014 / 02:17
3

Solução SystemTap

Script inspirado no exemplo tcp_connections.stp :

#!/usr/bin/env stap
# To monitor another TCP port run:
#     stap -G port=80 tcp_connections.stp
# or
#     ./tcp_connections.stp -G port=80
global port = 22
global connections

function report() {
  foreach (addr in connections) {
    printf("%s: %d\n", addr, @count(connections[addr]))
  }
}

probe end {
  printf("\n=== Summary ===\n")
  report()
}

probe kernel.function("tcp_accept").return?,
      kernel.function("inet_csk_accept").return? {
  sock = $return
  if (sock != 0) {
    local_port = inet_get_local_port(sock)
    if (local_port == port) {
      remote_addr = inet_get_ip_source(sock)
      connections[remote_addr] <<< 1
      printf("%s New connection from %s\n", ctime(gettimeofday_s()), remote_addr)
    }
  }
}

Saída:

[root@bubu ~]# ./tcp_connections.stp -G port=80
Mon Mar 17 04:13:03 2014 New connection from 192.168.122.1
Mon Mar 17 04:13:04 2014 New connection from 192.168.122.1
Mon Mar 17 04:13:08 2014 New connection from 192.168.122.4
^C
=== Summary ===
192.168.122.1: 2
192.168.122.4: 1

solução de strace

Inicie o programa sob strace:

strace -r -f -e trace=accept -o /tmp/strace ${PROGRAM} ${ARGS}

ou rastreie um programa já em execução:

strace -r -f -e trace=accept -o /tmp/strace -p ${PID_OF_PROGRAM}

-r imprime um registro de data e hora relativo na entrada de cada chamada do sistema, caso seja necessário posteriormente para uma análise de desempenho extra. -f rastreia processos filhos e pode não ser necessário.

A saída é algo como isto:

999        0.000000 accept(3, {sa_family=AF_INET, sin_port=htons(34702), sin_addr=inet_addr("192.168.122.4")}, [16]) = 5
999        0.008079 --- SIGCHLD (Child exited) @ 0 (0) ---
999        1.029846 accept(3, {sa_family=AF_INET, sin_port=htons(34703), sin_addr=inet_addr("192.168.122.4")}, [16]) = 5
999        0.008276 --- SIGCHLD (Child exited) @ 0 (0) ---
999        3.580122 accept(3, {sa_family=AF_INET, sin_port=htons(50114), sin_addr=inet_addr("192.168.122.1")}, [16]) = 5

e pode ser filtrado com:

# gawk 'match($0, /^([0-9]+)[[:space:]]+([0-9.]+)[[:space:]]+accept\(.*htons\(([^)]+)\),.*inet_addr\("([^"]+)"\).*[[:space:]]+=[[:space:]]+([1-9][0-9]*)/, m) {connections[m[4]]++} END {for (addr in connections) printf("%s: %d\n", addr, connections[addr]); }' /tmp/strace
192.168.122.4: 3
192.168.122.1: 2

Uma breve explicação do one-liner do AKW: m[1] é o PID, m[2] é o timestamp, m[3] é a porta remota e m[4] é o endereço remoto.

A vantagem desta solução é que a raiz não é necessária se o servidor for executado sob o mesmo usuário. A desvantagem é que todas as conexões são contadas, não há filtragem, então não funcionará se o aplicativo ouvir em várias portas.

    
por 17.03.2014 / 04:57
2

O seu sistema não se lembrará das contagens de conexões anteriores, a menos que você o informe, portanto, não espere encontrar contadores como o seu tráfego total por meio de uma interface, a menos que você configure algo para fazer essa contagem.

Além disso, em geral, você não pode fazer essa contagem de forma confiável, como Jacek Lakomiec sugeriu, já que algumas conexões serão iniciadas e terminadas mais rapidamente que o seu período de pesquisa. Esse tipo de abordagem pode ser aceitável para algumas situações em que você tem certeza de que as conexões de tempo são feitas por tempo suficiente, mas não consigo pensar em boas razões para preferir isso.

Como sugerido por Jenny D e Daniel Alder, suas opções para contar as conexões conforme ocorrem são basicamente contadores baseados em firewall e contadores baseados em captura de pacotes. Ambos geralmente funcionam bem, embora se o seu sistema for restrito pelo processador, você pode falhar em contar algumas conexões se usar a abordagem baseada em pacotes, e também é provável que consuma mais recursos do sistema para fazer a contagem. Por outro lado, as abordagens baseadas em captura de pacotes podem ser mais simples e seguras de configurar para investigações ad-hoc.

Existe outra classe geral de solução, que é netflow. Está mais envolvida em configurar, mas se for bem feito, é particularmente eficiente, e se você estiver fazendo um monitoramento em grande escala ou em andamento, eu olharei nessa direção. Capturar os dados brutos pode ser feito no seu firewall (por exemplo, fprobe-ulo) ou usando o libpcap que é mais lento (por exemplo, fprobeg). O sistema de captura envia dados de fluxo através da rede para um coletor (por exemplo, nfdump), e você tem uma variedade de ferramentas para analisar esses dados (por exemplo, nfsen).

Alguns roteadores (especialmente cisco gear) vêm com captura netflow, e também podem ser configurados em outros roteadores através de firmware de terceiros, ou é claro, você pode executá-lo em seu sistema linux. Se desejar, muitos pontos de coleta podem encaminhar seus dados de fluxo para um único coletor. Você pode encontrar opções de software livre, por exemplo, no link , e há também muitas ofertas comerciais.

O Netflow foi projetado para uso em escala industrial, mas achei muito útil a coleta de dados sobre o uso de minha rede doméstica em uma divisão para que eu possa identificar quem ou o que é responsável quando o uso do tráfego é maior que o esperado .

Tenha cuidado sempre que estiver mexendo com regras de firewall em um servidor remoto e, em geral, recomendo encontrar um bom front-end para configurar seu firewall, em vez de emitir comandos iptables diretamente. (Eu gosto de ferm, mas existem muitos bons).

Uma outra coisa para pensar - às vezes você não quer fazer isso na camada de rede. Às vezes, é apropriado monitorar as chamadas do sistema do processo do daemon com strace ou similar. É intensivo da CPU e tome cuidado com a lentidão do processo Daemon, mas em algumas circunstâncias, pode ser apropriado, dependendo principalmente de quais outras informações você precisa reunir ao mesmo tempo, ou talvez se você precisar isolar uma única criança bifurcada do daemon.

    
por 17.03.2014 / 06:37
1

Até agora, a solução que funcionou melhor para mim foi pegar o conteúdo de / proc / net / ip_conntrack a cada 20 segundos, registrá-lo em um arquivo com nome de arquivo contendo o timestamp apropriado e usá-los como entrada para qualquer filtro scripts, ou mesmo oneliners quando necessário. Para economizar seu tempo, você pode usar meu script. Eu uso entradas crontab para garantir que o script seja executado a cada minuto (ele dura 60 segundos na configuração atual, sinta-se à vontade para modificá-lo :-)

 cat conn_minute.sh
#!/bin/bash

function save_log {
LOG_DIR=/mnt/logs/ip_conntrack/'date +%Y%m%d'
TEMP_FILE=$LOG_DIR/'date +%Y%m%d_%H%M%S'.gz
LOG_FILE=$LOG_DIR/'date +%Y%m%d_%H'.tar
if [ ! -d $LOG_DIR ]
then
    mkdir $LOG_DIR
fi
gzip -c /proc/net/ip_conntrack > $TEMP_FILE
if [ -f $LOG_FILE ]; then
    tar -rf $LOG_FILE $TEMP_FILE 2> /dev/null
else
    tar -cf $LOG_FILE $TEMP_FILE 2> /dev/null
fi
rm $TEMP_FILE
}
function log_minute {
i=1;
LOOP_COUNTER=3
LOOP_TIME=20
while [ $i -le $LOOP_COUNTER ]; do
    save_log
    i=$[i+1]
    sleep $LOOP_TIME
done
}

log_minute

Você pode ajustar com que frequência quer despejar o conteúdo de ip_conntrack alterando LOOP_COUNTER e LOOP_TIME de acordo. Então, para obtê-lo a cada 5 segundos, seria: LOOP_COUNTER = 12, LOOP_TIME = 5. LOG_DIR é implicado onde os logs seriam salvos em.

Depois, você pode usar os arquivos zcat para cat de seu interesse e usar o grep para filtrar IPs / portas de origem de seu interesse (ou apenas usar zgrep). grep -c contará o que você quiser. Você também pode usar grep src=1.2.3.4 | grep dport=63793 | sort | uniq | wc -l .

    
por 16.03.2014 / 02:07
-2

Dê uma olhada em

Eles são todos um pouco obsoletos, mas escrever scripts para fazer o trabalho que os outros fizeram melhor é entediante. Alguns lhe dão fotos bonitas, alguns se especializam mais em análises forenses e estragam os Bad Guys, alguns (iplog) são apenas simples contadores que registram em DBs, alguns têm frontends brilhantes que você pode mostrar ao seu chefe.

Há também um monte de ferramentas para implementar uma pilha compatível com netflow no linux. E um monte de gente tentando vender apoio em torno disso. (Não vou recomendar um produto comercial ...) O que você está pedindo é muito mais simples do que algumas delas são capazes.

IMHO (Free | Net | Open) O BSD está muito à frente do tipo de análise há anos. Um firewall pFsense lhe daria pelo menos 7 opções prontas para uso.

    
por 15.03.2014 / 03:45