Image with the WordPress logo and code in the back ground

WordPress hack

So I have installed WordPress on my NGINX server for a little over a month now. Just a bare WordPress site sitting on the internet. What I have noticed over this time was a number of attacks on my server trying to get into the WordPress site. Mostly trying to brute force my account credentials by guessing the password. Not that I have anything valuable, but hackers need to practice, right?

I installed Jetpack and Block Bad Queries to block some of the intruders. However, what I have seen lately is a number of attacks that use /xmlrpc.php to amplify traffic and perform a DDoS attack or brute-force my password by trying to guess as many passwords as possible in a single query. The attacks actually brought down my server and caused me many headaches over the past week.

How did I deal with these attacks?

Because I use an NGINX server the .htaccess method to restrict access to the file would not work. Instead, I decided to block the use of /xmlrpc.php directly in my NGINX configuration while whitelisting all Jetpack IPs that use xmlrpc functions. This way I can keep using sharing while being protected from any outside attacks. If you are using other third-party services that require access to xmlrpc you could also whitelist other IP ranges so that you don’t lose functionality.

I added a new location block in my server configuration block to restrict access to xmlrpc.php.  While at the same time adding a geo block that keeps a list of all whitelisted IPs that will have full access to xmlrpc. Other solutions that have been suggested on the internet have been to outright block access from everyone to xmlrpc.php. Of course this comes at the cost of losing the share feature in WordPress. The beauty of this solution is that you don’t need to lose that feature.

Here is the code that you should include in the default configuration file for your server to implement this. The configuration file is usually located in /etc/nginx/sites-available/ folder:

geo $bad_guys {

# 1 is a bad guy
# 0 is a good guy
default 1;


# This is the IP range for Jetpack. This will likely change in the future
# so you must make sure you update them from time to time
192.0.64.0/18 0;

}

server {

location = /xmlrpc.php {

if ($bad_guys) {

return 444;
access_log off;

}

# Alternatively you can use allow and deny directive. By using these directives you would be sending a 403 error back to the requester's IP.
# If you like to use the allow/deny directive instead of if, uncomment the next two lines and delete the block above.
# allow 192.0.64.0/18;
# deny all;


include snippets/fastcgi-php.conf;
# if you are using php5-cgi instead of php5-fpm uncomment the next line and comment the php5-fpm line
# fastcgi_pass 127.0.0.1:9000;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}

}

In the code you would see that I have decided to just drop the connection from the requester and not send a response back. This is because I don’t know if the requests are coming with a spoofed or legitimate IP. I don’t want to keep sending traffic back in case the IP has been spoofed and somebody is trying to use my server as a DDoS device.  Alternatively I could send back a 403 error. If you want to send an error message then change return 444 to return 403.

I have also turned off logging of these events because the log file could get quite enormous with a lot of requests. Delete the line if you want logging turned on.

After reloading the NGINIX configuration my server stays nice and protected.