web-dev-qa-db-fra.com

Comment déterminer le temps de connexion sous Linux

Je peux vérifier que la connexion est en place:

$ netstat -tn | grep "192.168.2.110"
tcp  0  0 192.168.2.100:10444  192.168.2.110:52639  ESTABLISHED

y at-il un moyen de vérifier combien de temps cette connexion de port TCP était en place (connecté)?

(Non, je n'ai pas accès aux journaux d'applications)

18
hidralisk

Vous pouvez essayer ce qui suit:

  1. obtenez le PID (par exemple, $pid) du programme en ajoutant l'option -p à netstat.

  2. identifiez la ligne appropriée dans le fichier /proc/net/tcp en consultant les champs local_address et/ou rem_address (notez qu'ils sont au format hexadécimal, plus précisément l'adresse IP est exprimée dans l'ordre des octets little-endian), vérifiez également que la variable st est 01 ( pour ESTABLISHED );

  3. notez le champ inode associé (disons $inode);

  4. recherchez cette inode parmi les descripteurs de fichier dans /proc/$pid/fd et, enfin, interrogez l'heure d'accès au fichier du lien symbolique:

    find /proc/$pid/fd -lname "socket:\[$inode\]" -printf %t
    

C’est un travail fastidieux ... voici un script (stub) pour automatiser les points ci-dessus, il nécessite l’adresse distante et affiche le temps de disponibilité de la socket en secondes:

function suptime() {
    local addr=${1:?Specify the remote IPv4 address}
    local port=${2:?Specify the remote port number}
    # convert the provided address to hex format
    local hex_addr=$(python -c "import socket, struct; print(hex(struct.unpack('<L', socket.inet_aton('$addr'))[0])[2:10].upper().zfill(8))")
    local hex_port=$(python -c "print(hex($port)[2:].upper().zfill(4))")
    # get the PID of the owner process
    local pid=$(netstat -ntp 2>/dev/null | awk '$6 == "ESTABLISHED" && $5 == "'$addr:$port'"{sub("/.*", "", $7); print $7}')
    [ -z "$pid" ] && { echo 'Address does not match' 2>&1; return 1; }
    # get the inode of the socket
    local inode=$(awk '$4 == "01" && $3 == "'$hex_addr:$hex_port'" {print $10}' /proc/net/tcp)
    [ -z "$inode" ] && { echo 'Cannot lookup the socket' 2>&1; return 1; }
    # query the inode status change time
    local timestamp=$(find /proc/$pid/fd -lname "socket:\[$inode\]" -printf %T@)
    [ -z "$timestamp" ] && { echo 'Cannot fetch the timestamp' 2>&1; return 1; }
    # compute the time difference
    LANG=C printf '%s (%.2fs ago)\n' "$(date -d @$timestamp)" $(bc <<<"$(date +%s.%N) - $timestamp")
}

(Editez grâce à Alex pour les corrections )

Exemple:

$ suptime 93.184.216.34 80
Thu Dec 24 16:22:58 CET 2015 (46.12s ago)
14
cYrus

Ces questions m’ont été utiles, mais j’ai découvert que l’utilisation de lsof au lieu de netstat me permettait d’éviter tout ce qui concernait HEX:

Pour un processus ${APP} exécuté par l'utilisateur ${USER}, ce qui suit renvoie tous les sockets ouverts à l'adresse IP $ {IP}:

PEEID=$(Sudo pgrep -u ${USER} ${APP}) && for i in `Sudo lsof -anP -i -u logstash | grep ${IP} | awk '{print $6}'` ; do echo "${device} time" ; Sudo find /proc/${PEEID}/fd -lname "socket:\[${device}\]" -printf %t 2> /dev/null  ; echo  ;  done

La lsof contient aussi la PID, mais je ne sais pas comment l'obtenir ni le numéro de périphérique.

Ceci a été testé sur Amazon Linux.

3
Raúl Cuza

Le script de cYrus a fonctionné pour moi, mais je devais le corriger un peu (pour me débarrasser d’un "L" dans l’adresse hexadécimale et pour que le port soit un hexadécimal à 4 chiffres):

--- suptime.orig    2015-08-20 15:46:12.896652464 +0200
+++ suptime 2015-08-20 15:47:48.560074728 +0200
@@ -7,8 +7,8 @@
     hex_addr=$(python -c "
 import socket, struct;
 print hex(struct.unpack('<L',
-socket.inet_aton('$addr'))[0])[2:].upper().zfill(8)")
-    hex_port=$(python -c "print hex($port)[2:].upper()")
+socket.inet_aton('$addr'))[0])[2:10].upper().zfill(8)")
+    hex_port=$(python -c "print hex($port)[2:].upper().zfill(4)")
     inode=$(awk '$3 == "'$hex_addr:$hex_port'" {print $10}' /proc/net/tcp)
     time=$(find /proc/$pid/fd -lname "socket:\[$inode\]" -printf %A@)
     LANG=C printf '%.2fs' $(bc <<<"$(date +%s.%N) - $time")
2
Alex Vazquez Fente

Que diriez-vous:

lsof -t -i @ 192.168.2.110 | xargs ps -fp

Vous pouvez également personnaliser la commande "ps" pour obtenir uniquement pid et heure de début avec -o, par exemple:

lsof -t -i @ 192.168.2.110 | xargs ps --no-headers -o'pid, start '-p

Bien entendu, cela suppose que le socket a été démarré au moment du processus.

0
Pete

Merci pour le script maintenu dans la réponse de cYrus. J'ai eu des problèmes avec l'impression des doublons, probablement parce qu'il peut y avoir beaucoup de connexions de différents PID à l'adresse fournie. Voici donc ma version améliorée qui affiche également le PID sur chaque ligne de sortie:

function suptime() {
    local addr=${1:?Specify the remote IPv4 address}
    local port=${2:?Specify the remote port number}

    # convert the provided address to hex format
    local hex_addr=$(python -c "import socket, struct; print(hex(struct.unpack('<L', socket.inet_aton('$addr'))[0])[2:10].upper().zfill(8))")
    local hex_port=$(python -c "print(hex($port)[2:].upper().zfill(4))")

    # get the inode of the socket
    local inodes=$(awk '$4 == "01" && $3 == "'$hex_addr:$hex_port'" {print $10}' /proc/net/tcp)
    [ -z "$inodes" ] && { echo 'Cannot lookup the socket(s)' 2>&1; return 1; }

    # get file descriptors
    for inode in $inodes; do
        # get inode's file descriptor details
        local fdinfo=( $(find /proc/[0-9]*/fd -lname "socket:\[$inode\]" -printf "%p %T@") )
        [ -z "$fdinfo" ] && { echo 'Cannot find file descriptor' 2>&1; return 1; }

        # extract pid
        local fdpath=${fdinfo[0]}
        local pid=${fdpath#/proc/}
        pid=${pid%%/*}

        # extract timestamp
        local timestamp=${fdinfo[1]}

        # compute the time difference
        LANG=C printf 'PID: %s; Age: %s (%.2fs ago)\n' "$pid" "$(date -d @$timestamp)" $(bc <<<"$(date +%s.%N) - $timestamp")
    done
}

Remarques:

  • bc, netstat (fourni par net-tools sur rhel> = 7 et systèmes similaires)
  • doit être exécuté en tant que root
0
fholzer