GNU/Linux >> Linux Esercitazione >  >> Linux

Come posso trovare il numero totale di connessioni TCP per una determinata porta e periodo di tempo per IP?

Attiva iptables e impostalo su LOG per le connessioni in entrata. Esempio di regola:

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

(dove 4711 è la porta che vuoi tracciare).

Quindi esegui il registro risultante attraverso qualsiasi script che ti piace che possa fare il riepilogo per te.


Puoi utilizzare tcpdump per registrare tutti i pacchetti SYN (senza ACK):

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

o registrare tutti i pacchetti SYN+ACK (connessioni stabilite):

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

E poi combinalo con un wc -l per contare tutte le righe

Avresti anche bisogno di un modo per misurare periodi di tempo fissi (potresti fare in modo che un cron gli invii semplicemente un SIGINT a intervalli regolari, tcpdump conterà byte e pacchetti ma registrerà solo il tempo)

Aggiornamento:non è necessario dirlo, dai un'occhiata alla pagina man di tcpdump e considera l'utilizzo di alcune opzioni come:-i (ascolta solo un'interfaccia), -p (disattiva la modalità promiscua; meno invasiva) o alcune opzioni di output. Tcpdump ha bisogno dei permessi di root e al tuo capo potrebbe non piacere perché è una specie di strumento per hacker. D'altra parte, non hai bisogno di toccare nulla sul tuo sistema per eseguirlo (a differenza del iptables LOG soluzione)

Si prega di notare anche la piccola differenza src/dsk nel filtro. Se catturi pacchetti SYN+ACK e vuoi contare le connessioni a un server alla porta 4711 è necessario src. Se stai intercettando pacchetti SYN+!ACK per lo stesso risultato, hai bisogno di dst. Se conti le connessioni sul server stesso, devi sempre usare il contrario.


Soluzione SystemTap

Script ispirato all'esempio 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)
    }
  }
}

Uscita:

[[email protected] ~]# ./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

soluzione strace

Avviare il programma sotto strace:

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

o rintracciare un programma già in esecuzione:

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

-r stampa un timestamp relativo all'ingresso di ogni chiamata di sistema nel caso in cui sia necessario in seguito per un'analisi delle prestazioni extra. -f traccia i processi figlio e potrebbe non essere necessario.

L'output è simile a questo:

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 può essere filtrato con:

# 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

Breve spiegazione della battuta AKW:m[1] è il PID, m[2] è il timestamp, m[3] è la porta remota e m[4] è l'indirizzo remoto.

Il vantaggio di questa soluzione è che root non è richiesto se il server viene eseguito con lo stesso utente. Lo svantaggio è che vengono conteggiate tutte le connessioni, non ci sono filtri, quindi non funzionerà se l'applicazione è in ascolto su più porte.


Linux
  1. Come trovare il modulo del kernel per un determinato dispositivo?

  2. Come trovare ed eliminare file più vecchi di un determinato periodo di tempo in Linux

  3. Come posso definire DIRECTORY_SEPARATOR per entrambe le piattaforme Windows e Linux?

  4. Come posso eliminare la porta TCP 16969 in Bash?

  5. Come posso ottenere la data e l'ora correnti nel terminale e impostare un comando personalizzato nel terminale per questo?

Come trovare il numero di porta di un servizio in Linux

Come trovare la dimensione totale di una directory in Linux

Come trovare la data e l'ora di installazione del sistema operativo Linux

Dove posso trovare e installare le dipendenze per pygame?

Come posso eseguire il port forwarding con iptables?

Come eseguire il port forwarding da un IP a un altro IP nella stessa rete?