Search code examples
phpwhile-loopip-blocking

php blocking visitors based on text list of ips


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();
}
?>

Solution

  • 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();
    }