This blog posts shows how the CloudFlare firewall can increase website security and reduce server resources required to run a WordPress website.
I’ve recently set up a new web server for PTS, an AWS t3a.nano – a virtual server with 0.5GB of RAM and 5% of a processor core (bursting to 2 cores) running Ubuntu 20.04. The server runs the LEMP stack (Nginx, PHP 7.4, MySQL) serving five websites, plus runs other software such as SyncThing which is an open source Dropbox replacement. This replaces an Amazon Linux 1 server which worked fine for years, but Ubuntu has much more community support and simpler software installation, so for general purpose servers outside of enterprise work I use Ubuntu in preference to Amazon Linux.
Checking the web server logs of the new server I could see a huge number of requests for xmlrpc.php and wp-login.php on all the sites on the server. These requests are attackers probing the web server to try to compromise the website. The server and all software is set up securely and patched nightly so they probably wouldn’t get in this way, but the traffic takes resources such as bandwidth and CPU. I considered setting up Crowdsec but right now it’s just too immature, so Fail2Ban was installed as per a previous post.
I still wanted to increase the site security, reduce resource usage, and reduce the bandwidth charges, so I decided to use the CloudFlare firewall to prevent attackers even reaching the website. All traffic for the website is proxied through the CloudFlare service, the AWS firewall doesn’t allow any direct connections to the server. Because of this the CloudFlare firewall can be a very effective way to protect the server.
CloudFlare Firewall Rules
Setting the rules up is simple. The diagrams below explains it almost as well as these steps:
- Login into your CloudFlare console and select the property you want to protect
- Click “Firewall” then “Firewall Rules”
- Click “Create a Firewall rule”. Enter the name as “Block XMLRPC”, Choose field as “URI”, operator as “contains”, value as “xmlrpc.php”, and action as “block”. Hit Deploy.
- Click “Create a Firewall rule”. Enter the name as “Challenge WordPress Login”, Choose field as “URI”, operator as “contains”, value as “wp-login”, and action as “JS Challenge”. You can also choose to display a Catchpa or similar.
- Click the “Tools” tab then activate the “Bot Report” option. This will automatically present a challenge to any IP that CloudFlare thinks is a bot.
Looking at the web server logs I can see there are virtually no requests for xmlrpc or wp-login, so this process has been successful! The graphs on the third diagram above show that the number of requests sent at the server has dropped significantly in the 24 hours since I deployed these rules so the attackers are obviously giving up.
I can also see that the CloudFlare cache hit ratio has increased from around 10% to between 30% and 40% depending on the website. That’s pretty good given every one of the 100+ CloudFlare caching nodes needs to fetch the resource to cache it locally. This further reduces bandwidth, CPU, and RAM required to run the websites. Nginx when CloudFlare does hit the server Nginx page caching ensures that users who aren’t logged in get a cached page if one is available.
All this took about 15 minutes to implement, writing the blog post took longer!
AWS services can do this same job. The AWS Web Application Firewall can do this same job and do it well, but it’s going to cost at least US$7 per month and possibly more. Given that my entire AWS bill is currently around US$8 per month for a server, related services, and S3 storage I use the CloudFlare free plan in preference to the AWS services! I’ve been happy with CloudFlare’s service for years. For corporate or enterprise work I would likely use the AWS services as in those scenarios the monthly price is less important than advantages such as deployment using infrastructure as code, better integration, better logging, IAM integration, etc.