接続が確立していることを確認できます。
$ netstat -tn | grep "192.168.2.110"
tcp 0 0 192.168.2.100:10444 192.168.2.110:52639 ESTABLISHED
このtcpポート接続がアップ(接続)されていた時間を確認する方法はありますか?
(いいえ、私はアプリログにアクセスできません)
以下を試すことができます。
netstat
に$pid
オプションを追加して、プログラムのPID(-p
など)を取得します。
/proc/net/tcp
フィールドおよびlocal_address
フィールドを調べて、rem_address
ファイルの適切な行を特定します(16進数形式であることに注意してください。具体的には、IPアドレスはリトルエンディアンバイトで表されます)順序)、st
が01
( ESTABLISHED
);であることも確認してください。
関連するinode
フィールドに注意してください($inode
など)。
/proc/$pid/fd
のファイル記述子からinode
を検索し、最後にシンボリックリンクのファイルアクセス時間をクエリします。
find /proc/$pid/fd -lname "socket:\[$inode\]" -printf %t
それは面倒な作業です...ここに上記のポイントを自動化するスクリプト(スタブ)があります。リモートアドレスが必要で、ソケットの稼働時間を出力します秒:
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")
}
例:
$ suptime 93.184.216.34 80
Thu Dec 24 16:22:58 CET 2015 (46.12s ago)
この質問は私にとって役に立ちましたが、lsof
の代わりにnetstat
を使用していることがわかり、HEXに関するすべてのことを回避できました。
プロセスの場合${APP}
ユーザーが実行${USER}
、次は、開いているすべてのソケットを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
lsof
にはPID
も含まれていますが、取得方法とデバイス番号がわかりません。
これはAmazon Linuxでテストされました。
CYrusのスクリプトは私にとってはうまくいきましたが、少し修正する必要がありました(16進数のアドレスの "L"を取り除き、ポートを4桁の16進数にするため)。
--- 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")
どうですか:
lsof -t -i @ 192.168.2.110 | xargs ps -fp
「ps」コマンドを調整して、pidを取得し、-oを使用して時刻を開始することもできます。
lsof -t -i @ 192.168.2.110 | xargs ps --no-headers -o'pid、start '-p
もちろん、これはプロセスの開始時にソケットが開始されたと想定しています。
CYrusの回答で維持されているスクリプトに感謝します。おそらく、異なるPIDから指定されたアドレスへの接続が多いため、重複の印刷に問題がありました。そのため、各出力行にPIDも印刷するように改良したバージョンを次に示します。
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
}
ノート:
bc
、netstat
が必要(rhel> = 7および類似のシステムでnet-tools
によって提供)