REMOTE_ADDR not working - php

I have a wierd problem. Whatever i do, the IP is the server's IP, not the client / the visitor. What to do?
if(isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARTDED_FOR'] != '') {
$ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$ip_address = $_SERVER['REMOTE_ADDR'];
}
return $ip_address;
}

You may need to switch to another server software (depending on what you're using now)
From the PHP docs:
$_SERVER is an array containing information such as headers, paths, and script locations. The entries in this array are created by the web server. There is no guarantee that every web server will provide any of these; servers may omit some, or provide others not listed here. That said, a large number of these variables are accounted for in the ยป CGI/1.1 specification, so you should be able to expect those.
REMOTE_ADDR is in the CGI/1.1 specification though so it's odd that whatever server you're using wouldn't be returning it.

If your server is on the same network as your server, behind a router with NAT, then you might see your private IP.
If you are behind a reverse proxy $_SERVER['REMOTE_ADDR']; will always be the IP of the proxy server.

Your webserver is not configured properly (once I've had this issue on buying alias domains at my webhost provider).
However if you're unable to fix this problem, I HIGLY recommend you to check if $_SERVER['HTTP_X_FORWARDED_FOR'] is valid IP address and then just assing it to $_SERVER['REMOTE_ADDR'] for simply usage, because It is easy to fake $_SERVER['HTTP_X_FORWARDED_FOR'] and to throw there your own values (I had this problem).

Related

PHP - check if domain matches server's IP when domain's IP is dedicated

I have a remote login script that user hosts (runs) on his server. During registration, user needs to specify a domain he will login from. When user runs script on his domain and logins to my server for the 1st time, I log his IP using:
$ip_address = $_SERVER['REMOTE_ADDR'];
When user logins 2nd time, I check if his IP address is still the same (using the same function above). Then I check if he still uses the same domain using:
$domain = $_SERVER['HTTP_REFERER'];
Finally, besides other security checks, I also check if specified domain really points to IP address using:
$domain_ips_array = gethostbynamel($domain);
if (in_array($ip_address, $domain_ips_array)) {
echo "Wonderful, domain really points to this IP";
}
But there's a problem when domain points to a dedicated IP. For example, if server's IP (where script is actually hosted) is 1.1.1.1 (this IP is also returned by $_SERVER['REMOTE_ADDR']), but domain is configured to use a dedicated IP 1.1.1.2, gethostbynamel function will only return 1.1.1.2, and check will fail (even if domain is actually hosted on server with IP address 1.1.1.1).
How do I solve this issue? Put simply, I need to be sure that user always runs the script on the same IP/domain, and if any of these is changed, alert is displayed.
I think you have a better luck with refactoring a little bit of the script you send to the user.
For example when a first login comes along, you can see the IP from the requested server.
Do your magic and return the IP to your script. Then store it somewhere and always send it after that.
This way you will always have the first IP. And then check with the $_SERVER variable. Domains can be changed and I think it's not that reliable.
Said it more simple, you need to have it stored somewhere.
-EDIT
You can use the function gethostbyaddr.
This will return you the domain of the IP. So you can store the domain from the first request as well and then check it with every other.

Which is more reliable gethostbyaddr($_SERVER['REMOTE_ADDR']) or $_SERVER['REMOTE_HOST']

I have to get the remote url hostname from the server script, which one of the following is more reliable:
gethostbyaddr($_SERVER['REMOTE_ADDR']) or $_SERVER['REMOTE_HOST']
This has nothing to do with reliability. Both variables are just not the same although they may contain the same value under certain circumstances. Let me explain:
$_SERVER['REMOTE_ADDR']
will in all cases contain the IP address of the remote host, where
$_SERVER['REMOTE_HOST']
will contain the DNS hostname, if DNS resolution is enabled (if the HostnameLookups Apache directive is set to On, thanks #Pekka). If it is disabled, then $_SERVER['REMOTE_HOST'] will contain the IP address, and this is what you might have observed.
Your code should look like:
$host = $_SERVER['REMOTE_HOST'];
// if both are the same, HostnameLookups seems to be disabled.
if($host === $_SERVER['REMOTE_ADDR']) {
// get the host name per dns call
$host = gethostbyaddr($_SERVER['REMOTE_ADDR'])
}
Note: If you can control the apache directive, I would advice you to turn it off for performance reasons and get the host name - only if you need it - using gethostbyaddr()
$_SERVER['REMOTE_HOST'] will only be set if the HostnameLookups Apache directive is set to On.
You could check for $_SERVER['REMOTE_HOST'] first, and if it's not set, do a hostname lookup.
Both are likely to be equally reliable, as they will use the same lookup mechanism internally. For the general reliability of this information, see Reliability of PHP'S $_SERVER['REMOTE_ADDR']
Be aware that hostname lookups can be very slow. Don't do them unless you have a really good reason.

Setting $_SERVER['REMOTE_ADDR'] to fake IP address

I am mediating requests from client A to server B. Client A may be a phone or a laptop computer. Server B wants to know client A's IP address, but they are looking for it in $_SERVER['REMOTE_ADDR']. Because I am hitting server B, they are getting the "wrong" value for $_SERVER['REMOTE_ADDR'] -- they're getting my servers' IP addresses. What can I do on my side so that server B will see the client's IP address when they access $_SERVER['REMOTE_ADDR'] at their endpoint?
This is happening at a layer that cannot be overridden by your PHP script. The X-Forwarded-For header exists to relay the true client IP, but the remote server must support this easily-spoofed value.
$header = "X-Forwarded-For: {$_SERVER['REMOTE_ADDR']}, {$_SERVER['SERVER_ADDR']}";
curl_setopt($curl_handle, CURLOPT_HTTPHEADER, array($header));
EDIT: Prior answer is perfect. This only applies where your own dev-ip is interfering with client stats.
In the absence of more info, at the most basic level, you should remove your own 'developer IP' so that you're not included in any stats/data/logs...
Your IP may be different to the server in question:
<?php
$dev_ip = '217.12.14.14' // your dev IP address
if ($_SERVER['REMOTE_ADDR'] == $dev_ip){
// do nothing
} else {
// do|show|log something
}
This doesn't account for dynamic IP address allocation (rather than a static IP). Dynamic IP's are often allocated by ISPs which is something that causes further issues.

$_SERVER["REMOTE_ADDR"] gives server IP rather than visitor IP

I'm trying to track IP addresses of visitors. When using $_SERVER["REMOTE_ADDR"], I get the server's IP address rather than the visitor's. I tried this on multiple machines at multiple locations and they all resulted in the exact same IP. Is there some PHP/server settings that could be affecting this?
When using $_SERVER["REMOTE_ADDR"], I get the server's IP address rather than the visitor's.
Then something is wrong, or odd, with your configuration.
Are you using some sort of reverse proxy? In that case, #simshaun's suggestion may work.
Do you have anything else out of the ordinary in your web server config?
Can you show the PHP code you are using?
Can you show what the address looks like. Is it a local one, or a Internet address?
$_SERVER['REMOTE_ADDR'] gives the IP address from which the request was sent to the web server. This is typically the visitor's address, but in your case, it sounds like there is some kind of proxy sitting right before the web server that intercepts the requests, hence to the web server it appears as though the requests are originating from there.
Look no more for IP addresses not being set in the expected header. Just do the following to inspect the whole server variables and figure out which one is suitable for your case:
print_r($_SERVER);
if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
$IP = $_SERVER['HTTP_CLIENT_IP'];
} else if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
$IP = $_SERVER['HTTP_X_FORWARDED_FOR'];
} else {
$IP = $_SERVER['REMOTE_ADDR'];
}
Replacing:
$_SERVER["REMOTE_ADDR"];
With:
$_SERVER["HTTP_X_REAL_IP"];
Worked for me.
Try this
$_SERVER['HTTP_CF_CONNECTING_IP'];
instead of
$_SERVER["REMOTE_ADDR"];
If you are using Cloudflare then this is always the Cloudflare IP address from the node which is serving you.
In this case you get the real IP address from the $_SERVER['HTTP_FORWARDED_FOR'] entry as described in the the other answers.
if your site is behind cloudflare, you can use another header provided by cloudflare itself:
$_SERVER['HTTP_CF_CONNECTING_IP']
or if you are using Laravel
$request->server('HTTP_CF_CONNECTING_IP');
read more about it here:
How to get real client IP behind Cloudflare in Laravel / PHP
#php 7.x short condition syntax.
<?php
$ip = isset($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : (isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']);
echo "The user IP Address is - ". $ip;
?>
from https://www.delftstack.com/howto/php/php-get-user-ip/
Enable remoteIP module in your Apache server
a2enmod remoteip
Restart Apache: /etc/init.d/apache2 restart

Get the client's computer name

I am getting the client's (website user's) IP address. Now I'd like to go one step further by knowing the user's computer name. So far, my research has not turned up anything to aid me in retrieving this information.
Is it possible to use the user's IP address, or some other means, to get my visitor's computer name using PHP?
PHP 5.4+
gethostbyaddr($_SERVER['REMOTE_ADDR'])
You can perform a reverse DNS lookup using gethostbyaddr().
Note that this will give you the name of the host the request came from according to reverse DNS.
It will not give you a result if reverse DNS isn't set up
It will not give you the Windows name of the computer
It will give you the name of the router if NAT is involved or proxy if a proxy is involved.
Not possible with plain php running on the server. It'd be a security/privacy issue to know details of the client such as computer name, mac address, contents of his drive.
You need some sort of application running on the client's machine in order to get this.
If you're referring to the hostname (displayed for instance by the hostname command on linux) of the computer doing the request:
That information is not included in an HTTP request. (That is, it's impossible for PHP to figure out.)
You could do a reverse DNS lookup, but that's probably not what you want anyway.
This is all that you could get using just PHP (you may try these butIi dont think this is what you actually needed):
gethostname()
gethostbyname(gethostname())
$_SERVER['HTTP_HOST']
$_SERVER['SERVER_SIGNATURE']
$_SERVER['SERVER_NAME']
$_SERVER['SERVER_ADDR']
$_SERVER['SERVER_PORT']
$_SERVER['REMOTE_ADDR']
gethostbyaddr($_SERVER['REMOTE_ADDR'])
php_uname()
The only thing you could do is try to get a DNS name for the client. "Computer Name" is a Windows made-up thing. Just call the built-in function gethostbyaddr() with the client's IP address. However, it won't always (hardly ever) work.
You can do this by
$_SERVER['REMOTE_HOST']
'REMOTE_HOST' - The Host name from which the user is viewing the current page. The reverse dns lookup is based off the REMOTE_ADDR of the user.
Note: Your web server must be configured to create this variable. For example in Apache you'll need HostnameLookups On inside httpd.conf for it to exist. As David mentioned you can also use . gethostbyaddr()
Pls go thru all the comments in the
url before actually using the
function.
Do something lik this:
<?php
//get host by name
echo gethostname();
echo "<br>";
//get OS
echo php_uname();
?>

Categories