2

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.

Pradeepb
  • 2,564
  • 3
  • 25
  • 46

1 Answers1

1

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.

John Hanley
  • 74,467
  • 6
  • 95
  • 159
  • Thanks John for your reply. I took the code from some blog so I was not entirely sure in which order i should put them. And regarding load balancer, I will surely check that. FORWARDED_FOR means are you referring to HTTP_X_FORWARDED_FOR ? – Pradeepb Sep 06 '18 at 14:38
  • Yes, for AWS services it is HTTP_X_FORWARDED_FOR. However, check the documentation for the services that you are using as you did not specify this in your question. – John Hanley Sep 06 '18 at 14:41
  • ok sure. I did not mention it as I dont have access to that :D but soon I will get to know about it. Thanks for the headsup. – Pradeepb Sep 06 '18 at 14:42
  • @Pradeepb Also note that `$_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. – John Hanley Sep 06 '18 at 14:45
  • ah ok. Thats a good info. May be you can add it to your answer as others who is looking can easily find it useful. :) – Pradeepb Sep 06 '18 at 14:47