Secure A WordPress Deployment
This guide covers the most basic steps. For even more capabilities please refer here.
Assumptions
- You are deploying the server using a user account that is neither
root
, nor the the web-user (often www-data). - The guide is aimed at Ubuntu/Debian users using a VPS with Apache rather than shared hosting, but most of the instructions are fairly agnostic.
Installation
I recommend creating a new directory such as /var/www/my.website.com/public_html
and extracting your wordpress files there. Then set this to be your document root and directory in Apache.
Move the wp-config.php
file up one level, eg. at /var/www/my.website.com/
.
Now create a .htaccess
file at the same level of the wp-config.php file with the following contents:
<files wp-config.php>
order allow,deny
deny from all
</files>
Change File Ownership
All files should be owned by the SSH user who is going to be updating the site, and group ownership is going to be given to the apache user so that they can read/execute the files.
sudo chown $USER:www-data -R /var/www/my.website.com/
Change File Permissions
Change the file permissions of the wp-config file to 740.
cd /var/www/my.website.com/
find . -type d -exec chmod 750 {} \;
find . -type f -exec chmod 640 {} \;
cd /var/www/my.website.com/public_html/
chmod 770 -R wp-content
chmod 750 -R wp-content/plugins
If you don't need to be able to modify themes from within the admin area, then remove that possibility.
chmod 750 -R wp-content/themes
Optional Extra Steps
Place the following line in your wp-config.php
. This removes "permission" from the web interface from being able to edit themes, edit plugins, or edit files. However, you may need these permissions whilst first setting up and designing the site.
define('DISALLOW_FILE_EDIT', true);
You can secure your admin area so that only specific IP addresses can access it to edit your site.
To do this, add the following contents to the .htaccess
file within the public_html
folder and change xxx\.xxx\.xxx\.xxx
and yyy\.yyy\.yyy\.yyy
to the static IPs that you wish to whitelist
(use a self-hosted VPN). Simply, Add a line for each IP you wish to whitelist.
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_URI} ^(.*)?wp-login\.php(.*)$ [OR]
RewriteCond %{REQUEST_URI} ^(.*)?wp-admin$
RewriteCond %{REMOTE_ADDR} !^xxx\.xxx\.xxx\.xxx$
RewriteCond %{REMOTE_ADDR} !^yyy\.yyy\.yyy\.yyy$
RewriteRule ^(.*)$ - [R=403,L]
</IfModule>
Disable xmlrpc.php
Wordpress comes with an XML RPC interface through xmlrpc.php. Unfortunately, this can be used by attackers which will be shown in your apache access logs. One way to resolve this issue is to disable access to it through updating your .htaccess
file (on the same level as the file). Simply append the following to the top of it:
<Files xmlrpc.php>
order deny,allow
deny from all
allow from 123.123.123.123
</Files>
Test this by going to http://[my domain or IP]/xmlrpc.php
and check that you see a forbidden message.
Rate Limit Requests
Humans will only hit your site at a slow speed, however malicious attackers may flood your site with requests from computers. The easiest way to counter this is to rate limit requests to your site by IP.
Additional
- Update often. This means the themes, plugins, the core wordpress installation, and the server itself.
- Change the default username from 'admin'.
- Configure automatic backups/snapshots.
- Install SSH updater support rather than setting up ftp.
- Use a password manager such as Keepass to generate a strong random password for your admin user and store it so that you can forget it.
- Don't configure wordpress to use your database's root user!
References
First published: 16th August 2018