Php

Netstat 通過 php 函式 exec() 在 FreeBSD 上不起作用

  • May 9, 2013

在我的 php-app 中,我需要在埠 80 上連接的所有 IP 的列表。我選擇這樣做:

<?php
    $ips = exec("netstat -an |grep 'tcp\|udp' | awk '{print $5}' | cut -d: -f1 | sort | uniq -c", $info);
?>

但它不適用於我的 VPS FreeBSD 伺服器。當我開始時netstat -an會出現一條通知並且輸出中沒有連接:

netstat: kvm not available: /dev/mem: No such file or directory

我試圖添加device mem到 conf,但我有一個空的 /usr/src/sys。我到了需要重建核心的地步。))

netstat當使用者是 root 時(從控制台)正常工作。我在類似的 CentOS 託管平台上沒有遇到過這樣的問題。

/dev/mem: No such file or directory我嘗試過解決問題,mknod -m 660 /dev/mem c 1 1但它呼叫了mknod: /dev/mem: Operation not permitted

我有以下使用者pw showuser

owl:*:1000:1003:default:0:0:owl:/home/owl/data:/bin/csh
root:*:0:0::0:0:Charlie &:/root:/bin/csh

摘要:

當我執行netstatowl- 它返回一個空的連接列表

當我執行netstatroot- 它返回通知netstat: kvm not available: /dev/mem: No such file or directory和 IP

有誰能夠幫助我?是否存在解決此任務的另一種方法?謝謝

我相信你cut的行為不像你期望的那樣,因為在netstat’s 的輸出中,IP 和埠用點分隔,而不是冒號。

當我在我管理的一些監獄中執行時,我也會得到一個netstat: kvm not available: /dev/mem: No such file or directory錯誤netstat -an,但儘管有這個錯誤,我仍然從 netstat 得到預期的結果。我還沒有研究為什麼會發生這種情況,所以我傾向於認為這是一個紅鯡魚。

就命令行而言,您可以通過將更多功能打包到 awk 腳本中來減少管道:

netstat -an | \
 awk '/^(tcp|udp)/{ip=$5; sub(/.[0-9]+$/,"",ip); list[ip]++;} END{for(ip in list){printf("%7d %s\n",list[ip],ip)}}'

拆分為便於閱讀,這個 awk 腳本是:

# Only work on tcp/udp lines...
/^(tcp|udp)/ {
 ip=$5;
 sub(/.[0-9]+$/,"",ip);
 list[ip]++;  # Populate an array of counters-per-IP
}

# After data are gathered, print the results.
END {
 for (ip in list) {
   printf("%7d %s\n",list[ip],ip);
 }
}

但是由於您是在 PHP 中執行此操作,所以我會在 PHP 中進行更多的文本處理。

<?php

# Gather our data...
exec("netstat -an", $out);

# Easy access to the output we want (for isset() below)
$permit = array("udp4"=>1,"tcp4"=>1);

foreach ($out as $line) {

 $a = preg_split("/[[:space:]]+/", $line);

 # Only work on tcp4/udp4 lines...
 if (isset($permit[$a[0]])) {
   # Populate an array of counters...
   $ip = substr($a[4], 0, strrpos($a[4],".")-1);
   $list[$ip]++;
 }

}

# And print the results.
foreach ($list as $ip => $count) {
 printf("%7s\t%s\n", $count, $ip);
}

這看起來像是更多的工作,但實際上它可能比生成管道集合更快。

請注意,您sockstat在 FreeBSD 中也有該命令,因此基於 Chris S 的建議:

<?php

exec("sockstat -4", $out);

$permit = array("udp4"=>1,"tcp4"=>1);

foreach ($out as $line) {

 $a = preg_split("/[[:space:]]+/", $line);

 if (isset($permit[$a[4]])) {
   preg_match("/^[^:]+/", $a[6], $ip);
   $list[$ip[0]]++;
 }

}

foreach ($list as $ip => $count) {
 printf("%7s\t%s\n", $count, $ip);
}

更新:

我還發現了這個關於 kvm 錯誤的古老註釋。由於路由表資訊通常是可用的,因此您應該聯繫您的 VPS 提供商並了解他們是否故意限制您訪問此主機上的路由表數據。如果您不在監獄中,那麼我懷疑向 FreeBSD 郵件列表之一發帖會得到結果。irc.freenode.net 上還有一個##FreeBSD 頻道,知識淵博的人經常在那裡閒逛。

引用自:https://serverfault.com/questions/503324