[WordPress Security Tips #2] Gaining Performance Back

[WordPress Security Tips #2] Gaining Performance Back

Introduction

Previously I wrote a blog about my site being attacked. Even though I have blocked the attack, the website became very slow and made visiting my site difficult.

Here I want to share my experience of gaining my site’s performance back.

Restaurant vs Bad Customer Analogy

A website is like a restaurant that constantly serves web requests customers from the Internet. Attacks are like bad customers who mainly trying to do the following two damages:

  1. Type-One: Take cotrol/shut down the restaurant (the mafia).
  2. Type-Two: Make restaurant unable to serve normal customers (obnoxious customers).

The first one targets vulnerabilities of your site (like unlock back doors –> unprotected ports/insecure configuration), while the second one can be achieved with a huge flow of valid but “useless” requests.

As most of us are not security experts, the best way to thwart the first attack is to regularly update your web applications and use an application-specific security module. For wordpress I used the All-In-One WP Security & Firewall plugin.

WP all in one security plugin

In the plugin, the features I used the most are:

  1. Blocking xmlrpc attack.
  2. Blacklisting IPs.
  3. Limit login attempts.

For the second attack, you can’t just block their requests because doing so may also block regular users’ requests. Going back to our restaurant-bad customer analogy, the principle of dealing obnoxious customers is as follows:

Spend the least resources on obnoxious customers so we can better serve good customers.

This involves the following steps:

  1. Identify obnoxious customers from their behaviors.
  2. Configure your web server to spend the least time and resource to these obnoxious customers.
  3. Tell them they are not welcomed and stop wasting their resources visit our sites.

Below are the configurations I made to achieved the above steps:

Identifying Obnoxious Customers:

The Fundamental: Log Files

You need data to tell who’s the good guy and who’s the bad guy, and log files can help you do so. Any web server record access and errors in log files. For Apache on Ubuntu it is in /var/log/apache2 . See apache’s log page for how to read log information. The following is an example of the error.log file:

wp apache error log example

As you can see, there are some requests doing some .php file sniffing. I can proceed to block them and give them 403 error code, but the sniffing period is long enough that it does not affect performance too much.

Real-time status: Apache2’s mod_status

Log files are good, but it is better to have a more readable way of presenting read-time data. Apache2’s mod_status is useful.

When using it, pay specific attention of the access control configuration (who can see the status page). The last thing you want to show to potential hackers are your server status!!!!!

Make sure you protect the status access as what Apache document suggested:

Due to security reason here I only show the first few lines of the mod_status page:

apache mod_status

By using mod_status I was able to identify CONNECT requests that kept my server busy.

mod_status gives you the real-time server information. However for ultimate information we want statistics for history as well. The one I tried out is GoAccess.

Real-time + History: GoAccess

GoAccess is an easy to use log analyzer. The setup is more involved than mod_status but it provides history statistics capability. It has terminal and html interface. The html interface is as follows:

GoAccess panel

Apache2 Server Configuration:

Turn Off KeepAlive/Reduce KeepAliveTimeout

One way an obnoxious customer keeps the restaurant from serving other customers is to occupy the seat for a long time. Same thing in web server: a bad request can keep server connecting to its server so others can’t connect.

The counter-measure of this is reduce connection time or just prohibit keeping connection (drive-through only). Doing so does impact performance, but is still better than site being brought down.

The config code is simple. Just add this into apache2.conf

KeepAlive Off

Use mod_reqtimeout

Another way an obnoxious customer does is to take a ridiculously long time to order and eat. Same in web sever: a request can just wait there and not sending data, wasting your server connection.

The counter-measure is to set a timeout for incoming requests to send data. This can be done by Apache’s mod_reqtimeout. For example:

 

Use mod_rewrite

Apache’s mod_rewrite is a great tool to identify obnoxious customers and tell them that they ate not welcome. What it can do is:

  • Parse incoming request to spot unwelcome behaviors.
  • Reduce response time/resource by changing responses.

For example, the following rewrite codes (1) allow only GET, POST, and HEAD http connection. (2) anything else will be sent a 405 “not allowed” response to discourage requests:

This effectively thwart CONNECT methods that most servers do not need. Also throwing a 405 uses less resource than throwing a usual 404 (not found).

Server Performance Tuning

Lastly, it is wise to examine how your server software (Apache) utilize your server hardware resources (especially the memory). Doing so make sure that your hardware resource is not exhausted during an attack, as hardware resource depletion usually means a crash.

Amazon AWS document has a nice article of how to determine the maximal workers Apache should use according to your server hardware resource.