Latest TweetsPlugin update! Disable Gutenberg v1.5 adds whitelist options to always enable Block Editor on any post :) m0n.co/wpdg
Perishable Press

Automatic IP Blacklist

[ Automatic IP Blacklist ] Recently a reader going by the name of Rock Star sent me a cool little PHP script that automatically updates your site’s .htaccess with a current list of bad IP addresses. This is useful because it gives you better “real time” protection against attacks and malicious requests. This tutorial shares the code and explains how to implement in two easy steps.

Specific requirements: you will need access to the server to set up a cron job. Alternately, if you are using WordPress, you need a plugin or custom function to set up a WP Cron event.

Disclaimer: The script and technique provided in this article are intended to demonstrate concept and functionality. It is not meant to be used as-is on a live, production site. So be safe and have fun!

Step 1: Add PHP Script

To implement the automatic IP blacklist, first upload the script to your server. You can copy paste from the following code, or download a copy of the PHP script below. So without further ado, here is the Automatic IP Blacklist:

// Latest Blacklist IP file
$file 	= "https://myip.ms/files/blacklist/htaccess/latest_blacklist.txt";

// Latest Blacklist User Submitted IP 
// Optional, delete this variable $file2 if you don't need it
$file2 	= "https://myip.ms/files/blacklist/htaccess/latest_blacklist_users_submitted.txt";

// .htaccess apache file
$file3 = rtrim($_SERVER['DOCUMENT_ROOT'], "/ ")."/.htaccess";

// Separator
$line 	= "## BLACKLIST IP AUTO ADDED ##";

$data = @file_get_contents($file);
if ($data === false || !$data) die ("<font color='red'><b>Error!</b></font> No access to file: $file");

$htaccess = @file_get_contents($file3);
if ($htaccess === false) die ("<font color='red'><b>Error!</b></font> No access to file: $file3 in your website root directory. Please create this file or change file permissions if it exists");

$htaccess = trim($htaccess);
if (stripos($htaccess, $line) !== false) $htaccess = trim(substr($htaccess, 0, stripos($htaccess, $line)));
if (stripos($data, "# Copyright")) $data = substr($data, 0, strripos($data, "# Copyright")) . substr($data, strripos($data, "##############")+16);
$htaccess .= "\n\n\n" . $line . "\n\n" . $data;  

if (isset($file2) && $file2)
{
	$data2 = @file_get_contents($file2);
	if ($data2 === false || !$data2) die ("<font color='red'><b>Error!</b></font> No access to file: $file2");
	
	$data2 = substr($data2, strripos($data2, "##############"));
	$htaccess .= "\n\n" . $data2;
}

$htaccess = trim($htaccess) . "\n\n";


$res = file_put_contents($file3, $htaccess);

if ($res === false) die ("<font color='red'><b>Error!</b></font> Cannot write blacklist ip to file: $file3 in your website root directory. Please change file permissions to 0777 (command: chmod 0777 $file3)");
else die ("<font color='green'><b>File .htaccess successfully updated with new Myip.ms Blacklist IPs.</b></font><br>Date: " . date("r"));

Originally this script was written several years ago, but the code still is 100% solid and effective. It just works and is a really concise and elegant script.

No changes need to made, simply upload and then proceed to step 2 for the cron job. By itself this script doesn’t do anything. It needs to be called in order to lookup and grab the latest blocked IP addresses and update your site’s root .htaccess file. So technically you could just manually call the script via your browser every day, but that would be stupid when we can automate the process via simple cron command.

Important: Your site’s root .htaccess file must be writable by the server in order for this script to work. So make sure that the permissions are CHMOD as needed in your particular server environment.

Step 2: Cron Job

After uploading the automatic IP blacklist to your server, you need to set up a cron job to run the script every day or week or whatever you want. There are at least two ways to set up a cron job: directly via your server (or server control panel) OR using WordPress Cron API. Let’s look at an example of each.

Note: the examples below use 24 hours for the cron interval. Feel free to increase or decrease that time to whatever works best for you.

Linux/Unix Cron

Cron is a chronological scheduling service in Linux/Unix operating systems. Cron jobs (crontab commands) are used to execute commands or scripts periodically, at specified time intervals. In Linux/Unix, the cron service (daemon) runs in the background and constantly polls the /etc/crontab file, /var/spool/cron/, and /etc/cron./* directories.

A typical cron job that runs every 24 hours looks like this:

# [minute hour day month weekday] [resource] [command]
0 24 * * * /usr/bin/php /var/www/html/automatic-ip-blacklist.php

Without derailing into an in-depth tutorial on setting up cron jobs, suffice it to say that there are three thing you need to get right in order for this to work:

  • The time interval
  • The path to the resource (in this case, PHP)
  • The path the script (in this case, auto IP blacklist)

I can tell you from hard-earned experience that the tricky part to setting up cron jobs is getting the file paths correct. Once everything is setup, however, cron will not fail you. Check out this beginner’s guide for more information about setting up and configuring cron jobs. (Lots more great tutorials out there too).

WordPress Cron

Like Linux/Unix Cron, WP Cron enables us to perform time-based tasks at recurring intervals. Unlike Linux/Unix Cron, WP Cron is a pseudo cron service. Instead of running constantly, WP Cron runs only on page load. So when a page is loaded, WP Cron checks the queue of scheduled tasks and runs anything that is past the scheduled time. In most cases this pseudo approach works well; but for sites with little activity, the queue of scheduled events can build up.

Here is a super basic script for setting up a new WP Cron event:

function shapeSpace_wpcron_activation() {
	if (!wp_next_scheduled('auto_ip_blacklist')) {
		wp_schedule_event(time(), 'daily', 'auto_ip_blacklist');
	}
}
add_action('admin_init', 'shapeSpace_wpcron_activation');

function shapeSpace_auto_ip_blacklist() {
	if (!defined('DOING_CRON')) return;
	require_once('/path/to/automatic-ip-blacklist.php');
}
add_action('auto_ip_blacklist', 'shapeSpace_auto_ip_blacklist');

The only change that needs to be made: change the /path/to/ to match the actual path to the automatic-ip-blacklist.php. To add these two functions to WordPress, you can create a simple plugin (recommended) or add the code to your active theme’s functions.php.

Using WP Cron with HTTP Authentication? You need WP Cron HTTP Auth!

Testing

After implementing the automatic IP blacklist, you can verify that everything is working by simply keeping an eye on your site’s root .htaccess file. You should notice that the IP-blocking directives change every day.

So to test functionality while getting set up, you can decrease the time interval in your cron job to something like 5 minutes or whatever short duration. Then you can add a comment or empty line to the block-IP rules in your .htaccess file. Wait five or whatever minutes and then check to see if the comment or empty line is removed. If so, that means the blocked IP rules were successfully updated (and in the process your comment or blank line was overwritten/removed).

Download

Grab a copy of the automatic IP blacklist.

Automatic IP Blacklist – Version 1.0 (1 KB zip)

Jeff Starr
About the Author Jeff Starr = Designer. Developer. Producer. Writer. Editor. Etc.
Archives
7 responses
  1. Thanks for sharing, Jeff! I’ve always wondered what your thoughts are on so many IP blocks in htaccess slowing down the overall page load time.

    • Jeff Starr

      It really all depends on the environment, list size, rate of change, and so forth. In general it’s not a good idea, but it would be straighforward to tweak the IP method to look at any variables that make sense for the application.

  2. Marcus Downing December 3, 2018 @ 2:11 amReply ]

    The URL of the list in that script doesn’t include SSL. This is a vulnerability, as an attacker could intercept the page in transit and use it to inject bad content into your .htaccess file – for example, letting them bypass authentication.

    Luckily, it appears to work just fine if you swap http: to https:

  3. works ;)

  4. Hmmm!

    I’ll have see how well this may work with my custom firewall software. Have been very busy with “life”, lately, but still looking into designing a custom Cron-job for getting the current IP-blacklists.

    BTW:

    Still getting some great “intel” on some the latest attack attempts. A lot of “bot” activity!

    – Jim S.

    • Jeff Starr

      It’s fun to play with Cron jobs. Here is one I use to send an email listing any modified files on the server:

      find /your/path/to/httpdocs -type f -ctime -1 -exec ls -ls {} \; | mail -E -s "File Monitor Report" email@example.com

      And you are right about the increased bots. It’s a war zone these days. I am drowning in data lol. If I had time, I would deep dive into it, but like most others gotta pay da billz.

      P.S. More info on the Cron tip over at WP-Mix!

Drop a Comment  ]
RSS