In August 2014 Google announced they will start ranking websites that support HTTPS higher on their search result pages (SERPs). While the impact is minimal right now, they also stated it might (that’s Google’s saying it eventually will) become increasingly relevant in the future, so why not take care of it now and reap the benefits long term?

Another important factor to consider is also credibility; Whenever I visit a website with the now-well-known green padlock next to the website’s URL in the address bar, I know that data I request and/or send is securely transmitted. This means the owner of the website took that extra step to make sure I feel safe browsing his website. Bonus points from me!

HTTPS, SSL, TLS, oh my!

In order to get your WordPress site served over a secure connection, you first need to understand a few core terms that will appear throughout this tutorial:

  • HTTPS stands for HyperText Transfer Protocol, and it basically means a way of communicating between your browser (also called the client in this context) and the web server. The S at the end just means secure. Think of the protocol as a language that both sides communicate in. There is a lot of protocols out there, and one you might also be familiar with is FTP, which means File Transfer Protocol.
  • SSL is a cryptographic protocol (think of a language again) that enables communication in an encrypted or simply put, secure way that prevents third parties (such as malware) spying on what the content of that communication is. Remember when we were kids and had a best friend who you developed a special language with that no one else would understand? Well, this is a grownup version :) It’s also not in use anymore, because it has been superseded by…
  • TLS, which is, for all intents and purposes, an upgraded version of SSL. It uses certificates as a means of verifying identity of the server to the client (your browser). Feel free to learn more about it on Wikipedia
  • Certificates are special files that need to be set up on the server so it can prove to the browser it’s a verified by an issuing authority. Think of your ID being a certificate that you show to the police officer who can, based on it, verify that’s really you.

It’s time to get our hands dirty, now that the terminology is in order.

Prerequisites

This article assumes you’re using your own VPS server, they come so cheap these days you have absolutely no reason to use shared hosting. While it may be possible to set up TLS on a shared host (via a control panel, maybe?), I prefer a more clean approach.

We will also skip setting up WordPress as we’ve done that in our previous tutorial.

Also, we’ll use Nginx instead of Apache, since it uses less memory (RAM), is faster under same conditions and is a more lightweight piece of software. That being said, most steps we’ll take can be easily adapted to Apache and we’ll even include them if there’s demand for it.

Generate needed files

As mentioned above, certificates form the base of secure communication and to in order to get one, you first need to generate what it’s called a private key; This is the first of the four files you’ll need in order to set up your secure WordPress website.

Note: All the commands in this section are done via a Linux shell, which means you’ll have to either login to the server (we've setup one in our first tutorial, in case you missed it!) via SSH or run them on your computer inside a terminal.

In order to generate the private key, run the following command (change wp-kickstart.com to the domain you’re generating the key for):

$ openssl genrsa -des3 -out wp-kickstart.com.key 2048

This will generate a key file and will also ask you for a pass phrase (password). DO NOT lose it! If you do, you’re gonna have trouble accessing the certificate later on.

Now that we have the key, let’s make a file called signing request. This file is needed by the issuing authority in order to generate a certificate the server can share with the browser (because the key is too important to share with anyone).

$ openssl req -new -key wp-kickstart.com.key -out wp-kickstart.com.csr

Once you enter this command, you’ll be prompted for the pass phrase and once entered a few questions will be asked, like so:

Generate WordPress SSL certificate
Generate WordPress SSL certificate

The most important part is the common name, which is the domain you’re generating your certificate for. Note that www.wp-kickstart.com and wp-kickstart.com are two different domains in this context, so make sure to put www in if you use it!

Now that we have the certificate signing request file (csr), we need to remove the pass phrase from the original key, otherwise we would have to enter it whenever we ran nginx on the server, which is a bad idea:

$ cp wp-kickstart.com.key wp-kickstart.com.key.pass
$ openssl rsa -in wp-kickstart.com.key.pass -out wp-kickstart.com.key
WordPress SSL list certificates
List SSL certificate files

Voila! We have everything we need in order to get our certificate. Now, we need to submit the csr file to the issuing authority (a company that sells certificates). I recommend ssls.com because you can get a certificate there for as low as $4.99/year, which makes it a no-brainer.

Note: Do not buy certificates from official vendors, because they usually cost 10 times more with absolutely no additional benefits! Visit RapidSSL and you’ll notice the same certificate costs $49/year!

So go ahead and buy a certificate, the process is quite straightforward and the website should give you proper instructions on what steps to take in order to get one. Hint: in order to get the contents of the csr you generated, just enter the following command:

$ cat wp-kickstart.com.csr
WordPress SSL show certificate
Certificate contents (partially hidden for security)

When asked to enter the contents of the csr, you'll also be asked what server you're generating it for. IF there's no nginx as an option, just choose other.

Continue reading when you have received an email with the certificate. I’ll wait :)

You probably received TWO certificates, one of which is called an intermediary certificate. We won’t go into details at this point, suffice it to say that you need to combine the two certificates into one file, so paste your certificate in first, then the intermediary just below (with no empty lines in between) and save the file as wp-kickstart.com.crt (change wp-kickstart.com with the domain you have the certificate for). Now we have everything we need, time to…

Set up nginx

If you haven’t yet, now is the time to copy all the files to the server, the most common directory for this is /etc/ssl, but since it's quite crowded, I'll put them in our home directory /home/webmaster/certs/. Assuming you did that, it’s time to modify the nginx configuration file, which I’ll just show here and comment on it below:

server {
  listen 443 ssl spdy;
  server_name www.wp-kickstart.com;

  ssl on;
  ssl_certificate /home/webmaster/certs/wp-kickstart.com.crt;
  ssl_certificate_key /home/webmaster/certs/wp-kickstart.com.key;

  # Where the root of your WordPress site is
  root /home/webmaster/www/www.wp-kickstart.com;
  index index.php index.html;

  location / {
    try_files $uri $uri/ /index.php?$args;
  }

  location ~ .php$ {
    include fastcgi_params;
    fastcgi_pass unix:/run/php-fpm/php-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_index index.php;
    fastcgi_param PATH_INFO $fastcgi_script_name;
  }
}

server {
  listen 443;
  server_name wp-kickstart.com;
  return 301 https://www.wp-kickstart.com$request_uri;
}

server {
  listen 80;
  server_name www.wp-kickstart.com;
  return 301 https://www.wp-kickstart.com$request_uri;
}

server {
  listen 80;
  server_name wp-kickstart.com;
  return 301 https://www.wp-kickstart.com$request_uri;
}

Notice the word spdy on the second line of the block above? This word turns on an experimental protocol by Google, that significantly improves the speed at which secure websites are served. If you use one of the latest versions of Nginx, it should already be compiled in.

In our nginx configuration above, we defined four virtual hosts and they cover the following URLs being requested:

  • http://wp-kickstart.com (wrong one, not secure, no www)
  • http://www.wp-kickstart.com (wrong one, not secure but with www)
  • https://wp-kickstart.com (wrong one, secure, but no www)
  • https://www.wp-kickstart.com (yup, that’s the one!)

Why do we need to address all four scenarios? Two reasons: First, we’re improving the user experience since all of them are not just possible, but will probably happen - so we redirect all of those visitors to the correct domain (and protocol). Second, search engines won’t penalise you for having duplicate content (because if your site works with WWW and without it, then Google thinks those are two separate websites!).

So the meat of the configuration file above is the first server {} block, or more specifically, the lines that start with ssl, as the rest of the file may, of course, vary based on your requirements and/or existing setup.

(For more advanced stuff on Nginx configuration, check this Github repository from where I took some parts to improve my own version you can see here)

Once done, restart nginx (on Ubuntu, that’s usually accomplished by executing $ sudo service nginx restart) and you should now have a securely served WordPress site, and a green badge (that looks like a padlock) of honour, just like this one:

WordPress HTTPS padlock
The green padlock icon (in Chrome)

Securing FTP

If you decided to leave certificates in the home folder, now would be a good time to secure the last access point to our server: FTP.

We installed vsFTPd in our first tutorial and it already comes with all the prerequisites to secure it properly and turn it into sFTP (s, as usually, stands for secure).

To do that, you first need to create a certificate file that will hold both our key and the certificate itself, which is done by running this command:

$ sudo openssl req -x509 -nodes -days 365 -newkey rsa:1024 -keyout /etc/ssl/private/vsftpd.pem -out /etc/ssl/private/vsftpd.pem

You’ll end up with a pem file, the patch to which we need to configure into our FTP server:

$ sudo nano /etc/vsftpd.conf

Scroll all the way to the bottom of the file and make sure to comment out (add # sign in front) the keys rsa_cert_file and rsa_private_key, then paste the following lines after the last line in the file:

rsa_cert_file=/etc/ssl/private/vsftpd.pem
rsa_private_key_file=/etc/ssl/private/vsftpd.pem
ssl_enable=YES
allow_anon_ssl=NO
force_local_data_ssl=YES
force_local_logins_ssl=YES
ssl_tlsv1=YES
ssl_sslv2=NO
ssl_sslv3=NO
require_ssl_reuse=NO
ssl_ciphers=HIGH

Exit the editor and restart vsFTPd:

$ sudo service vsftpd restart

There is one last thing to do before we can actually test our new, secured FTP. In our first tutorial, we prevented password authentication which we need to enable back, so open the file:

$ sudo nano /etc/ssh/sshd_config

and locate the line that says PasswordAuthentication then change its value to yes. Close the editor and restart our SSH daemon:

$ sudo service ssh restart

If you’re thinking we just lowered the security of our server a little, you’re right, but have no fear, just install Sshguard that will monitor and prevent any bad activities related to SSH access:

$ sudo apt-get install -y sshguard

And that’s all there is to it! You can test this new configuration in two ways; Either try connecting to the server with an FTP client (choosing SFTP protocol and port 22), or login to your WordPress and install a plugin (choosing FTPS as the connection type).

Conclusion

As you see, installing an SSL certificate is really no big of a deal, and it's definitely a long-term investment in your website and your credibility! Plus, we didn't have to use a plugin, which is always a good idea, since more plugins almost always also mean slower WordPress. One plugin is not problematic, but once you have 20 or more things really tend to slow down.

Next week, I'll teach you how to backup your WordPress site to a Dropbox account - daily!

Questions? Ask below.