Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Retrieve real IP of user using codeigniter

My app tracks the IP address of users logging into the site. The tracking was working fine on a regular web server (we were on hostgator) but seemed to start tracking odd IP addresses when we switch to a PaaS platform (pagodabox) After speaking to pagodabox support they informed me that the IPs codeigniter was picking up was the IPs of the load balancers/routers of pagodabox and to get a user's actual IP address I would have to utilize HTTP_X_FORWARDED_FOR

I was using codeigniter's input class function $this->input->ip_address() to retreive the user's IP. I looked at the function and noticed they had some sort of features to retreive the HTTP_X_FORWARDED_FOR IP value but I am not sure how to use it. Do i have to change/add something in the config?

EDIT: After a few users have pointed out where I should add in the list of IP addresses of load balancers a new question came up: What would I do if the list of IP's change frequently? (ie no static IP, all dynamic)

like image 804
Zaki Aziz Avatar asked Jan 23 '13 23:01

Zaki Aziz


3 Answers

I'm sure you've resolved this by now, but I thought I would post the correct answer for future reference. I came across this same problem (Using load balancers on AWS with a CodeIgniter app.) As you pointed out, it's easy enough to get the correct IP behind a load balancer or other distributed environment using the HTTP_X_FORWARDED_FOR header. The problem is how do we correctly implement this solution in CodeIgniter? As the previous answer points out: Write your own IP function. The problem with this, is what if ip_address() is called throughout your app? Wouldn't it be better to override that function (With one that looks at the correct header)? CodeIgniter has a convenient mechanism for this, which is handy:

The solution is to extend the CodeIgniter Input class, by creating a new class file in /application/core called MY_Input.php (MY_ is a configurable prefix for extensions, you can change it in your config file). With extensions, you can create a function of the SAME name as the original class method without breaking anything, and without editing core files. CodeIgniter will just use your new method instead. Your extended input class will look something like this:

class MY_Input extends CI_Input {

    function __construct()
    {
        parent::__construct();
    }
    //Overide ip_address() with your own function
    function ip_address() 
    {
        //Obtain the IP address however you'd like, you may want to do additional validation, etc..
        $correct_ip_address = $_SERVER['HTTP_X_FORWARDED_FOR'];  
        return $correct_ip_address;
    }
}

This way we've changed the core behavior without hacking the framework, and existing calls to ip_address() throughout your app will now be using your method.

With regards to dealing with other IP's in the chain, if you're only interested in the client IP, it shouldn't matter. With AWS load balancers at least, the HTTP_X_FORWARDED_FOR header seems to always contain the correct client IP.

like image 110
Oliver Holmberg Avatar answered Oct 16 '22 03:10

Oliver Holmberg


Oliver's solution works, but in some circumstances, it is better to use the following if you know the proxy IP addresses that are in use. Edit your application/config/config.php file to include the following:

$config['proxy_ips'] = '1.2.3.4, 2.3.4.5';

Also be aware of the fact that the header information is usually unreliable and should not be used for security sensitive purposes. For example, it is not uncommon to restrict admin users to use only some white listed IP addresses.

like image 9
Thava Avatar answered Oct 16 '22 03:10

Thava


<?php 
function getIPfromXForwarded() 
{ 
    $ipString = @getenv("HTTP_X_FORWARDED_FOR"); 
    $addr     = explode(",",$ipString); 

    return $addr[sizeof($addr)-1]; 
} 
?> 

Try something like that. See if it works. Usage:

<? echo getIPfromXForwarded(); ?>
like image 3
edwardmp Avatar answered Oct 16 '22 04:10

edwardmp