Reputation: 2562
I am new to PHP and I am given a task to work on geolocation.
I want to get client_ip in my php application. The application is deployed on AWS and has 2 load balancers and apache web server.
I have tried following:
if (array_key_exists('HTTP_CLIENT_IP', $_SERVER)) {
$ipAddress = $_SERVER['HTTP_CLIENT_IP'];
} elseif (array_key_exists('HTTP_X_FORWARDED', $_SERVER)) {
$ipAddress = $_SERVER['HTTP_X_FORWARDED'];
} elseif (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
$ipAddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
} elseif (array_key_exists('HTTP_FORWARDED_FOR', $_SERVER)) {
$ipAddress = $_SERVER['HTTP_FORWARDED_FOR'];
} elseif (array_key_exists('HTTP_FORWARDED', $_SERVER)) {
$ipAddress = $_SERVER['HTTP_FORWARDED'];
} elseif (array_key_exists('REMOTE_ADDR', $_SERVER)) {
$ipAddress = $_SERVER['REMOTE_ADDR'];
} else {
$ipAddress = '';
}
I thought it would work but it did not. Then I looked into phpinfo and found the following:
In Headers
, X-Forwarded-For
is set to 10.1.29.16,
$_SERVER['HTTP_X_FORWARDED_FOR']
is set to 10.1.29.16 and
$_SERVER['REMOTE_ADDR']
is 172.17.7.173.
All are internal IP addresses.
Can anyone please guide me, how can I find real client's ip address?
PS: Its a Symfony 4 application.
Upvotes: 2
Views: 974
Reputation: 81416
You are checking the headers in the wrong order. Check the FORWARDED_FOR types first. You need to check the documentation for the servers (load balancers, etc.) in front of your instance to know what header to reference. HTTP_X_FORWARDED_FOR
is probably the most common. You are blindly checking anything.
You are assuming the the headers contain a single value. If there is a chain of servers then each one will add its address. An example would be Cloudfront with ALB.
The header $_SERVER['REMOTE_ADDR']
is not reliable and should not be trusted. Actually none of the headers should be trusted unless you control the entire chain (caching, load balancing, etc.). Forging these values is very easy.
Upvotes: 1