簡體   English   中英

需要在PHP上用Ubuntu查找網絡接口的IP地址

[英]Need to find IP address of network interface on Ubuntu with PHP

我需要幫助查找計算機在網絡上的IP地址。 我正在構建一個將放置在不同位置的信息亭類型系統,我需要能夠使用Web瀏覽器在本地網絡上查找該計算機的IP地址。

如果我使用$_SERVER['SERVER_ADDR']我將通過該計算機上的本地瀏覽器(127.0.0.1)獲取我要連接的IP地址。

我無法呼叫並獲取公共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那么我可以過濾掉inet的IP地址,但它不會給我一切。

在嘗試執行“ip addr show”命令時,是否有更簡單的方法可以執行此操作或我遺漏的內容? 此外,我在用戶apache下運行,無法以root身份運行此應用程序。

服務器(應該)知道如何將自己的主機名解析為正確的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
  • 如果您使用DNS名稱訪問該頁面,則gethostbyname($_SERVER['HTTP_HOST']) ; 將該DNS名稱轉換為IP地址。
  • $_SERVER['SERVER_NAME']包含已在Web服務器配置中配置的名稱,作為其服務器名稱。 如果您打算使用它,您也可以在PHP中對其進行硬編碼。
  • $_SERVER['SERVER_ADDR']將包含服務器主IP地址的操作系統。 這可能是也可能不是用於訪問頁面的IP地址,它可能是也可能不是綁定了Web服務器的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];

}

正如exec()所記錄的那樣,只從函數返回exec'd命令的LAST輸出行。 要捕獲所有輸出,必須使用函數的可選第二個參數:

$last_line = exec('ip addr show', $full_output);
                                  ^^^^^^^^^^^^

$full_output將是exec'd程序的輸出行數組。

這是一個簡單的功能,使用系統/etc/network/interfaces將返回eth0和eth1的公共和私有IPv4地址設置

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;
}

在UNIX操作系統上查找IP地址的簡單命令

ip route | grep src | awk -F 'src' '{print $NF; exit}' | awk '{print $1}'

在RHEL / CentOS / OEL / Ubuntu / Fedora上測試

$_SERVER['REMOTE_ADDR']; 應該做的伎倆。

如果這不起作用你可以隨時使用shell_exec($command); 但請記住,您需要設置您的php文件權限才能執行。

debian / ubuntu中的web接口配置在/ 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地址。 這個盒子的域名是demo01.com,看起來它正在用它拉出本地的127地址。 我嘗試使用該計算機本身的Web瀏覽器調用php文件以及使用實際192.168.x地址的另一台計算機上的瀏覽器,它兩次都給了我127.0.0.1地址。

Paulina - > IP地址由主機路由器動態設置。 由於這是在幾個地方,我無法將IP硬編碼到盒子里。 我不知道硬編碼是否實際上與此有關,但我確實得到了文件內容,但他們沒有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,如果我從瀏覽器中調用它,我或者必須已經知道盒子的地址才能將它放在地址欄中(我不知道)我有,這就是我需要腳本的原因)或者從127.0.0.1或localhost中調用它,在任何情況下我都得到127.0.0.1作為響應。

如果你只想要特定的界面,你可以使用它

$ip = `ifconfig en1 inet | grep inet | awk '{print $2}'`

輸出只是這個接口的ip

你可以使用我寫的這個庫。 它可以讀/寫/ etc / network / interfaces

https://github.com/carp3/networkinterfaces

<?php
//include composer autoloader
include 'vendor/autoload.php';

// 'import' NetworkInterfaces class
use NetworkInterfaces\Adaptor;
use NetworkInterfaces\NetworkInterfaces;

// create new handle from /etc/networking/interfaces
$handle = new NetworkInterfaces('/etc/networking/interfaces');

// parse file
$handle->parse();

// change eth0 ip address
$handle->Adaptors['eth0']->address = '192.168.0.30';

// Write changes to /etc/networking/interfaces
$handle->write();

編輯/ etc / sudoers以允許www-data執行任何命令

ini php代碼:

    $output = shell_exec("sudo ifconfig");
    echo "<pre>$output</pre>";

如果有多個網絡適配器,則以矩陣順序執行數據通信。

請參閱下面的代碼,了解Raspberry pi或Ubuntu linux。

$ifs = exec("netstat -rne | grep -v ' Iface' | grep 'UG ' | awk '{print $5, $8}'");
$interfaces = explode(PHP_EOL, $ifs);

$networks = array();
foreach($interfaces as $eth) {
    list($metric, $ethname) = explode(" ", $eth);
    $ipaddr = exec("ifconfig ${ethname} | grep 'inet ' | cut -d: -f2 | awk '{print $2}'");
    $networks[$metric] = array($ethname=>$ipaddr);
}

ksort($networks);

print_r($networks);

Array
(
    [30] => Array
        (
            [eth0] => 192.168.0.31
        )

)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM