Here is a tip for speeding up WordPress, especially if you are running it on a low power server. I made the change to WordPress running on a small ARM server, resulting in an immediate and dramatic speed up. It works because it prevents bots on the Internet from wasting your server resources.
The procedure could hardly be easier. Just move the wp-login.php script. And create an empty stub in its place. And that’s it.
$ cd /usr/share/wordpress
$ sudo mv wp-login.php ~/wp-login.php
$ sudo touch wp-login.php
That will move the wp-login.php script into your home directory, and create an empty file in its place. Now, when any internet bot tries to log into your WordPress by guessing the password, they won’t even get a valid login form. Your WordPress security has been radically improved. If your server is low power (eg a Raspberry Pi, sheevaplug or similar), you may also get a startling improvement in your site’s speed and responsiveness.
You won’t be able to log into WordPress now of course, because you have moved the script that controls the login. Neither will you be able to log out. Whenever you want to log in or out of WordPress, just undo the change:
# cd /usr/share/wordpress
# sudo mv ~/wp-login.php wp-login.php
…and now you can log in/out again. Don’t forget to redo the change afterwards, in order to get the performance and security benefits. (The script has to be in place for loggin in and out, but it does not affect an existing WordPress session).
Obviously, this procedure is most useful where you log into WordPress relatively rarely. If you are logging in and out all day log, it won’t be very practical to be renaming the script all the time. Better to try one of the plugins mentioned below.
Botnets and WordPress Scripts
The above procedure works because it prevents botnets and other ever-present internet attackers from consuming your CPU resources as they probe for weak passwords. Many blogs are protected by very long passphrases (and if your WordPress passphrase isn’t very long, it should be). Long passphrases will generally stop the attacker from getting in, but they won’t stop him from trying to guess the password. And those failed attempts can slow your server down significantly.
Scammers are always trying to guess WordPress (and other) passwords. It has become a constant background drone on the internet. “Script kiddies” (ie. novice hackers) will often mount an attack from their server, trying to guess your password a few thousand times over the course of a day or two. These are easy to spot in your site’s access.log file – you will see many references to “wp-login.php” from the same IP address.
Botnets are a more advanced form ot internet hacking. They are quite common these days. If your blog is attacked by a botnet, you may see tens of thousands of references to “wp-login.php” in your sites access.log file, within the space of a few hours. They will come from many different IP addresses, usually hundreds. Often they will make up to 40,000 or so guesses at the password, as they work through a list of dictionary words and common passwords. This is called a dictionary attack.
I recently made the change above on a low powered WordPress server that was actually undergoing a dictionary attack. The attack was neutralised and the considerable CPU resources it consumerd were reclaimed, speeding up the server and web site instantly. More importantly, the ongoing web performance was significantly boosted, long after the dictionary attack ceased.
That is the end of this article really. If you are running WordPress on a low powered, internet-facing server, moving the WordPress login script is a no brainer, for both security and performance.
The rest of this article gives more technical background, and explains why a stub file is created, rather than just having no wp-login.pfp file at all.
CPU Consumed by Password Guessing
Each login attempt will occupy one of your server’s Apache processes for some time, just as it does when you legitimately login to WordPress. The server has to draw the login page, accept the password, run the authentication algorithm, and so on. On fast hardware this would not be too noticable.
Lower Powered Server
However, on a low power ARM server I checked recntly, each password guess was occupying an Apache process for 5 to 10 seconds. The maximum number of Apache server processes was set to 5, so when 5 login attempts came within 5 seconds or so, the server became unresponsive, and remained unresponsive for as long as login attempts (password guesses) were received at that rate. Meanwhile the “top” command showed Apache server processes to be consuming, between them, almost 100% of the CPU.
It’s Quicker to Return 404
When I renamed the wp-login.php script to something different, WordPress came back to life. The apache logs showed the password guesses now being returned code 404 instead of a proper login page. It is much quicker for the Web server to return a code 404 than it is to process a login. The Apache processes returned to their normal rate of CPU consumption. WordPress was responsive and the site performance was restored.
The second command above (touch wp-logon.php) creates an empty file in place of the login script. In fact you could miss the step out, and just have no wp-login.php file at all. However when I did this on a live WordPress server, after a few minutes of returning 404 codes to login attempts, it started to return 302 instead, which has something to do with redirection. That is okay, but I noticed the 302 return also took up some CPU, although much less than a full login attempt. Creating the stub file made the return code revert to 404 again, with consequent small saving in CPU.
WordPress plugins are available that move the login script, eg the sf-move-login plugin. I haven’t tried these, but you might. The change above is so simple, adding another plugin to WordPress hardly seems worth it. Again, if you are on a low powered hardware, plugins are best kept to a minimum.
If your blog has many users, who often log in, then simply moving the wp-login.php script might not be very convenient for you, and a plugin such as the above might be prefereable.
Botnet Dictionary Attacks
Dictionary attacks are very common these days. They come from organised networks of compromised PCs called “botnets”. They look for sites running WordPress and other blogging platforms and, having found one, try to guess the login password – using dictionary lists and commonly used passwords. Consecutive guesses come from different PCs on the botnet, so in your Apache log they will appear as login attempts from many different IP addresses. Not so obvious as many guesses from the same IP would be.
A Dictionary Attack is not DDOS
Dictionary attacks do not normally overwhelm their targets. They aren’t trying to take your blog offline, just to guess the password. With the server mentioned above, it only became obvious because the server hardware was quite low power, and the botnet tried to guess too quickly. In fact the server had sustained the attack for several days without slowing down much. Each password guess tied up 1 Apache process while several others were free to service legitimate page requests. Only when the guess rate crossed a critical threshold did the blog become extremely slow (and that was not the scammer’s intention – they want to go under the radar, not become a huge blip on it).
Software packages like fail2ban have been developed to protect againt internet attacks based on password guessing. You might get some mileage from these. In my view, large software frameworks are more suitable for large web server, not small servers that are the subject of this article. Also fail2ban in particular is not designed to combat attacks from distributed botnets.