obtenir le PID (par exemple $pid) du programme en ajoutant l' -poption à netstat.
identifiez la ligne appropriée dans le /proc/net/tcpfichier en regardant les champs local_addresset / ou rem_address(notez qu'ils sont au format hexadécimal, en particulier l'adresse IP est exprimée dans l'ordre des octets en petits caractères), assurez-vous également que le stest 01(pour ESTABLISHED);
notez le inodechamp associé (par exemple $inode);
recherchez-le inodeparmi les descripteurs de fichiers dans /proc/$pid/fdet enfin interrogez le temps d'accès au fichier du lien symbolique:
C'est un gros travail ... voici un script (stub) pour automatiser les points ci-dessus, il nécessite l'adresse distante et il imprime la disponibilité du socket en quelques 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")
}
Cette recette affiche l'âge du processus qui a créé la connexion TCP, pas la connexion elle-même.
myroslav
@myroslav êtes-vous sûr? Il fonctionne contre ce scénario Node.js .
cYrus
J'avais testé votre nouveau script avec des connexions TCP ouvertes par mon Firefox sur Fedora 22 64 bits, et je n'obtenais certainement pas de numéros de "disponibilité". Quand un nouveau socket s'ouvre, il obtient une disponibilité "aléatoire", généralement le temps du "plus jeune" socket ESTABLISHED.
myroslav
@myroslav J'utilise Debian (3.16.0-4-amd64) ici, la seule chose que je remarque, c'est que le temps signalé est en fait d'environ 3 secondes de retard par rapport à la création de socket. Peut-être qu'il y a des comportements dépendants du système impliqués ...
cYrus
Pour le script, "$ suptime 192: 168: 120: 10 6379 Traceback (dernier appel le plus récent): Fichier" <string> ", ligne 1, dans <module> socket.error: une chaîne d'adresse IP illégale passée à inet_aton ne correspond pas "
Ondra Žižka
4
Ces questions m'ont été utiles, mais j'ai trouvé l'utilisation lsofau lieu de netstatme laisser éviter toutes les choses HEX:
Pour un processus ${APP}exécuté par l'utilisateur ${USER}, ce qui suit renvoie tous les sockets ouverts à l'adresse IP $ {IP}:
Le script de cYrus a fonctionné pour moi mais j'ai dû le corriger un peu (pour se débarrasser d'un "L" dans l'adresse hexadécimale et faire du port un hexadécimal à 4 chiffres):
cela montre combien de temps le processus qui a ouvert le socket est en place. Dans le cas où il y a un processus qui s'exécute tout le temps et qu'il y a des déconnexions réseau, ces valeurs seraient très différentes. +1 pour l'effort
hidralisk
1
Merci pour le script maintenu dans la réponse de cYrus. J'ai eu des problèmes avec l'impression de doublons, probablement parce qu'il peut y avoir de nombreuses connexions de différents PID à l'adresse fournie, alors voici ma version améliorée qui imprime é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:
besoins bc, netstat(fournis par net-toolsle rhel> = 7 et des systèmes similaires)
Ces questions m'ont été utiles, mais j'ai trouvé l'utilisation
lsof
au lieu denetstat
me laisser éviter toutes les choses HEX:Pour un processus
${APP}
exécuté par l'utilisateur${USER}
, ce qui suit renvoie tous les sockets ouverts à l'adresse IP $ {IP}:Le
lsof
contientPID
également, mais je ne sais pas comment l'obtenir ni le numéro de l'appareil.Cela a été testé sur Amazon Linux.
la source
Le script de cYrus a fonctionné pour moi mais j'ai dû le corriger un peu (pour se débarrasser d'un "L" dans l'adresse hexadécimale et faire du port un hexadécimal à 4 chiffres):
la source
Que diriez-vous:
Vous pouvez également personnaliser la commande "ps" pour obtenir simplement pid et l'heure de début avec -o comme:
Bien sûr, cela suppose que le socket a été démarré au moment du processus.
la source
Merci pour le script maintenu dans la réponse de cYrus. J'ai eu des problèmes avec l'impression de doublons, probablement parce qu'il peut y avoir de nombreuses connexions de différents PID à l'adresse fournie, alors voici ma version améliorée qui imprime également le PID sur chaque ligne de sortie:
Remarques:
bc
,netstat
(fournis parnet-tools
le rhel> = 7 et des systèmes similaires)la source