GNU/Linux >> Tutoriels Linux >  >> Linux

Comment puis-je trouver le nombre total de connexions TCP pour un port et une période donnés par IP ?

Activez iptables et réglez-le sur LOG pour les connexions entrantes. Exemple de règle :

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

(où 4711 est le port que vous souhaitez suivre).

Exécutez ensuite le journal résultant via le script de votre choix qui peut faire le résumé pour vous.


Vous pouvez utiliser tcpdump pour enregistrer tous les paquets SYN (sans ACK) :

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

ou journaliser tous les paquets SYN+ACK (connexions établies) :

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

Et puis combinez-le avec un wc -l compter toutes les lignes

Vous auriez également besoin d'un moyen de mesurer des périodes de temps fixes (vous pourriez avoir un cron qui lui envoie simplement un SIGINT à intervalles réguliers, tcpdump comptera les octets et les paquets mais n'enregistrera que le temps)

Mise à jour :inutile de le dire, consultez la page de manuel de tcpdump et envisagez d'utiliser certaines options telles que :-i (écouter une seule interface), -p (désactiver le mode promiscuité ; moins invasif), ou certaines options de sortie. Tcpdump a besoin des autorisations root et votre patron peut ne pas l'aimer car c'est une sorte d'outil de piratage. D'autre part, vous n'avez pas besoin de toucher à quoi que ce soit sur votre système pour l'exécuter (contrairement au iptables LOG solutions)

Veuillez également noter la petite différence src/dsk dans le filtre. Si vous interceptez des paquets SYN+ACK et souhaitez compter les connexions vers un serveur sur le port 4711, vous avez besoin de src. Si vous interceptez des paquets SYN+!ACK pour le même résultat, vous avez besoin de dst. Si vous comptez les connexions sur le serveur lui-même, vous devez toujours utiliser l'inverse.


Solution SystemTap

Script inspiré de l'exemple 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)
    }
  }
}

Sortie :

[[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

solution de suivi

Soit lancer le programme sous strace :

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

ou tracer un programme déjà en cours :

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

-r imprime un horodatage relatif à l'entrée de chaque appel système au cas où il serait nécessaire plus tard pour une analyse de performances supplémentaire. -f trace les processus enfants et il se peut qu'il ne soit pas nécessaire.

La sortie ressemble à ceci :

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

et peut être filtré avec :

# 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

Brève explication du one-liner AKW :m[1] est le PID, m[2] est l'horodatage, m[3] est le port distant et m[4] est l'adresse distante.

L'avantage de cette solution est que root n'est pas requis si le serveur s'exécute sous le même utilisateur. Le inconvénient est que toutes les connexions sont comptées, il n'y a pas de filtrage, donc cela ne fonctionnera pas si l'application écoute sur plusieurs ports.


Linux
  1. Comment trouver le module du noyau pour un appareil donné ?

  2. Comment fonctionne la corbeille et où puis-je trouver de la documentation officielle, des références ou des spécifications pour celle-ci ?

  3. Comment puis-je tuer le port TCP 16969 dans Bash ?

  4. Comment puis-je trouver des fichiers et calculer leur taille ?

  5. Comment puis-je transférer un port avec iptables ?

Comment trouver le numéro de port d'un service sous Linux

Comment trouver la taille totale d'un répertoire sous Linux

Comment trouver la date et l'heure d'installation du système d'exploitation Linux

Comment puis-je obtenir la date et l'heure actuelles dans le terminal et définir une commande personnalisée dans le terminal pour cela ?

Comment puis-je trouver le nombre d'utilisateurs en ligne sous Linux ?

Comment puis-je compter le nombre de dossiers dans un lecteur sous Linux ?