Мне нужна помощь в поиске IP-адреса моего компьютера, когда он находится в сети. Я создаю систему типа киосков, которая будет помещена в разные местоположения, и мне нужно иметь возможность использовать веб-браузер для поиска IP-адреса этого компьютера в локальной сети.
Если я использую $_SERVER['SERVER_ADDR']
я получаю IP-адрес, через который я подключаюсь через локальный браузер (127.0.0.1) на этом компьютере.
Я не могу позвонить и получить публичный IP-адрес, потому что блоки могут находиться за маршрутизатором, и я не хочу публичный IP-адрес маршрутизатора.
Мне нужно найти IP-адрес этого окна на сервере (например: 192.168.0.xxx)
Я знаю, что когда я делаю «ip addr show» с терминала, я получаю
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: em1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 61:a6:4d:63:a2:80 brd ff:ff:ff:ff:ff:ff inet 192.168.0.211/24 brd 192.168.0.255 scope global em1 inet6 fe80::62a4:4cff:fe64:a399/64 scope link valid_lft forever preferred_lft forever
Когда я пытаюсь:
$command="ip addr show"; $localIP = exec ($command);
$localIP
выдает «valid_lft forever preferred_lft forever», но ни одна другая информация. Если я могу получить все это в $localIP
тогда я могу отфильтровать IP-адрес inet, но он не даст мне все.
Есть ли более простой способ сделать это или что-то, что мне не хватает при попытке выполнить команду «ip addr show»? Кроме того, я запускаюсь под пользователем apache и не могу запускать его как root для этого приложения.
Как указано в exec()
, из функции возвращается только строка LAST из команды exec'd. Чтобы захватить весь вывод, вы должны использовать необязательный второй аргумент функции:
$last_line = exec('ip addr show', $full_output); ^^^^^^^^^^^^
$full_output
будет массивом строк вывода из программы exec'd.
Сервер (должен) знать, как разрешить собственное имя хоста на правильный IP-адрес, даже если он не подключен к Интернету.
Итак, все, что вам нужно сделать, это получить ваше имя хоста, а затем разрешить имя хоста на IP-адрес. Что-то вроде этого должно отлично работать для вас:
$ip = gethostbyname(gethostname());
Независимо от того, зарегистрировано ли имя хоста в DNS, файл / etc / hosts или даже ActiveDirectory, до тех пор, пока он разрешима каким-то образом, он получит вам разрешенный IP-адрес.
Вероятно, вам также придется планировать другие варианты. Поэтому проверьте, что выше работало, если это не так, тогда вам нужно вернуться к другим параметрам:
$_SERVER['HTTP_HOST']
содержит адрес, который был введен в адресную строку браузера для доступа к странице. Если вы заходите на страницу, введя (например) http://192.168.0.1/index.php
в браузер, $_SERVER['HTTP_HOST']
будет 192.168.0.1
. gethostbyname($_SERVER['HTTP_HOST'])
; превратит это DNS-имя в IP-адрес. $_SERVER['SERVER_NAME']
содержит имя, настроенное в конфигурации веб-сервера, в качестве имени сервера. Если вы собираетесь использовать это, вы можете просто просто записать его на PHP. $_SERVER['SERVER_ADDR']
будет содержать операционную систему основного IP-адреса сервера. Это может быть или не быть IP-адресом, который использовался для доступа к странице, и может быть или не быть IP-адресом с привязанным к нему веб-сервером. Это сильно зависит от конфигурации ОС и сервера. если у сервера есть один IP-адрес, это, вероятно, безопасная ставка, хотя бывают ситуации, когда это может содержать 127.0.0.1
. Вы можете попробовать что-то вроде:
<?php $ip = gethostbyname(gethostname()); // if we didn't get an IP address if ($ip === gethostname()){ // lets see if we can get it from the // configured web server name $ip = gethostbyname($_SERVER['SERVER_NAME']); // if we still don't have an IP address if ($ip === $_SERVER['SERVER_NAME']){ // Then we default to whatever the OS // is telling us is it's primary IP address $ip = $_SERVER['SERVER_ADDR']; } }
Если вы используете для командной строки (опасный, потенциальный вектор атаки) в linux, вы можете сделать что-то вроде:
//then all non 127.0.0.1 ips should be in the $IPS variable echo exec('/sbin/ifconfig | grep "inet addr:" | grep -v "127.0.0.1" | cut -d: -f2 | awk \'{ print $1}\'', $IPS); $ip = ''; $foundIps = count($IPS); switch($foundIps){ case 0: print "Crud, we don't have any IP addresses here!\n"; $ip = '127.0.0.1'; break; case 1: print "Perfect, we found a single usable IP address, this must be what we want!\n"; $ip = $IPS[0]; break; default: print "Oh snap, this machine has multiple IP addresses assigned, what you wanna do about that?\n" // I'm crazy, I'll just take the second one! $ip = $IPS[1]; }
Это простая функция, которая с помощью системы /etc/network/interfaces
вернет вам общедоступную и приватную настройку адреса IPv4 для eth0 и eth1
function getIps() { $ifs_raw=file('/etc/network/interfaces'); $tocheck=array('eth0','eth1'); foreach($tocheck as $if) { foreach($ifs_raw as $idx=>$line) { if(strpos($line,"iface {$if} inet static")!==false) { $address=$ifs_raw[$idx+1]; $address=trim($address);$address=ltrim($address,"\t");$address=rtrim($address,"\t"); list($address_text,$addrip)=explode(" ",$address); if($address_text=='address') { if(filter_var($addrip, FILTER_VALIDATE_IP) !== false) { //Valid IP if(false===filter_var($addrip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { $ips['private']=$addrip; } else { $ips['public']=$addrip; } } } } } } return $ips; }
иfunction getIps() { $ifs_raw=file('/etc/network/interfaces'); $tocheck=array('eth0','eth1'); foreach($tocheck as $if) { foreach($ifs_raw as $idx=>$line) { if(strpos($line,"iface {$if} inet static")!==false) { $address=$ifs_raw[$idx+1]; $address=trim($address);$address=ltrim($address,"\t");$address=rtrim($address,"\t"); list($address_text,$addrip)=explode(" ",$address); if($address_text=='address') { if(filter_var($addrip, FILTER_VALIDATE_IP) !== false) { //Valid IP if(false===filter_var($addrip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE)) { $ips['private']=$addrip; } else { $ips['public']=$addrip; } } } } } } return $ips; }
$_SERVER['REMOTE_ADDR'];
должен сделать трюк.
И если это не сработает, вы всегда можете shell_exec($command);
с shell_exec($command);
, Но имейте в виду, что вам нужно установить права доступа к файлу php для выполнения.
Конфигурация веб-интерфейсов в debian / ubuntu находится в файле / etc / network / interfaces. Вы можете читать, если php cgi-процесс не chrooted и посмотреть этот файл, вы можете его разобрать и получить ip-адрес. Его легко читать. Что-то вроде этого должно работать …
$myFile = "/etc/network/interfaces"; $fh = fopen($myFile, 'r'); $theData = ""; $resoult = ""; while(! feof($file)){ $theData = fgets($fh); if($theData == "iface em1 inet static"){ while(! feof($file)){ $theData = fgets($fh); if(split(" ",$theData)[0] == "address"){ $resoult = split(" ",$theData)[1]; brake; } } brake; } } fclose($fh); echo $resoult;
Хорошо, я нашел решение ….
Bubba -> Вы решили вернуть адрес 127.0.0.1. Домен box – demo01.com, и похоже, что он вытаскивает локальный адрес 127. Я попытался вызвать php-файл с помощью веб-браузера на этом компьютере вместе с браузером с другого компьютера, используя фактический адрес 192.168.x, и он дал мне адрес 127.0.0.1 оба раза.
Paulina -> IP-адрес динамически устанавливается хост-маршрутизатором. Поскольку это происходит в нескольких местах, я не могу кодировать IP-адрес в ящики. Я не знаю, было бы ли hardcoding у него в действительности иметь какое-либо отношение к этому или нет, но я получил содержимое файла, но у них нет IP-адреса: # Этот файл описывает сетевые интерфейсы, доступные в вашей системе #, и как для их активации. Для получения дополнительной информации см. Интерфейсы (5).
# The loopback network interface auto lo iface lo inet loopback # The primary network interface #auto em1 #iface em1 inet dhcp
Marc B -> Ваше решение, которое сработало для меня. Я не знал, что мне нужно добавить эту вторую переменную в вызов, чтобы отобразить ее. Я могу разобрать IP-адрес оттуда. Поскольку это только для отображения для человека, который настраивает киоск, если по какой-то причине несколько адресов, я могу вытащить каждого из них и отобразить список, а затем они могут сыграть хит и пропустить, это будет всего лишь 2 IP, вероятно, им все равно придется беспокоиться (lan и wan)
У меня недостаточно сока, чтобы поднять ваш ответ на ответ, если бы я мог. Но я благодарен и благодарю вас!
Joren -> Это не сработает для моих нужд, remote_address возвращает адрес компьютера, вызывающего скрипт. Если я вызову его с удаленного компьютера, я собираюсь получить IP-адрес этого компьютера, если я его вызову из браузера, я либо должен знать адрес этого поля, чтобы поместить его в адресную строку (что я не знаю, t, и именно поэтому мне нужен сценарий) или вызывать его из 127.0.0.1 или localhost, в котором я получаю 127.0.0.1 в качестве ответа в любом случае.
если вам нужен только конкретный интерфейс, вы можете использовать этот
$ip = `ifconfig en1 inet | grep inet | awk '{print $2}'`
выход – это просто ip этого интерфейса