Rate limiting xmlrpc requests on WordPress using Nginx

WordPress based sites are target for most automated bots. Those bots look for various vulnerability in WordPress core, the themes, and the plugins. Then, there are some kids (and their kid bots) that target specific resources in a WP site. “xmlrpc.php” is one such resource. It uses XML-RPC protocol that does many things in WordPress. For example, it helps with remote sites to notify their mentions, to publish (and edit) articles using an app (such as WordPress app for Android / iOS). It is also used by many plugins such as Jetpack.

Naturally, xmlrpc.php file may be called multiple times in a day or in an hour (on a busy site). It may be called multiple times for every minute on a high traffic site. I have seen xmlrpc.php being accessed more frequently even on a site with no traffic too. Those traffic are likely from scan / scam bots, looking for vulnerabilities.

Since, there is no way to cache requests to xmlrpc.php, PHP and MySQL usage tend to go high quickly as every request needs a bit of php and MySQL. As a result, CPU usage spikes up, resulting in a wastage of precise CPU minutes. If we use platforms like AWS EC2, GCP, or Microsoft Azure where every CPU hour is charged, the cost of running a site can increase substantially.

In order to reduce the CPU usage, one solution is to completely block access to xmlrpc.php file. However, since this file is used for genuine purposes too, it is not recommended to disable access to this file. Alternatively, we can rate limit the requests to this file. A genuine request would not call this file multiple times per second. A decent limit is 1 request per second.

Let’s see how to implement rate limiting for xmlrpc in Nginx…

limit_req_zone $binary_remote_addr zone=wp_xmlrpc_limit:10m rate=1r/s;

server {
    server_name example.com;

    location = /xmlrpc.php {
        limit_req zone=wp_xmlrpc_limit;

        fastcgi_split_path_info ^(.+\.php)(/.+)$;

        if (!-f $document_root$fastcgi_script_name) { return 404; }

        # Mitigate https://httpoxy.org/ vulnerabilities
        fastcgi_param HTTP_PROXY "";

        include                     fastcgi_params;
        fastcgi_index               index.php;
        fastcgi_param   SCRIPT_FILENAME    $document_root$fastcgi_script_name;
        fastcgi_pass                fpm;
    }

    # other location blocks such as location / {}
}

Basically, we define a separate location block to process xmlrpc.php file and then insert two lines of code to introduce rate limit. The first line (starting with limit_req_zone) should be defined outside of server block. The other one (starting with limit_req) should be defined inside the newly introduced location block.

In the above code, we limited the requests at 1 request per second. We can fine-tune it depending on our use-case. There are other areas to fine-tune too such as implementing a separate log for xmlrpc requests. That’s for another day!

Happy Hosting!

WordPress Migration Checklist

A successful WordPress site gets migrated to another host or another server within the same host, at least once in every few years for a number of reasons. Better operating system, to upgrade the PHP version, to handle larger traffic, etc. The first step is to test your migration on a staging server. Most issues (such as theme / plugins incompatibility) can be caught, if we test our migration using an existing (full) backup of the site. So, the following list applies only to live site migration. Here are the list of areas to check after the migration…

Backups

There are hundreds of plugins available to take a complete backup of your site. Each one is prone to errors. If you visit the official wp.org support forum for each of the backup plugins, you’d understand what I mean. The new host (or the server) may have some limitations that may not work well the current backup plugin. That’s why it is recommended to use an external backup solution that doesn’t rely on WordPress core, or its plugins. I have a dedicated Github project to take backups of WordPress sites using simple bash scripts.

Four things to consider while checking backups.

  1. Make sure local database backups are taken correctly.
  2. Make sure local files backups are taken correctly.
  3. Make sure offsite backups are working.
  4. Make sure the backups are verified.

No backup is useful, if it is not verified for authenticity of what it contains. That’s why it is important to have a workflow to test the backups, with automated tests.

Email

Unlike backup (that is basically a complex process), email is relatively an easy process. That’s why there are thousands of plugins available related to emails in wp.org repo. Because, people use email in a WordPress site for a number of reasons. To send a upgrade email to administrator, to get messages via contact form, to send newsletters, to get informed about the new user registration, to get notified about new e-commerce order, etc.

Even though, email is as old as internet itself, reaching inbox is a complex process. Most common issue with WordPress sites is that the email never leaves WordPress in most cases and would be simply dropped at WordPress itself. That’s why the most used contact form plugin still recommends an add-on plugin to keep an archive of all messages that come via the contact form.

If you use a SMTP service and a plugin to send emails via WordPress, then, in most cases, the emails would continue to work, after the migration. It is still recommended to test emails by submitting a test entry via the contact form.

If you depend on the server or host to send emails, then you may be in trouble, as certain host blog ports related to sending emails. For example, Google blocks port 25 on its compute platform.

Other items to check

There are some less-priority items to check after the migration. Here’s an incomplete list…

  • Cron: Check if cron hasn’t stopped and continues to run events as expected.
  • Cache: Check if your full-page caching plugin caches posts and the web server serves cached content if exists. Server response time is the most critical factor. You may check it at https://web.dev/ or in Google Search Console that provides historical data.
  • CDN: If your CDN depends on the IP of the server and if your server IP changes, then it may not be able to pull the content. You wouldn’t even aware of this, as CDN caches contents for an average of 24 hours and checks for newer content only once in a day or week. So, you’d understand the CDN related issues only if you create and publish a new post with images.

I will add other items as and when I come across or if it is important. Do you have a checklist whenever you migrate? If I missed anything, please feel free to add it via the comments section.

Happy hosting!

DigitalOcean Hosting Review

No affiliate links are inserted in this post. I did not have and do not have any monetary benefits in posting a positive review about DigitalOcean (or any other hosts in this blog), either. No host is perfect. So, I am posting only what I like about DigitalOcean. There may be some cons of using any host. If you search the internet, you may find them. I use Google Compute Engine for hosting this site, though.

Logo - DigitalOcean

Time to Restart the Whole Server

Whenever I build a server from scratch, I make sure that the automatic security updates are enabled. Most security updates are applied automatically. However, certain updates, particularly, the updates related to Linux kernel needs a restart of the entire server. This means a short downtime of the site/s hosted in that particular server. No one likes a downtime. At least, Google Search Bots do not.

The server restart and the resulting downtime is the primary reason for the popularity of containers such as Docker, LXC, LXD, etc. Of course, there are other benefits of using a container. Not everyone can afford to use containers, load balancers, etc. Maintaining them cost a lot more than maintaining a single server without the container eco-system. Most individual site owners and small businesses opt for single server system to lower the cost of running a server.

In shared hosts, the Linux kernel updates are applied on-the-fly, using one of the multiple technologies available, such as kpatch, livepatch (commercial), etc. Most of them are commercial services. The free services come with a big warning such as the following…

WARNING: Use with caution! Kernel crashes, spontaneous reboots, and data loss may occur!

So, most vendors (shared hosts) opt for paid commercial services to apply Linux kernel updates without a complete restart of the server. If you use a shared host, then no worries. This post is valid only for VPS servers and dedicated servers. The term VPS may also mean cloud servers with certain hosts. Some popular VPS providers are AWS (Amazon Web Services), Google Compute Engine (GCE), Linode, DigitalOcean, Vultr, etc.

The time to restart a server (VPS or dedicated server) depends on various factors. The number of running processes, the number of running programs, the choice of web server, the database server, etc. Every tiny thing matters. Even the hypervisor used by the host can have an impact on the time to restart the whole server.

Choosing a host is hard. There are lots of factors to consider. Price, the location of data centers, the Operating Systems provided, the bandwidth or the network speed, overall value for money, etc. Among these, you might also want to consider the time to restart a server when choosing a host. Because, some hosts take more than 5 minutes to restart a server, resulting in a downtime that may be a considerable amount for Google Search Bots.

In my experience working with various hosts, DigitalOcean restarts the servers in the shortest time possible, often less than 30 seconds for a server with a memory of up to 32GB. An idle server with no sites hosted on it, may restart much more quickly, like less than 15 seconds.

There are other advantages of choosing DigitalOcean. I will update this post with those, if it is worth mentioning.

Happy Hosting!

Uptime Monitoring

WordPress is easy to use. Behind the scene, it is a complex piece of software, running on PHP and MySQL. Monitoring the uptime of WordPress sites may seem straightforward. But, in reality, it is easy to miss the downtime using conventional methods.

Let me provide you with an example. Let’s take this site… tinywp.in . I monitor this site using multiple uptime monitoring services. They keep watching the home page at https://www.tinywp.in and see if it shows any errors. They notify me in case of the following errors

Continue reading “Uptime Monitoring”

Sandboxing email for a local WP site using just three lines of code!

In a local-staging-live workflow, often we have some restrictions on both local and staging / development environments. A common restriction is to disallow indexing of the development site that may introduce duplicate content in the search result, if indexing is allowed (that is not uncommon when we set up the live site and then copy it to develop further :-) ). There are lot more restrictions and workarounds in order to setup a perfect development or local environment. Here, let me share a particular solution regarding emails. Let me start with some of the use cases.

Continue reading “Sandboxing email for a local WP site using just three lines of code!”

Project: WordPress in a (LEMP) box!

There are plenty of scripts in the internet, some of them even open source, that helps us to install WordPress automatically in a (single) server. Bitnami is the most popular among them. However, none of them met my requirements. I have some design considerations, security requirements and performance checklists. Since none of the existing tools met all my principles, I started developing my own tool to set up a (single) WordPress site in a (tiny) server.

Continue reading “Project: WordPress in a (LEMP) box!”

Is Your Awesome Site Mobile Friendly Too?

Image - mobile friendly sitesToday is the day when Google has started implementing mobile friendliness as a search engine ranking factor. The actual announcement in this regard was done two months ago in the official WebMasterCentral blog. It also started showing a tiny warning in the official blog since then. If you use WordPress and if your site is not mobile friendly, yet, there are options to convert it (for free) to fit into mobiles nicely.

Continue reading “Is Your Awesome Site Mobile Friendly Too?”