我需要帮助查找计算机在网络上的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身份运行此应用程序。
答案 0 :(得分:4)
服务器(应该)知道如何将自己的主机名解析为正确的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']
包含已配置的名称
Web服务器配置作为服务器名称。如果你要使用
这个,你不妨在PHP中硬编码。$_SERVER['SERVER_ADDR']
将包含该操作系统
服务器的主IP地址。这可能是也可能不是IP地址
用于访问页面的,它可能是也可能不是IP
绑定到Web服务器的地址。它在很大程度上取决于OS和
服务器配置。如果服务器有一个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];
}
答案 1 :(得分:4)
如exec()
所述,只有exec'd命令的最后一行输出从函数返回。要捕获所有输出,必须使用函数的可选第二个参数:
$last_line = exec('ip addr show', $full_output);
^^^^^^^^^^^^
$full_output
将是来自exec'd程序的一系列输出。
答案 2 :(得分:1)
这是一个简单的功能,使用系统/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;
}
答案 3 :(得分:1)
在UNIX操作系统上查找IP地址的简单命令
ip route | grep src | awk -F 'src' '{print $NF; exit}' | awk '{print $1}'
在RHEL / CentOS / OEL / Ubuntu / Fedora上测试
答案 4 :(得分:0)
$_SERVER['REMOTE_ADDR'];
应该做到这一点。
如果这不起作用,你可以随时使用shell_exec($command);
。但请记住,您需要设置您的php文件权限才能执行。
答案 5 :(得分:0)
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;
答案 6 :(得分:0)
好的,我找到了解决方案......
Bubba - &gt;您的解决方案返回127.0.0.1地址。该框的域名是demo01.com,看起来它正在用它拉出本地127地址。我尝试使用该计算机上的Web浏览器调用php文件以及使用实际192.168.x地址的另一台计算机上的浏览器,它两次都给了我127.0.0.1地址。
Paulina - &gt; 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 - &gt;你的解决方案对我有用。我不知道我需要将第二个变量添加到调用中以使其显示所有内容。我可以从那里解析出IP地址。这只是为了设置信息亭的人显示,如果由于某种原因有多个地址,我可以将每个地址拉出来并显示列表,然后他们可以玩命中和错过,它只会是2他们可能不得不担心IP(lan和wan)
如果可以的话,我没有足够的果汁来反击你的反应。但我很感激,谢谢你!
Joren - &gt;这不能满足我的需求,remote_address返回调用脚本的计算机的地址。如果我从远程计算机上调用它,我将获得该计算机的IP,如果我从浏览器中调用它,我或者必须已经知道盒子的地址才能将它放在地址栏中(我不会# 39; t有,这就是我需要脚本的原因)或者从127.0.0.1或localhost调用它,在任何情况下我都得到127.0.0.1作为响应。
答案 7 :(得分:0)
如果您只想要特定的界面,可以使用此
$(document).ready(function () {
$("#connectLink")
.click(function () {
Trello.authorize({
type: "popup",
name: "from link test",
scope: {
read: true,
write: true},
success: function () {
onAuthorizeSuccessful();
},
error: function () {
onFailedAuthorization();
}
})
});
function onAuthorizeSuccessful() {
console.log("Authorization success.");
}
function onFailedAuthorization() {
console.log("Authorization failed.");
}
});
输出只是此接口的IP
答案 8 :(得分:0)
你可以使用我写的这个库。它可以读/写/ 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();
答案 9 :(得分:0)
编辑/ etc / sudoers以允许www-data执行任何命令
ini php代码:
$output = shell_exec("sudo ifconfig");
echo "<pre>$output</pre>";
答案 10 :(得分:0)
如果有多个网络适配器,则按矩阵顺序执行数据通信。
请参阅以下有关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
)
)