В моем php-приложении мне нужен список всех IP-адресов, подключенных к порту 80. Я решил сделать это следующим образом:
<?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.
Fot разрешение /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
Резюме:
Когда я бегу netstat
так как owl
- возвращает пустой список подключений
Когда я бегу netstat
так как root
- возвращает уведомление netstat: kvm not available: /dev/mem: No such file or directory
и IP
Кто-нибудь может мне помочь? Может быть, существует другой способ решения этой задачи? Спасибо
Я верю твоему cut
ведет себя не так, как вы ожидаете, поскольку в netstat
вывод 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, поэтому, основываясь на предложении Криса С.
<?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 даст результат. Также есть канал ## FreeBSD на irc.freenode.net, где часто тусуются знающие люди.