...and general pests, by IP address block
Introduction
Being fundamentally fed up with spam Referrers, I wanted a quick and easy way to ban entire blocks of IP addresses inside PhpWiki. My requirements were simple:
- No database tables (I'm not going to waste time doing a query for these clowns)
- Instantly editable with vim over SSH
- Short and efficient, so that it can be included from all my PHP code
- Support for IP network masks or ranges
- Support for custom messages indicating the reason of the ban
I soon gave up trying to match substrings inside URLs and trying to prevent access before the fact - it would be extremely slow and require far too much effort.
The Code
Without further ado, here it is:
// Check if a given IP address is inside a given subnetfunction in_subnet($network, $mask, $ip) { $ip_long=ip2long($ip); $network_long=ip2long($network); $mask_long=ip2long($mask); if( ( $ip_long & $mask_long) == ($network_long & $mask_long)) { return true; } else { return false; }}// The bozos (in vim, just "/bozo" to get here)$aBanned = array( array( 'ip' => "69.57.152.89", 'mask' => "255.255.255.255", 'reason' => "Referral spamming with URLs to spam services and porn sites" ), array( 'ip' => "193.55.220.0", 'mask' => "255.255.255.0", 'reason' => "Referral spamming with drug advertising" ));// inline code (this gets executed by whoever includes this file)foreach( $aBanned as $aCheck ) { if( in_subnet( $aCheck['ip'], $aCheck['mask'], $_SERVER['REMOTE_ADDR'] ) ) { header( "HTTP/1.1 403 Access Denied" ); echo( "<H1>You Are Banned From Accessing This Site</H1>"); echo( "<p><b>Reason:</b> " . $aCheck['reason'] . "</p>" ); echo( "<p>I am in the process of reporting this abuse to your ISP or netblock owner" ); echo(" - on the Internet, nobody is really anonymous.</p>" ); // log this so we can grep it out of error_log error_log( strftime("%d/%b/%Y:%H:%M:%S") . " [BANNED] " . $aCheck['ip'] . " " . $aCheck['reason'] ); exit; }}
