লিনাক্সে কীভাবে সকেট সংযোগ নির্ধারণ করা যায়


24

আমি যাচাই করতে পারি যে সংযোগটি শেষ হয়েছে:

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

এই টিসিপি পোর্ট সংযোগটি কতক্ষণ ধরে (সংযুক্ত) ছিল তা যাচাই করার কোনও উপায় আছে?

(না, আমার কাছে অ্যাপ্লিকেশন লগের অ্যাক্সেস নেই)

উত্তর:


23

আপনি নিম্নলিখিত চেষ্টা করতে পারেন:

  1. বিকল্পটি $pidযোগ করে প্রোগ্রামটির পিআইডি (বলুন ) -pপান netstat

  2. যথাযথ লাইন চিহ্নিত /proc/net/tcpদিকে তাকিয়ে ফাইল local_addressএবং / অথবা rem_address(যে তারা হেক্স ফরম্যাটে আছে, বিশেষ করে আইপি ঠিকানা অল্প endian বাইট অনুক্রমে প্রকাশ করা হয় নোট) ক্ষেত্র, এছাড়াও নিশ্চিত যে stহয় 01(জন্য ESTABLISHED);

  3. সম্পর্কিত inodeক্ষেত্র নোট (বলুন $inode);

  4. যে জন্য অনুসন্ধান inodeফাইল বর্ণনাকারী মধ্যে /proc/$pid/fdএবং পরিশেষে সিম্বলিক লিংক ফাইল অ্যাক্সেস সময়: QUERY

    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)

1
এই রেসিপিটি প্রসেসের বয়স প্রদর্শন করে যা নিজেই সংযোগ নয়, টিসিপি সংযোগ তৈরি করেছে।
মাইরোস্লাভ

@ মাইরোস্লাভ আপনি কি নিশ্চিত? এটি এই নোড.জেএস স্ক্রিপ্টের বিপরীতে কাজ করে ।
সিআরস

ফেডোরা 22 64৪-বিটে আমার ফায়ারফক্স দ্বারা খোলার টিসিপি সংযোগের সাহায্যে আমি আপনার নতুন স্ক্রিপ্টটি পরীক্ষা করেছি এবং আমি অবশ্যই "আপটাইম" নম্বর পাচ্ছি না। নতুন সকেটটি খুললে এটি "র্যান্ডম" আপটাইম পাবে, সাধারণত "কনিষ্ঠ" ইস্টাব্লিশড সকেটের সময়।
মাইরোস্লাভ

@ মাইরোস্লাভ আমি এখানে ডিবিয়ান (৩.১16.০-৪- এএমডি 6464) ব্যবহার করছি, কেবলমাত্র আমি লক্ষ্য করছি যে সময়টি রিপোর্ট করা সময়টি সকেট তৈরির ক্ষেত্রে প্রায় 3 সেকেন্ড দেরিতে হয়। সম্ভবত কিছু সিস্টেম-নির্ভর আচরণ জড়িত রয়েছে ...
সিউরাস

স্ক্রিপ্টের জন্য, "$ সুপারটাইম 192: 168: 120: 10 6379 ট্রেসব্যাক (সর্বশেষতম কল): ফাইল" <স্ট্রিং> ", লাইন 1, <মডুল> সকেট.অররে: অবৈধ আইপি অ্যাড্রেস স্ট্রিং ইনট_এটোন ঠিকানাতে পাস হয়েছে মেলে না "
ওন্দ্রা Žižka

4

এই প্রশ্নগুলি আমার পক্ষে সহায়ক ছিল, কিন্তু আমি lsofতার পরিবর্তে netstatআমাকে সমস্ত এইচএক্স স্টাফ এড়াতে ব্যবহার করে দেখতে পেয়েছি :

${APP}ব্যবহারকারীর দ্বারা পরিচালিত একটি প্রক্রিয়ার জন্য ${USER}, নিম্নলিখিত সমস্ত খোলা সকেটগুলিকে আইপি ঠিকানা $ {আইপি to এ প্রদান করে:

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তবে আমি কীভাবে এটি এবং ডিভাইস নম্বর পেতে পারি তা নিশ্চিত নই।

এটি অ্যামাজন লিনাক্সে পরীক্ষা করা হয়েছিল।


3

সাইরাস দ্বারা লিখিত স্ক্রিপ্টটি আমার পক্ষে কাজ করেছিল তবে আমাকে এটি কিছুটা ঠিক করতে হয়েছিল (হেক্স ঠিকানার "এল" থেকে মুক্তি পেতে এবং পোর্টকে 4 ডিজিটের হেক্স তৈরি করতে):

--- 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")

1

কেমন:

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

আপনি "পিএস" কমান্ডটি কেবল পিড পেতে এবং সময় যেমন -o দিয়ে শুরু করতে পারেন তাও তৈরি করতে পারেন:

lsof -t -i @ 192.168.2.110 | xargs PS - না-শিরোনাম -o'pid, শুরু '-পি

অবশ্যই এটি ধরে নেয় সকেটটি যখন প্রক্রিয়াটি শুরু হয়েছিল।


এটি দেখায় যে সকেটটি খোলার প্রক্রিয়াটি কতক্ষণ শেষ। যদি এমন একটি প্রক্রিয়া থাকে যা সর্বদা চলতে থাকে এবং নেটওয়ার্ক সংযোগ বিচ্ছিন্ন থাকে তবে এই মানগুলি খুব আলাদা হবে। প্রয়াসের জন্য +1
hidralisk

1

স্ক্রিপ্ট উত্তরের জন্য রক্ষিত স্ক্রিপ্টের জন্য ধন্যবাদ। এর সাথে ডুপ্লিকেট প্রিন্ট করার ক্ষেত্রে আমার সমস্যা ছিল, সম্ভবত বিভিন্ন প্রদত্ত ঠিকানায় বিভিন্ন পিআইডি থেকে সংযোগ থাকতে পারে, সুতরাং এখানে আমার উন্নত সংস্করণ যা প্রতিটি আউটপুট লাইনে পিআইডি প্রিন্ট করে:

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( net-toolsরেল> = 7 এবং অনুরূপ সিস্টেমে সরবরাহিত )
  • রুট হিসাবে চালানো প্রয়োজন
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.