CloudFlare Page Rules for WordPress Caching

CloudFlare only caches static content like css, jpg, etc. by default to enable faster load times for your site; however you can take advantage of Page Rules to make CloudFlare cache everything including the HTML. The problem with enabling this level of caching for WordPress is that it will cache:

  • The entire wp-admin section allowing a non-privileged user to load the admin site by typing in the URL
  • Preview URLs when you’re drafting a new page/post making it difficult to see your changes
  • wp-login.php getting you stuck in a redirect loop so you can’t login.

As a CloudFlare Free user, you will only have 3 Page Rules to work with; one will turn on caching of everything, leaving you with two rules to disable caching of the admin section, preview urls, and wp-login.php.

You could make a Page Rule with the pattern *domain.com/wp-* to prevent caching of both /wp-admin/ and wp-login.php; this leaves you with one rule left to prevent preview url caching with the pattern *domain.com/*preview=true*. However the pattern *domain.com/wp-* will also prevent caching of your static content since it matches the WordPress wp-content folder where most of it is located.

To solve this problem I used the WordPress plugin Rename wp-login.php to change my login URL to https://blog.thirdechelon.org/wp-admin[randomstring]/ – now you can prevent caching of the login page and admin sections with a single rule using pattern *domain.com/wp-admin* and you’ll still have two rules left to prevent caching of previews and to enable full caching of everything.

Below are the Page Rules I use for caching this blog (order matters); you’ll also want to install the WordPress Sunny Plugin to purge CloudFlare’s cache automatically when you make updates.

pagerule1pagerule2

CentOS MotD Generator

Recently a friend of mine showed me the cool MotD message he set up on his Ubuntu server that displays upon ssh login; it displays useful information such as OS & kernel version, uptime, system load, memory usage and other system stats. After some searching I found a MotD generator for CentOS here; it’s made up of two scripts: count_yum_updates.sh and generate_motd.sh. As the names imply, the first script counts the number of yum updates available, whose output will be read by the second script when it creates the MotD banner. Below are the instructions I’ve adapted from the author’s site on how to install it.

Install the dependencies for the scripts:

Download the scripts and make them executable:

Test the scripts to see if they work correctly:

If everything works, you should see similar output to below:

centos_motd

Copy scripts to their final locations:

Make a cron job to run count_yum_updates.sh automatically (adjust for your own preferred interval):

Now you’ll get a nice MotD whenever you log in with ssh. These scripts worked perfectly fine on a CentOS droplet at Digital Ocean but at RamNode the MotD did not display the IP address of the server. I’m not sure if it was because they were OpenVZ or not but I fixed the issue by modifying line 80 of generate_motd.sh:

Original line 80:

Modified:

Protect WordPress Login using Fail2Ban and Cloudflare

I’ve discovered a way to protect my WordPress site from brute force attacks thanks to these two guides I found:

DDOS PROTECTION WITH CLOUDFLARE AND FAIL2BAN
WordPress Login Security with Fail2Ban

The best part is these guides do not require installing yet another plugin to WordPress. If your WordPress site does not sit behind Cloudflare, you can just follow the second guide; if you are using Cloudflare however, that guide won’t do anything for you because iptables will only ever see IP addresses from Cloudflare, not your attacker. To make it work with Cloudflare, we need the action filter created in the first guide.

The following steps are a combination of the two guides above and are what I used to configure fail2ban to ban IPs at Cloudflare after failed logins on WordPress; if you haven’t done so already you need to install mod_cloudflare for Apache so it can see the IPs of visitors instead of Cloudflare’s. It’s also a good idea to configure iptables to only allow HTTP/HTTPS traffic from Cloudflare so they can’t bypass it and browse your site directly; the list of Cloudflare IPs is available here as a text file.

First we need to make WordPress log failed authentication attempts; edit the functions.php of your site’s theme and add the following:

Next we need edit /etc/rsyslog.conf and add the following lines under the “Rules” section:

Since we’ve added a new log, we should configure logrotate; add the following to the bottom of /etc/logrotate.conf:

Restart rsyslog with:

Next we create the filter for fail2ban to use; create a new file /etc/fail2ban/filter.d/wordpress.conf with the following contents:

Now we define the action for fail2ban to use; create a new file /etc/fail2ban/action.d/cloudflare.conf with the contents below. Remember to insert your Cloudflare email address and API Key at the bottom.

Now that we have the filter and action created for fail2ban we can add the jail to /etc/fail2ban/jail.local:

Restart fail2ban and it will watch /var/log/wp_f2b.log for failed WordPress authentication and use the Cloudflare API to ban/unban IPs.

Nginx Reverse Proxy with Deluge Web UI

Last year I experimented with using a seedbox for torrenting; I built one using CentOS and Deluge and took a snapshot before I decided to stop using it. Recently I tried deploying it again from the snapshot and found the Deluge Web UI unreachable as Chrome displayed the error message ERR_SSL_VERSION_OR_CIPHER_MISMATCH. It appears in the time since I built it, browsers have stopped supporting SSLv3 due to the POODLE vulnerability. According to this thread, it can be fixed by updating to a newer version of Deluge; however I needed to keep using version 1.3.6 because reasons. Fortunately I was able to configure Nginx as a reverse proxy with SSL enabled for the Deluge Web UI; instead of connecting to the Deluge Web UI directly, I can connect to it through Nginx over HTTPS while the Web UI continues to listen on localhost:8112. Nginx is easy to install and there are many guides on the internet; here’s one for Ubuntu 14.04 and one for CentOS 6.

Below is my configuration for proxying Deluge Web UI through Nginx with SSL enabled; I found the SSL cipher settings on a blog post about hardening SSL ciphers here and the proxy settings on the Deluge Bug Tracker here.

 

Windows Deployment Services – Event ID 772 and Capture Boot Image failure

I recently tried to set up Windows Deployment Services (WDS) on Server 2012 R2 in my home lab environment; WDS has been around since Windows 2003 and sadly I’ve never tried using it until now. It allows you to deploy Windows operating systems quickly by allowing workstations to PXE boot from a WDS server; you no longer need a DVD or USB stick with Windows on it in order to image a desktop or laptop. You can simply boot a machine via PXE and select the appropriate image to install; you can also include driver packages to be installed automatically or build your own custom images by capturing a sysprepped machine.

Installing Windows Deployment Services is straight forward; if you’ve added a Server Role before like DNS or DHCP then you’ll be familiar with the process. You can read more about it here. I already had a 2012 R2 VM running as a Domain Controller; I added the WDS role first and then the DHCP role as I needed to provide DHCP Options 60, 66 and 67. I initially only added options 66 and 67 for the server IP and boot path; I didn’t immediately notice a way to specify Option 60 and tried PXE booting my notebook anyway. The PXE boot process failed (connection timeout) and I noticed the Event Log on the WDS Server had one error concerning Event ID 772:

wds_event_log

After looking up Event ID 772, I found the issue was due to having WDS and DHCP running on the same machine; it seems they both listen on some of the same ports which why the error log mentions “some other application is already using the port.” I fixed this by enabling the following options in the WDS Server properties:

wds_dhcp

These options can also be enabled by command line:

After enabling those options I was able to successfully boot from an install image I had added. Next I tried creating a custom install image based the Windows install that was already on my notebook. I created a capture image by following the TechNet instructions but it gave an error when I tried to boot from it; the error was a “Windows failed to start” message similar to this one:

winloaderror

I don’t know how but someone in this thread figured out that mounting and unmounting the capture image resolves the issue. I issued the following commands to fix my capture image:

Now I could boot my capture image and after fixing my issue with sysprep, I was able to capture and upload the Windows install on the notebook (complete with applications and drivers) to the WDS Server. I installed the image I captured but ran into an error message as Windows was booting: “Windows could not finish configuring the system”.