2

I want to block some hostnames and ips from accessing my website, I use this codde to =block only one hostname or ip:

<?php
$hostname = gethostbyaddr($_SERVER['REMOTE_ADDR']);
$ipz = $_SERVER['REMOTE_ADDR'];
if ($hostname === "blocked hostname" || $ipz == "blokced ip" ){
echo "redirect to some url";
}
else {
echo "show site content";
}
?>

But I have a long list hof hostnames and IPs to be blocked, I want to add all those bad IPs and hostnames I have in a separated file, and then check if the visitors hostname or IP is on that list or not. how can I do that and keep to site loading fast ?

Thanks

Jawad Mira
  • 105
  • 9
  • If you have blocked ip's and host's in array, just do if stetment with in_array() function... – Glavić Sep 15 '12 at 14:09
  • could you please show me how? – Jawad Mira Sep 15 '12 at 14:16
  • Are you sure that this is the best way to go? My ISP uses DHCP so sometimes I get an ip address of the chap down the road! Is that fair? – Ed Heal Sep 15 '12 at 14:18
  • technicly I want to block proxy IPs and known bad hostnames , not to block regular ones – Jawad Mira Sep 15 '12 at 14:19
  • @JawadMira - but people can change their IP address or hostname at a flip of the switch - so the exercise is pointless. Get them to log in using https. Then you will know who(?) they are – Ed Heal Sep 15 '12 at 14:33
  • usualy dynamic IPs are not proxies, some visitors try to hide their real countris using proxy servers, those that I want to block – Jawad Mira Sep 15 '12 at 14:37
  • All my traffic goes thru a proxy. And it is dynamic. Just questioning the futility of embarking on this adventure. Perhaps supplying a username and password would be simpler? – Ed Heal Sep 15 '12 at 14:42
  • yes, I do have members area, but alos they could join from proxy! and hide their real country – Jawad Mira Sep 15 '12 at 14:44
  • @JawadMira - Does that matter that they hide their location? 'cos you have to maintain this database as to what are the dodgy hostnames/ips and what ones are no longer dodgy. Seems a lot of effort. – Ed Heal Sep 15 '12 at 14:53
  • yeah, but I'm getting lot of chinese ppl joining my site but using US proxies to see US content, witch is too bad for me – Jawad Mira Sep 15 '12 at 14:58
  • @JawadMira - Why is that bad? idiot - Chinese government are a bunch of a********* – Ed Heal Sep 15 '12 at 15:08

2 Answers2

2

First way, put all your ip in a single file, separated by a newline. Then, you'll do :

$ips = file("ips.txt", FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES);
if (in_array($hostname, $ips) || (in_array($ipz, $ips)) {
  // redirect to some content for banned guyz
  die();
}
// real things

If you need more info about file() flags, you can read this.

For security reasons, you may put your "ips.txt" file in a folder unavailable from the outside.

Second way, you have a sql table where all ips are stored :

require_once("config.php");
$dbh = new PDO("mysql:host={$host};dbname={$base}", $user, $password);
$hostname = gethostbyaddr($_SERVER['REMOTE_ADDR']);
$ipz = $_SERVER['REMOTE_ADDR'];
$sth = $dbh->prepare("select count(*) from banned_ips where ip IN (?, ?)");
$sth->execute(array($hostname, $ipz));
$count = $sth->fetchColumn();
if ($count > 0) {
    // do some stuffs with banned user
    die();
}
// do some stuffs with normal users
hjpotter92
  • 78,589
  • 36
  • 144
  • 183
Alain Tiemblo
  • 36,099
  • 17
  • 121
  • 153
  • in case the ips.txt file becomes very large, would that slow down the site? – Jawad Mira Sep 15 '12 at 15:14
  • I'm getting this error 'Call to a member function fetchColumn() on a non-object in /home/monk/public_html/prox.php on line 9' where that line is '$count = $sth->execute(array($hostname, $ipz))->fetchColumn();' – Jawad Mira Sep 15 '12 at 16:05
  • this indicate a mysql error: did you created the "banned_ips" table with a field "ip" where every ip are? did you changed user/password/host and db name? did you tried to display errors (`print_r($dbh->errorInfo());`) ? – Alain Tiemblo Sep 15 '12 at 16:29
  • remove the `->fetchColumn()` and use a `print_r($dbh->errorInfo());` to show and tell me what's wrong – Alain Tiemblo Sep 16 '12 at 03:59
  • I did those changes and now I'm getting this error Fatal error: Call to a member function print_r() on a non-object in /home/monk/public_html/prox.php on line 9 – Jawad Mira Sep 16 '12 at 08:12
  • `$count = $sth->execute(array($hostname, $ipz)); print_r($dbh->errorInfo());` – Alain Tiemblo Sep 16 '12 at 08:51
  • Okey, then, just after `$dbh = new PDO("mysql:host={$host};dbname={$base}", $user, $password);`, put ` $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);` you'll get an exception. – Alain Tiemblo Sep 16 '12 at 09:26
  • did that and still having this error: Fatal error: Call to a member function fetchColumn() on a non-object in , and the line is ' $count = $sth->execute(array($hostname, $ipz))->fetchColumn();' – Jawad Mira Sep 16 '12 at 11:32
  • Please try [this code](http://pastebin.com/egJ9EA3P) I can't explain myself easily on a comment field :-) – Alain Tiemblo Sep 16 '12 at 11:36
  • thanks you a lot, you was very helpfull, I did some searching and solved the problem before you comment, I also edited your answer with the final working code, again thank you – Jawad Mira Sep 16 '12 at 11:53
-1

I actually just implemented this feature last week into one of my sites. I have a MySQL Table with an IP column, and a reason column so both the user can see why their IP is banned, and whoever is able to edit/view the list.

$query = 'SELECT * FROM banned_ips';
$result = mysql_query($query);
while ($row = mysql_fetch_array($result)) {
$bannedips = array($row['ip']);
};
$ip=$_SERVER['REMOTE_ADDR'];

if (in_array($ip, $bannedips))
{
header('Location: some url');
};
bhooks
  • 409
  • 5
  • 16
  • so is it faster to handle it in php and mysql? or adding the bad ips/hostnames in separated file and including it in the script would be better? – Jawad Mira Sep 15 '12 at 14:12
  • 1
    why are you promoting `mysql_*` functions? – jeremy Sep 15 '12 at 14:12
  • @Nile I think it's easier to put it into MySQL so that you could always create an interface for people to use, instead of having a file that one person has access to – bhooks Sep 15 '12 at 14:23
  • @bhooks why not doing `SELECT COUNT(*) FROM banned_ips WHERE ip = '(some ip)'` and check if you have > 0 rows? your method is far from a nice solution – Alain Tiemblo Sep 15 '12 at 14:32
  • so witch way is faster? using file.txt to list bad ips/hots or using database ? just tru=ying to sue less resources and making the site load faster – Jawad Mira Sep 15 '12 at 14:34
  • @bhooks don't use `mysql_*` functions – jeremy Sep 15 '12 at 14:37
  • @Nile , what can we replace mysql_* by? – Jawad Mira Sep 15 '12 at 14:39