Actually I have no any practical experience using php other than in locally hosted server. I am following a video tutorial to learn php, and there was this code to block specific ip from a web site. The thing I want to know here if this is works for users who have dynamic ip addresses also or not? And, is this a proper way to block a user? I'm so glad if you can explain more about practical side of blocking users. Thank you!
<?php
$http_client_ip = $_SERVER['HTTP_CLIENT_IP'];
$http_x_forwarded_for = $SERVER['HTTP_X_FORWARDED_FOR'];
$remote_address = $SERVER['REMOTE_ADDR'];
if (!empty($http_client_ip)){
$ip_address = $http_client_ip;
} elseif (!empty($http_x_forwarded_for)) {
$ip_address = $http_x_forwarded_for;
} else {
$ip_address = $remote_address;
}
//block list contains all the IPs that should be blocked.
foreach ($block_list as $block) {
if ($block == $ip_address){
die();
}
}
?>
Visitors can be restricted from accessing your site by using the IP deny manager in your cPanel or by adding the Allow or Deny code in your .htaccess file.
The syntax is as follows:
Allows IP 122.102.1.2 access to your website.
Allow from 122.102.1.2
Denys IP 25.122.6.3 access to your website.
Deny from 25.122.6.3
both combined as,
Order deny,allow
Deny from all
Allow from 203.25.45.2
Deny from unwanted-domain.com
No it does not. It takes his IP and check if it is in the block list. As soon as it will change, he won't be blocked anymore.
You could try blocking a larger range of IP.
By example:
$targetAddr = "123.123..*..*"; //yes is two dots
//this code will match any class of 123.123.x.x,
//you can also do "123.123.123..*" to do anything that is 123.123.123.x
if (ereg($targetAddr, $_SERVER['REMOTE_ADDR'])) {
//remote address match, do something or don't do anything
} else {
//do whatever you want to address that doesn't match
}
To be honest I don't think this is the best way to block users. This could block other users than the one you are trying.
I guess this would be best for regional block, when you want to block your site from a certain geographical area, using the IP range assigned to that area. as goes for certain users with dynamic IP addresses, it won't work well.
Related
I'm trying to load content from a different page if the user came to the page with NO referrer or if the user types my page in directly.
This is the code I would like to alter to be able to achieve this.
The code below redirects based on if the user has 1 of the IPs listed below, it will load the fakepage.php. I would like to alter this script so it can work if there is NO referrer, or if the user types in my url directly.
<?php
$banned = array('56.150.186.229','89.103.221.49');
$userIP = $_SERVER['SERVER_ADDR'];
if(in_array($userIP,$banned)) {
include_once('fakepage.php');
} else {
include_once('realpage.php');
}
?>
I'm trying to make this look as seamless as possible, so the user will not know they were redirected
Use $_SERVER['REMOTE_ADDR'] to get the users ip (you may need another header if you are running behind a proxy or similar. Then check to see if $_SERVER['HTTP_REFERER'] is empty for your second condition.
$banned = array('56.150.186.229','89.103.221.49');
$userIP = $_SERVER['REMOTE_ADDR']; // likely users ip
$noReferer = empty($_SERVER['HTTP_REFERER']);
if(in_array($userIP,$banned) or $noReferer) {
include_once('fakepage.php');
} else {
include_once('realpage.php');
}
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)
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.
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.
<?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(); ?>
In your case, you can add specified Load-Balancer IP into $config['proxy_ips'] (application/config/config.php), for example:
$config['proxy_ips'] = ['192.168.1.2'];
Dynamic proxy IP:
According to your dynamic IP problem, you can mask the IP range for the Load-Balancer network, for example:
$config['proxy_ips'] = '192.168.1.0/24';
The mask function is able in Codeigniter 3
Get IP method:
$this->input->ip_address();
While $this refers to CI instance.
This method takes into account the $config['proxy_ips'] setting and will return the reported HTTP_X_FORWARDED_FOR, HTTP_CLIENT_IP, HTTP_X_CLIENT_IP or HTTP_X_CLUSTER_CLIENT_IP address for the allowed IP addresses.
I came across a version of Thava's solution that works great for situations where the load balancer IPs can change (such as AWS) and still leverages CIs configuration files natively. When you know you are running behind an LB you can modify config.php to be:
$config['proxy_ips'] = isset($_SERVER["REMOTE_ADDR"]) ? $_SERVER["REMOTE_ADDR"] : '';
Knowing that REMOTE_ADDR will always be the current LB.
Thanks to Eric Brown here https://expressionengine.com/forums/archive/topic/185751/amazon-load-balancing-and-codeigniter-configproxy_ips#925678
I know there is a good answer which is relevant to your question and is accepted by you but for future users I am sharing a function which is working perfectly for me in all situations.
public function ip()
{
$ipaddress = '';
if ($_SERVER['HTTP_CLIENT_IP'])
$ipaddress = $_SERVER['HTTP_CLIENT_IP'];
else if($_SERVER['HTTP_X_FORWARDED_FOR'])
$ipaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
else if($_SERVER['HTTP_X_FORWARDED'])
$ipaddress = $_SERVER['HTTP_X_FORWARDED'];
else if($_SERVER['HTTP_FORWARDED_FOR'])
$ipaddress = $_SERVER['HTTP_FORWARDED_FOR'];
else if($_SERVER['HTTP_FORWARDED'])
$ipaddress = $_SERVER['HTTP_FORWARDED'];
else if($_SERVER['REMOTE_ADDR'])
$ipaddress = $_SERVER['REMOTE_ADDR'];
else
$ipaddress = 'UNKNOWN';
echo $ipaddress ;
}
I had the same kind of situation at work, except that the IPs were not really 'dynamic', but the the 'infrastructure people' managing proxyies and load balancers used to change them for undisclosed reasons. So we had to negotiate and we came up with a solution setting up a hook in their configuration/provision management tool to write a config file somewhere (in a folder accessible to the user running our Apache/PHP).
So I used a CI hook to read that file on system bootstrap in order to change my apps config, updating values like the proxy IP list, cache path, cookie domain etc.
I am using this function to get ip address of the user in my site but it cant read ipaddress sometimes. I dont know that a user can hide the ipaddress or not ? If a user able to do so then how can i get the ipaddress or any other solution to identify the local computer of the user so i can prevent that computer to open my site.
Any suggestion would be greatly appreciated.
function GetIP()
{
if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))
$ip = getenv("HTTP_CLIENT_IP");
else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
$ip = getenv("HTTP_X_FORWARDED_FOR");
else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
$ip = getenv("REMOTE_ADDR");
else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
$ip = $_SERVER['REMOTE_ADDR'];
else
$ip = "unknown";
return($ip);
}
Thanks a lot.
Normally just echo $_SERVER['REMOTE_ADDR']; should do the job. Otherwise, explain us, what you mean with "it cant read ipaddress sometimes"
Ip addresses aren't a sure-fire way of banning users, since they can use Proxies, or can have a dynamic IP. For instance, for some users, banning the IP would just mean they'd have to restart their router and they can access your site again.
Depending on your site, a better way to deny someone access is to use user authentication (user login).
The short answer is that there is no 100% guaranteed way of getting a user's IP address - $_SERVER['REMOTE_ADDR'] is your best bet but even that's not 100% reliable - especially for users on networks.
Anything that's passed over HTTP from the client could be blocked/spoofed.
It's easier to work your problem the other way around - it's much easier (and more secure) to whitelist access rather than blacklist it - if you can work that way around, I'd go for it. It only requires something like a simple (in an Apache .htaccess or vhost configuration):
Deny from all
Allow from mydomain.com
the only IP address you can get from the environment is REMOTE_ADDR one.
The other silly strings in your code is no more than HTTP headers, optional ones. Can be faked, omitted, have wrong format, be empty etc.
I leave a conclusion for you to make.
I'm making a website that appeals to students at my school. I want to only allow access if the user is on the campus wifi or hardwire. Using PHP, how can I restrict access to people I am sure are on the campus internet?
You would need to get a range of IP addresses and put them in a while list. You could then use the $_SERVER['REMOTE_ADDR'] variable to check against the white list for access. Do it at the beginning of the page with something like this:
if(in_array($_SERVER['REMOTE_ADDR'],$white_list)) {
//allow execution code?
} else {
exit;
}
This is usually done in the webserver configuration, which has the advantage of also working for images, but in theory you could put
if ($_SERVER['REMOTE_ADDR'] != '...')
die();
in every of your PHP pages.
At first, you need to get the range of IPs from your school's network admin.
Then from PHP:
$ip=$_SERVER['REMOTE_ADDR'];
if(inRange($ip)) die();
else { ....
Now write inRange($ip) function to return true if the given ip is in the range. you can use explode function to get pieces of the ip to compare.. :)
It's already been mentioned, but the 'right' way to do it is to specify the IP range in the setup of your webserver (IOW, don't do it in PHP)
There are 2 different websites in 2 directories ..path/siteA/ and ..path/siteB/ . I need to load one of them on domain example.com depending on their country they are visiting from.
It can't be www.example.com/siteA it must be www.example.com .
Is it posible?
Edit: found the solution.
Configure Your webserver to listen on two different ports, one pourt should serve content from /path/siteA and the second one from /path/siteB.
Next step is to configure Pound depending on the location of the user (IP geolocalisation) and You're on Your way
It is usually done with geo-location.
You use a redirect on example.com/index.php that redirects to example.com/pathA or example.com/pathB depending on their ip
use the header() function to redirect :)
$ip = $_SERVER['REMOTE_ADDR'];
if(...) // check location of IP
{
header("Location: /pathA");
}
else
{
header("Location: /pathB");
}
http://php.net/manual/en/reserved.variables.server.php
http://au.php.net/manual/en/function.header.php
Edit:
Based on comment, this is what you need: mod_Rewrite: Filter specific pages by IP and redirect them
Yes it is possible. First pages you have to ask the language or show the default language.
This is done by two methods:
Each language can be lines or words assigned in separately files with each variables. By using the variable calling we can the get the language parameter.
Each language can be lines or words assigned in database with separately table.