php blocking visitors based on text list of ips

1.5k views Asked by At

I'm trying to write a SIMPLE generic block of PHP include code that will read a text file to fill an array of IPs, then use that array to compare a visitors IP to determine if it should end display of the page, blocking that page or site. This code also drops a log line to a 403 file and then sends the loser (user) to view it, ending their visit to the site. the line appends their info to the end of the open ended 403 file.

The include can be put in anywhere you don't want that list of IPs to see. The problem is I'm a hopeless hack, and don't have a good grasp on these loops and the syntax. can you help me sort this out? it seems to read the IP list ok, but then the while loop seems to be wrong. I could prolly simplify this more. but I'm not sure what the issue is.. My choice of variable names... maybe.

<? 
$IP = $_SERVER['REMOTE_ADDR'];


        $link_file = "bannedips.dat";
        $lines = file($link_file);

        foreach($lines as $line){
            if(!empty($line)){
                $line_array = explode(',', $line);
                $bannedip = trim(trim(strip_tags($line_array[0]), "\x00..\x1F"));
            }
        }



while $bannedip if ((substr($IP,0,10) == $bannedip) {
$line = date('Y-m-d H:i:s') . " - <b>$IP</b><br>\n";

file_put_contents('403.shtml', $line . PHP_EOL, FILE_APPEND);
header('Location: 403.shtml');
die();
}
?>
2

There are 2 answers

14
Nigel Ren On BEST ANSWER

You could build up an array of the banned IP's from the file (you are just overwriting the last one in your code, use $bannedip[] to add it to a list) and then use in_array() to check the users IP against this list...

$link_file = "bannedips.dat";
$lines = file($link_file);
$bannedip = [];   // Create start array
foreach($lines as $line){
    if(!empty($line)){
        $line_array = explode(',', $line);
        $bannedip[] = trim(trim(strip_tags($line_array[0]), "\x00..\x1F"));
    }
}
if(in_array($IP, $bannedip )) {
    $line = date('Y-m-d H:i:s') . " - <b>$IP</b><br>\n";
    file_put_contents('403.shtml', $line . PHP_EOL, FILE_APPEND);
    header('Location: 403.shtml');
    die();
}

There may be a tidier way of dealing with the input file, but without knowing the format it's difficult to say, so I've left your code as it was.

Update:

If you banned IP file is just a list of IP addresses, you could replace the load and foreach with...

$bannedip = file($link_file, FILE_IGNORE_NEW_LINES);
$bannedip = array_filter($bannedip);

Update2: As you seem to have sorted this out yourself, but posted a sample of the actual file format you have, thought I would add how it could be done...

$IP= "31.130.4.241";
$link_file = "bannedips.dat";
$bannedip = file($link_file, FILE_IGNORE_NEW_LINES);
$bannedip = array_map("str_getcsv", $bannedip);
$bannedip = array_column($bannedip, null, 0);
if(isset($bannedip[$IP])) {
    $line = date('Y-m-d H:i:s') . " - <b>{$bannedip[$IP][0]}</b> - {$bannedip[$IP][1]} - {$bannedip[$IP][2]}<br>\n";
    file_put_contents('403.shtml', $line . PHP_EOL, FILE_APPEND);
    header('Location: 403.shtml');
    die();
}
0
Neil Patterson On

The original goal was write a short piece of INCLUDE code that would parse a text file, find a matching IP, log the info, and drop the spamming jerk to a 403 page. this way, an offending user COULD visit any page, except ones that included this piece of script. Very selective blocking.

Here is my final code:

  <? 
    $IP = $_SERVER['REMOTE_ADDR'];
    echo $IP;
    $link_file = "bannedips.dat";
    $lines = file($link_file);

            foreach($lines as $line){
                if(!empty($line)){
                    $line_array = explode(',', $line);
                    $inputip = trim(trim(strip_tags($line_array[0]), "\x00..\x1F"));
                    $website = trim(trim(strip_tags($line_array[1]), "\x00..\x1F"));
                    $email = trim(trim(strip_tags($line_array[2]), "\x00..\x1F"));

                    if($IP == $inputip) {
                        $line = date('Y-m-d H:i:s') . " - <b>$inputip</b> - $website - $email<br>\n";
                        file_put_contents('403.shtml', $line . PHP_EOL, FILE_APPEND);
                        header('Location: 403.shtml');
                        die();
                    }
                }
            }
    ?>

The data file format is as follows:

23.105.159.238,penilengorgement.com,[email protected]
31.130.4.240,scamtown.com,[email protected]

so, now as I ban IPs (spammers), it pulls their info from my blog, and drops it into the linkfile, where it can be parsed and used to log repeat offenders and offer them an alternative to trying to get into my site, by offering them a list of their peers.