2014-08-27

A step-by-step guide explaining how to install, securely configure and performance-tune WordPress on Apache on Linux.

Contents

To Virtualize or Not

Windows – or Linux?

Installing Ubuntu in a Generation 2 Hyper-V Virtual Machine

Installing and Hardening Apache

Configuring Apache

Configuring MySQL

Migrating WordPress

Hardening WordPress

Mod_pagespeed: Apache Performance Tuning

Support & Operations

The web is all about speed. If your site is slow, you lose visitors. And administering it is not much fun. In order to get to a fast server, you need to control the hardware. If you currently are on any kind of virtual server or even on shared hosting, in other words on anything where someone other than you is controlling resource allocation, your chances at a fast server are based solely on luck. For that reason I decided to get my own Hyper-V server in the cloud.

To Virtualize or Not

There is, of course, nothing wrong with (web server) virtualization – as long as you do not overcommit resources. Hosting providers, however, tend to do that, which explains why performance is often less than optimal. To illustrate that point compare the system I am describing here with my previous setup, a managed virtual server at a good (and not inexpensive) hosting provider:



The graphic shows the time spent downloading a page and is taken from an authoritative source: Google Webmaster Tools.

Windows – or Linux?

Being at home more in the Windows than in the Linux world my initial plan was to deploy Server 2012 R2 in the webserver VM. That was until I learned that my personal killer application mod_pagespeed was not available for Windows.

Another thing that weighed strongly in favor of Windows: if you want a software to just work, use it the way its developers intended it to, in its natural habitat. Do not try to be clever. Be pragmatic. Exotic configurations are tested less thoroughly – if at all – and finding help on the internet is a lot easier if there is more than a single person on this planet with your exact configuration.

So Linux it was. As for the distribution, I decided on Ubuntu 14.04 Server LTS. It comes with long-term support (hence the acronym LTS) and is fully supported even on generation 2 Hyper-V VMs without the need to install integration components. Just make sure to disable secure boot (see below).

Installing Ubuntu in a Generation 2 Hyper-V Virtual Machine

Downloading Without a Browser

Download the ISO through PowerShell (IE is not available in minimal interface mode):

Creating the VM

Create a new generation 2 VM

Enable Dynamic Memory

Disable Secure Boot

Assign the MAC-Address obtained from Hetzner to the VM’s NIC

I have assigned 6 vCPUs and 8 GB RAM to the VM. That seems to be more than enough for the time being: CPU usage is well below 5% and RAM usage around 1.5 GB.

Installing Ubuntu

Run the installer

Select the partitioning scheme Guided – use entire disk

Reboot after the installer finishes and log in with the account you specified during installation

To simplify management install Midnight Commander, a Norton Commander clone:

Set up time synchronization:

Install OpenSSH for remote management and SFTP:

Securing Ubuntu

Change the SSH port by editing /etc/ssh/sshd_config:

Enable the firewall, allowing only SSH traffic:

Rate-limit SSHd, allowing only 5 connections per IP address in any 30 second interval:

IP hardening, uncomment the following lines in /etc/sysctl.conf:

Reload:

E-Mail

Install Sendmail to enable your server applications to send e-mail:

Configure a reverse DNS entry in Hetzner’s robot so that it points to something meaningful like www.yourserver.com.

Installing and Hardening Apache

Installing LAMP

Install LAMP (Apache, MySQL, PHP):

Install additional Apache and PHP modules:

Hardening PHP

Add the following to disable_functions in etc/php5/apache2/php.ini: exec, system, shell_exec, passthrough

Hardening Apache

Enable HTTP and HTTPS in the firewall:

Edit /etc/apache2/conf-enabled/security.conf to send only minimal information about the server:

Restart Apache:

Mod_security?

Mod_security is a powerful application firewall for Apache. As with all firewalls its usefulness depends entirely on the quality of the rulesets available. The one free quality ruleset, OWASP ModSecurity Core, does not work correctly with WordPress. Two companies I am aware of sell rulesets and claim full WordPress compatibility but those are expensive. So no mod_security for me.

Mod_evasive

Mod_evasive is a kind of rate limiter helping against DDoS attacks.

Edit the configuration file /etc/apache2/mods-enabled/evasive.conf so that it looks like this:

Restart Apache:

Configuring Apache

Apache Virtual Host Configuration

Delete the default site:

Create a new site configuration (replace helgeklein.com with your domain name):

Paste the following into the file helgeklein.com.conf:

Enable the new Apache site helgeklein.com.conf:

Website Directory Structure and Filesystem Permissions

Create the directory structure in the file system:

Add your account to the webserver’s group (replace helge with your user name):

Set the directory’s ownership:

Set permissions on files and directories:

Enable SSL

Add the following to the virtual host configuration file helgeklein.com.conf:

Add the following to your main Apache configuration file /etc/apache2/apache2.conf:

Enable the SSL module:

Cache-Control Header

Set a cache-control header for static resources. Add the following to /etc/apache2/apache2.conf:

Log Rotation

Change the default log rotation so that it keeps 30 daily logs instead of 52 weekly ones. Edit /etc/logrotate.d/apache2 so that it looks like this:

Configuring MySQL

Securely initialize MySQL:

Set the collation to UTF-8 by adding the following to /etc/mysql/my.cnf:

Restart MySQL:

Migrating WordPress

This guide assumes that you already have WordPress running on another server and want to transfer it without modification, keeping the domain name.

Create the database for WordPress:

Import into the WordPress database from an SQL dump file dump.sql (created on your old site):

Copy all the files in the public_html folder (or similar) from the old server to the new server. I did that by creating a backup on the old server and transferring that to the new server.

Edit wp-config.php and update database name, user and password.

If you get this error when WordPress needs to write to the file system: “To perform the requested action, WordPress needs to access to your web server. Please enter your FTP credentials to proceed. If you do not remember your credentials, you should contact your web host” add the following to wp-config.php:

Hardening WordPress

Another layer of security for WordPress’ admin area. Additional basic authentication makes it harder to exhaust the server’s resources through many logon attempts in quick succession.

Create a .htpasswd file for Apache authentication with a single user helge:

Create a .htaccess file in wp-admin with the following content:

Mod_pagespeed: Apache Performance Tuning

Tuning a website for speed can be done at different levels. It can be done at the application level with WordPress plugins like W3 Total Cache. That works well enough but it is much more efficient and a lot simpler to do it at the server level with mod_pagespeed. In other words: if you have mod_pagespeed you do not need WordPress plugins like W3 Total Cache or EWWW Image Optimizer any more.

Installing Mod_pagespeed

Monitoring Mod_pagespeed

Mod_pagespeed makes detailed statistics like the following available through the URL /pagespeed_admin:



In order to be able to access the admin pages you need to configure /etc/apache2/mods-enabled/pagespeed.conf to allow access from your IP address. You also need to turn off the rewrite engine if you are using this in conjunction with WordPress:

Configuring Mod_pagespeed

The default rules (called filters) are just fine and they are updated whenever mod_pagespeed is updated, so in theory your site should get faster over time. The following configuration changes need to be made by editing the file /etc/apache2/mods-enabled/pagespeed.conf.

Enable rewriting of resources that have Cache-Control: no-transform set:

Utilize direct disk access instead of http(s):

Support & Operations

Patching Ubuntu

Restricted SFTP Access for Support Users

When you need support for your WordPress theme or a similar web application the vendor may request access to your installation. In such a case you may want to create an account with limited access. The following instructions show how to create a user support-account with access to only what is explicitly mounted in that user’s home directory.

Add the following to /etc/ssh/sshd_config:

Please note that all directories in the path /var/sftp/support-account need to be user/group owned by root.

Show more