Fix CodeIgniter IP address detection on lighttpd
If the results of a call to $this->input->ip_address() gives you "0.0.0.0" (the "invalid address" response) and you're running lighttpd as your web server, you may be able to fix it with a minor tweak to by extending one of the base CodeIgniter libraries. An IPv6-style header is being appended to the IPv4 address, most likely, and stripping it out before CodeIgniter considers the validity of your address should restore functionality without circumventing any of the logic.
Crack open the system/libraries/Input.php file and find the following code:
PHP code:
if (!$this->valid_ip($this->ip_address))]
…and replace it with this:
PHP code:
$this->ip_address = preg_replace("#^[:a-z0-9]+:#i", "", $this->ip_address);
if (!$this->valid_ip($this->ip_address))
Update Jump to heading
As mentioned in Anthony's comment below, this edit requires that you modify a core CodeIgniter library. In order to avoid this, you can create a class definition in system/application/libraries/Input.php that extends the functionality of the valid_ip() function (which is used internally by $this->input->ip_address()). He has been so kind as to provide a class-encapsulated version of my snippet on github which does just that. Thanks, Anthony!
Here is the updated code:
PHP code:
<?php if (! defined('BASEPATH')) exit('No direct script access allowed');
require_once(BASEPATH.'/libraries/Input.php');
/**
* Input Class Override
*
* Pre-processes global input data for security
*
* @package CodeIgniter
* @subpackage Libraries
* @category Input
* @author haliphax / ExpressionEngine Dev Team
* @link https://codeigniter.com/user_guide/libraries/input.html
*/
class Input extends CI_Input
{
function Input()
{
parent::CI_Input();
}
/**
* Validate IP Address
*
* Updated version suggested by Geert De Deckere
*
* @access public
* @param string
* @return string
* @see https://haliphax.dev/2010/10/fix-codeigniter-ip-address-detection-on-lighttpd/
*/
function valid_ip($ip)
{
$ip = preg_replace("/^[:a-z0-9]+:/i", "", $ip); // See the link in the @see declaration above for more info
$ip_segments = explode('.', $ip);
// Always 4 segments needed
if (count($ip_segments) != 4)
{
return FALSE;
}
// IP can not start with 0
if ($ip_segments[0][0] == '0')
{
return FALSE;
}
// Check each segment
foreach ($ip_segments as $segment)
{
// IP segments must be digits and can not be
// longer than 3 digits or greater then 255
if ($segment == '' || preg_match("/[^0-9]/", $segment) ||
$segment > 255 || strlen($segment) > 3)
{
return FALSE;
}
}
return TRUE;
}
}
If having "::ffff:" in front of your addresses was causing the problem, this snippet should have you back on your way juggling IP addresses in no time.
Posted: