Hardening WordPress Security on a DigitalOcean Ubuntu Server Droplet

This is my third entry in my WordPress security series.

The $ in the code blocks represents the command line prompt. Ctrl+C will clear page logs when they hide the command line prompt. Use arrow keys in nano editor to move through file. Ubuntu 18.04 LTS at the time of this writing.

Update all installed software

$ sudo apt update
$ sudo apt upgrade
$ sudo reboot

Install a Digital Ocean Firewall

Install a Digital Ocean Firewall for one droplet and give it a name to remember in Networking/Firewall/Create Firewall. If you have more than one droplet and wish to apply the same firewall to each, it is best to apply a tag to all the droplets and then apply the firewall to the tag. The inbound and outbound rules should at least have:

place your public IP address for SSH

These changes to the security.conf file make changes at the server level for everything in it so if you are checking if Sucuri SiteCheck will see them, it will think they are still not working. If you want to have them seen and only applied to WordPress, then you will need to apply these settings to the .htaccess file in the root of WordPress install folder. For these changes, they can be checked with the curl -I command below and the output on the website from the Network tab on Developer Inspector in your web browser of choice, select the root domain name line, usually the first entry after the site reloads, in the inspector then click on Headers tab to see them.

First, you need to enable Apache Headers module or the next steps will throw errors by not letting your website load or producing a 500 error.

$ sudo a2enmod headers

Go to root folder where all WordPress files are installed. ls -a shows hidden files and must be used before editing the file:

$ cd /var/www/html/
$ ls -a
$ sudo nano .htaccess

Below #END WordPress add the code after adding two returns:

# Security Hardening

# Restrict Access to Sensitive Files
<Files .htaccess>
Order Allow,Deny
Deny from all
Satisfy all
</Files>

<IfModule mod_headers.c>
Header set Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" env=HTTPS

# Header set X-Content-Type-Options NOSNIFF
# Header always append X-Frame-Options SAMEORIGIN
Header set X-XSS-Protection "1; mode=block"
Header set Referrer-Policy "no-referrer-when-downgrade"
Header set Feature-Policy "vibrate=none;"
Header set Content-Security-Policy "default-src=https:; script-src=self; style-src="unsafe-inline;"
</IfModule>

# Disable Directory Browsing 
Options All -Indexes

# Disable HTTP Trace Method 
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_METHOD} ^TRACE
RewriteRule .* - [F]
</IfModule>

# END Security Hardening

Make a backup copy of these two files or comment out the previous values you plan to make changes to:

    /etc/apache2/apache2.conf
    /etc/apache2/conf-enabled/security.conf

Then edit the security.conf file by using these commands:

$ cd /etc/apache2/conf-enabled/
$ ls
$ sudo nano security.conf

Scroll through file and uncomment these values if they exist or add them close to similar names on new lines if they don’t exist in the file. This first code block hides the Apache version number.

ServerTokens Prod
ServerSignature Off
Header set X-Content-Type-Options NOSNIFF

#Mitigate clickjacking.
Header always append X-Frame-Options SAMEORIGIN

#Enable XSS protection.
Header set X-XSS-Protection "1; mode=block"

#Mitigate XSS by securing cookies.
Header edit Set-Cookie ^(.*)$ $1;HttpOnly;Secure

#Disable HTTP/1.0.
RewriteEngine On
RewriteCond %{THE_REQUEST} !HTTP/1\.1$
RewriteRule .* - [F]

#Hide PHP version.
Header unset X-Powered-By

Ctrl+X to exit editing, Y to save file, and hit Enter to keep filename the same. Reboot Apache and optionally reboot server by turning on/off the Droplet or using sudo reboot in command line.

$ sudo systemctl restart apache2
$ sudo systemctl status apache2

Visit your website to see if it is loading after these changes and use this to see if they are applied:

$ curl -I https://yourdomain.com 

Scan your website and you should receive an A+ at https://securityheaders.com.


If by chance you need to flush the WordPress cache, go to the folder where it is installed first and run this WP-CLI command:

$ cd /var/www/html/
$ wp --info 

wp –info will show you if WP-CLI is already installed, you will see the version number. Then you run this next command to flush the cache. You have to use the default user (www-data) in the user group on Apache. You can’t use your root user to do this and if it says you can override it to allow root user to control, don’t do it for the security of your server.

$ sudo -u www-data wp cache flush

These are a list of websites that refreshed my knowledge:


Posted

in

Comments

2 responses to “Hardening WordPress Security on a DigitalOcean Ubuntu Server Droplet”

  1. Khürt Louis Williams Avatar

    Hi Daniel, I think you did a great job of documenting this. Even better you provided references.

    1. Daniel Brinneman Avatar

      Thank you, Khürt!

Start a conversation about this post

%d bloggers like this: