obtenga el PID (digamos $pid) del programa agregando la -popción a netstat.
identifique la línea correcta en el /proc/net/tcparchivo mirando los campos local_addressy / o rem_address(tenga en cuenta que están en formato hexadecimal, específicamente la dirección IP se expresa en orden de bytes little-endian), también asegúrese de que stsea 01(para ESTABLISHED);
tenga en cuenta el inodecampo asociado (por ejemplo $inode);
busque eso inodeentre los descriptores de archivo /proc/$pid/fdy finalmente consulte el tiempo de acceso al archivo del enlace simbólico:
Ese es un trabajo duro ... aquí hay un script (stub) para automatizar los puntos anteriores, requiere la dirección remota e imprime el tiempo de actividad del socket en segundos:
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")
}
Probé su nuevo script con conexiones TCP abiertas por mi Firefox en Fedora 22 de 64 bits, y definitivamente no obtengo números de "tiempo de actividad". Cuando se abre un nuevo socket, está obteniendo un tiempo de actividad "aleatorio", generalmente el tiempo del socket ESTABLECIDO "más joven".
myroslav
@myroslav Estoy usando Debian (3.16.0-4-amd64) aquí, lo único que noto es que el tiempo informado es en realidad unos 3 segundos de retraso con respecto a la creación del socket. Tal vez hay algunos comportamientos dependientes del sistema involucrados ...
cYrus
Para el script, "$ suptime 192: 168: 120: 10 6379 Traceback (última llamada más reciente): Archivo" <cadena> ", línea 1, en <módulo> socket.error: cadena de dirección IP ilegal pasada a inet_aton La dirección sí no coincide "
Ondra Žižka
4
Estas preguntas me ayudaron, pero descubrí que usar en lsoflugar de netstatdejarme evitar todas las cosas HEX:
Para un proceso ${APP}ejecutado por el usuario ${USER}, lo siguiente devuelve todos los sockets abiertos a la dirección IP $ {IP}:
El script de cYrus funcionó para mí, pero tuve que arreglarlo un poco (para deshacerme de una "L" en la dirección hexadecimal y convertir el puerto en un hexadecimal de 4 dígitos):
Esto muestra cuánto tiempo está activo el proceso que abrió el socket. En caso de que haya un proceso que se ejecute todo el tiempo y haya desconexiones de la red, estos valores serían muy diferentes. +1 por esfuerzo
hidralisco
1
Gracias por el guión mantenido en la respuesta de cYrus. Tuve problemas con la impresión de duplicados, probablemente porque puede haber muchas conexiones de diferentes PID a la dirección proporcionada, así que aquí está mi versión mejorada que también imprime el PID en cada línea de salida:
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
}
Notas:
necesidades bc, netstat(proporcionado por net-toolsel rhel> = 7 y sistemas similares)
Estas preguntas me ayudaron, pero descubrí que usar en
lsof
lugar denetstat
dejarme evitar todas las cosas HEX:Para un proceso
${APP}
ejecutado por el usuario${USER}
, lo siguiente devuelve todos los sockets abiertos a la dirección IP $ {IP}:El
lsof
contienePID
también, pero no estoy seguro de cómo obtenerlo y el número de dispositivo.Esto fue probado en Amazon Linux.
fuente
El script de cYrus funcionó para mí, pero tuve que arreglarlo un poco (para deshacerme de una "L" en la dirección hexadecimal y convertir el puerto en un hexadecimal de 4 dígitos):
fuente
Qué tal si:
También puede personalizar el comando "ps" para obtener pid y comenzar la hora con -o como:
Por supuesto, esto supone que el socket se inició cuando el proceso fue.
fuente
Gracias por el guión mantenido en la respuesta de cYrus. Tuve problemas con la impresión de duplicados, probablemente porque puede haber muchas conexiones de diferentes PID a la dirección proporcionada, así que aquí está mi versión mejorada que también imprime el PID en cada línea de salida:
Notas:
bc
,netstat
(proporcionado pornet-tools
el rhel> = 7 y sistemas similares)fuente