Page 1 of 1
[SOLVED] How do you fetch server IP?
Posted: Thu Dec 29, 2005 10:52 pm
by heiatufte
Hi,
This is probably simple,
How do you get the server IP with PHP?
$_SERVER['SERVER_ADDR'] only gives the LAN ip

Posted: Thu Dec 29, 2005 11:00 pm
by Burrito
Posted: Thu Dec 29, 2005 11:10 pm
by josh
I actually have a thread open related to this, burrito the $_SERVER superglobal does not show the server's IP if it is on a LAN, rather it shows the internal (192.168.XX.XXX)
viewtopic.php?t=42317
Re: How do you fetch server IP?
Posted: Fri Dec 30, 2005 6:57 am
by Roja
heiatufte wrote:Hi,
This is probably simple,
How do you get the server IP with PHP?
$_SERVER['SERVER_ADDR'] only gives the LAN ip

It entirely depends on how you have your server setup.
For example, I have a development server that sits on both a local network, and an external network. It could have a 192.* address, or a 24.* address. If I echo server_addr, it says 24.*.
You can address your problem a few different ways. You can change the listen directive in your httpd.conf:
Code: Select all
# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, in addition to the default. See also the <VirtualHost>
# directive.
#
# Change this to Listen on specific IP addresses as shown below to
# prevent Apache from glomming onto all bound IP addresses (0.0.0.0)
#
#Listen 12.34.56.78:80
Listen 24.24.24.24:80
That way you explicitly set the external IP address as the only address it listens on. Doing so is rather brittle however - if your external address changes (dhcp), it will no longer work.
You can also try simply using the dns name, and using a service like DynDns, which updates the dns pointers for that machine whenever the ip address changes.
It all boils down to it not really being an Apache problem, so much as a server setup problem. If your server has a reasonable IP/DNS setup, Apache will usually do the right thing. Of course, getting a reasonable IP/DNS setup can take a little work.
Posted: Fri Dec 30, 2005 7:45 am
by Chris Corbyn
If you're on a linux server you could get it from the shell. Untested.
Code: Select all
$device = 'eth0';
$expression = '/^'.$device.'.*?inet addr:([\d\.]+)/ism';
preg_match($expression, `ifconfig $device`, $matches);
echo $matches[1];
EDIT | Tested (I was curious)
Code: Select all
d11wtq@d11wtq d11wtq $ php test.php
212.69.XX.XXX
EDIT AGAIN (Man I'm bored)
Code: Select all
//This could potentially be very insecure
//Fetches the IP address of eth0 or any given device
// returns false on failure
function get_server_ip($device='eth0')
{
if (preg_match('/[^\w-]/', $device)) return false; //For security
$expression = '/^'.$device.'.*?inet addr:([\d\.]+)/ism';
preg_match($expression, `/sbin/ifconfig $device`, $matches);
if (!empty($matches[1])) return $matches[1];
else return false;
}
Posted: Fri Dec 30, 2005 9:41 am
by josh
thanks d11 that worked well,
the secure way to do it was
it doesn't really matter what you pass to ifconfig to my knowledge, so long as they don't "inject" any other commands (just like anything else that uses the shell), but then again this function is meant to be used internally from the application anyways.. unless you expect your developers to be rooting your box, it shouldn't even matter that much
if you were accepting user input or something and you only wanted to let them look at the eth ports you'd of course want to
preg_match('#^(eth[0-9])$#', $device);
or something like that
Posted: Fri Dec 30, 2005 11:39 am
by heiatufte
Roja, are you sure?

As you mention, my IP changes rather frequently, so I can't change the listen directive to an IP, and I want the IP and not a dns name.
As for d11's suggestion: yeah it's a linux box (FC3). I've managed to setup apache, php and mysql on it but other than that I don't have much experience with linux (unfortunately; I'm learning

)
Anyway, your code doesn't work with me, it returns my LAN IP 192.168.x.x !
All computers are connected to a router, which is connected to the ADSL box, a not so uncommon setup. But I still need my external IP!
For the record, I have also access to a server located outside my LAN. Perhaps I could use that server to create a page which returns the remote IP, and then use MY server to fetch it from there? That would perhaps not be the best, but a possible, solution...
Posted: Fri Dec 30, 2005 8:13 pm
by Chris Corbyn
jshpro2 wrote:thanks d11 that worked well,
the secure way to do it was
Handy to know
jshpro2 wrote:
it doesn't really matter what you pass to ifconfig to my knowledge, so long as they don't "inject" any other commands (just like anything else that uses the shell), but then again this function is meant to be used internally from the application anyways.. unless you expect your developers to be rooting your box, it shouldn't even matter that much
I really wouldn't want to be help responsible if someone on a shared server started fiddling with ifconfig... there's the potential there to change the both the MAC and the IP of the interface.... that's more down to the security of the *nix machine itself granted but all the same it never hurts to validate user (or developer) input
heiatufte wrote:
As for d11's suggestion: yeah it's a linux box (FC3). I've managed to setup apache, php and mysql on it but other than that I don't have much experience with linux (unfortunately; I'm learning Wink)
Anyway, your code doesn't work with me, it returns my LAN IP 192.168.x.x !
All computers are connected to a router, which is connected to the ADSL box, a not so uncommon setup. But I still need my external IP!
For the record, I have also access to a server located outside my LAN. Perhaps I could use that server to create a page which returns the remote IP, and then use MY server to fetch it from there? That would perhaps not be the best, but a possible, solution...
If you have a domain name you could always try using the function
gethostbyname() with your fully qualified domain name as the input

Posted: Fri Dec 30, 2005 11:24 pm
by josh
gethostbyname() would work... but you'd have to have a service like no-ip that is updating your DNS when your IP changes.. but then again if the no-ip software is able to read out your ext. IP your script should..
I think the only 100% reliable way is have a script in a remote location that just sends back the $_SERVER['REMOTE_ADDR'], and call it from your script, and cache the data for say... 1 hour or something so you're not hammering that script.
Posted: Mon Jan 02, 2006 8:57 am
by heiatufte
gethostbyname() worked fine

Of course, if you
know that your users has connected via the domain name, you could also use gethostbyname($_SERVER['HTTP_HOST']).
I don't know how no-ip works but I know that
dyndns will let you download
DynDns Updater which somehow resolves your IP address whenever it changes and automatically updates the dns.
jshpro2 you won't even need to have that script on a remote location, just a seperate file on the same server, it's the server which visites the file anyway

that was my solution until now.
And nice thinking about the caching, anyhow my site hasn't got so many visitors so hammering would not be a problem

I think I'll prefer using the gethostbyname() because if the user can see my site, it means that my dns has updated and points towards the right IP so gethostbyname() would definetly work. The other idea
could potentially give the wrong IP, in case it hasn't updated yet. I'd rather look at the gethostbyname() solution as 100% reliable, but anyway that's just my opinion
Thanks for the help everyone!