My website (and a couple others on the same server) had been plagued with this mysterious ‘Error Establishing Database Connection’ for several weeks. I actually thought I had exhausted the system resources of my small web server and probably needed to upgrade it (add more RAM). I hadn’t considered the possibility that something more devious was going on, but it turns out my WordPress installation was vulnerable and was being 0wned!
This particular attack utilized the XML-RPC capabilities of WordPress. RPC is short for ‘Remote Procedure Call’. It’s a mechanism to execute procedures on a remote computer as if you were running locally. It’s a pretty powerful mechanism, but can be fairly dangerous too.
There are a few fixes published on the Internet. One solution was to enable Jetpack‘s security features. I tried it and it didn’t work. What did work for me was a two fold strategy.
1. Use a firewall to specifically deny the IP addresses of the attackers. I would consider this the first line of defense — it works at the lowest possible level. The problem with the Jetpack solution is that it works at the application tier, which consumes more system resources, leaving you open to denial-of-service type attacks.
I’m running Apache on an Ubuntu server. To find the IP addresses of the attackers, I did something like this:
fgrep '"POST /xmlrpc.php HTTP/1.0" 500 585 "-" "Mozilla/4.0 (compatible: MSIE 7.0; Windows NT 6.0)"' /var/log/apache2/access.log | cut -d' ' -f1 | sort | uniq
Once I had the IP addresses I installed Uncomplicated Firewall, and added a rule for each IP address.
sudo ufw insert 1 deny from 184.108.40.206
sudo ufw insert 1 deny from 220.127.116.11
sudo ufw insert 1 deny from 18.104.22.168
That alone helped dramatically, but doesn’t stop someone coming in from another address, so another step was needed.
2. I explicitly reject any web request for xmlrpc.php. You can do this using an .htaccess file, or directly in the web site configuration (in my case in /etc/apache2/sites-enabled). I added the following snippet to the bottom of the virtual host file(s). (I believe you could also do this globally if you didn’t want to do it per-site.)
Note, this disabled XML-RPC and therefore any features/plugins that require it! However, it works fine for my purposes. YMMV!