Add SSL/TLS encryption

Overview

SSL/TLS ("SSL") is a protocol for encrypting the traffic to and from a website. We have all used it: an encrypted site has the green padlock and uses HTTPS rather than HTTP before the URL.

We want to add this to any site which requires the user to enter sensitive data in a form or which delivers sensitive data to the user. So any site with login functionality, such as the Tech Club, needs to be encrypted. By not doing this, we make it much easier for a malicious person to read the sensitive data and even to impersonate the user (see Review of security).

In this guide we will look at adding SSL to the Tech Club application, the live demo of which is at techclub.macinntech.com. I register my .com sites with NIC.COM so I will use one of their certificates, shown above. However I have also used a RapidSSL certificate at a client and that was fine too.

Process

Here's a summary of what we need to do:

  1. Generate private key and CSR (info + public key)
  2. Decide which type of certificate we want, then buy it
  3. Configure Apache
  4. Configure our firewall - the AWS security group
  5. Test it

Firstly, we need to generate a private key which will stay on the server.

  1. SSH into the server: ssh -i /path/to/my-key-pair.pem ubuntu@{Elastic IP}
  2. Generate the key, change the key name accordingly: sudo openssl genrsa -out techclub.macinntech.com.key -des3 2048
  3. Make up a passphrase, save in KeePass2, then enter it here twice

Now we need to generate a certificate signing request ("CSR") for the key, which contains information about the domain to be protected and the public key, the other half of the encryption key pair.

  1. Generate the CSR, change the .csr and .key names accordingly: sudo openssl req -out techclub.macinntech.com.csr -new -key techclub.macinntech.com.key
  2. Enter the key passphrase
  3. Now we need to answer a bunch of questions about the organization. Tip - for more help in answering these questions, please see here:
    • Country Name: I am saying DE since I am based in Germany at the moment. List of country codes here.
    • State or Province Name: Berlin for me
    • Locality Name: Berlin for me again
    • Organization Name: hm, I'm just hitting Enter here because the Tech Club doesn't actually exist
    • Organizational Unit Name: Enter again for me
    • Common Name: this is the super important bit. For me, it's techclub.macinntech.com because I want SSL on that subdomain only. If you're doing it for a normal domain, enter the domain WITH the extension but WITHOUT www, so example.com. The www is included automatically. If you want a wildcard certificate (see below), use *.example.com
    • Email Address: I have read in some places that it should best be left blank, in other places that it should be entered. I entered mine
    • Challenge Password: I leave it blank, we already have a password on the private key
    • An optional company name: Doesn't seem so official, so I entered Tech Club

Now we buy the certificate. The exact details will obviously vary depending on the certification company you use, but as we saw in the picture from NIC.COM above, there are generally 3 types of SSL certificate for a domain and we need to choose the appropriate one:

  1. Standard SSL - for a single domain or subdomain. So I could use it for macinntech.com OR for techclub.macinntech.com
  2. Premium SSL - for a single domain or subdomain, but it looks like the organization is also verified and the full organization name is shown in the URL bar. So I could use it for macinntech.com OR for techclub.macinntech.com and users would see something like what is shown in the URL bar on the right side of the NIC.COM picture above
  3. Wildcard SSL - for a domain and all its subdomains. So I could use it for macinntech.com, techclub.macinntech.com, anotherproject.macinntech.com, etc

For the Tech Club, we don't need a Wildcard. It comes down to Standard or Premium, and I'll choose Standard because it's much cheaper and the Tech Club doesn't exist yet as an organization in any case.

The process for me with NIC.COM was as follows:

  1. Purchase 1 year Standard SSL
  2. Confirm payment
  3. An SSL certificate is added my account
  4. Click on the certificate and chose the option "Set up"
  5. It asks for the CSR as shown above. By the way, I remember with RapidSSL the process was a bit different - I had to enter the CSR details before payment
  6. Display the CSR in the terminal: less techclub.macinntech.com.csr
  7. Copy everything, from the start of -----BEGIN CERTIFICATE REQUEST----- to the end of -----END CERTIFICATE REQUEST-----
  8. Paste it into the certification company's form shown above
  9. Check that the Domain Name field now properly displays "techclub.macinntech.com" rather than "None"
  10. In the terminal, close the CSR file with q
  11. Wait for NIC.COM to verify my ownership of the domain and sign and create the certificates. i didn't have to do anything, since my domain is registered with them. With RapidSSL the domain was registered elsewhere and so I had to verify my phone number and also verify that I had access to the "webmaster@" email address
  12. After about 3 minutes I am redirected to a screen which lets me download the certificates
  13. I download the zip to my computer, unzip it, and I have 2 .crt files. By the way, I recall that with RapidSSL the certs were embedded in the email itself, so I had to copy them into a text editor and save the .crt files that way
  14. The .crt files have awkward names, so I rename them. One is named as the serial number of my certificate, so this is the certificate itself, and I rename it to cert.crt. The other has the word "bundle" in the name, I rename this to chain.crt, since this one establishes the chain of trust between the server and NIC.COM. This crt was known as "intermediate" with RapidSSL, it's the same thing
  15. I use FileZilla to upload the files into /home/ubuntu on the server

Move key and certs out of /home/ubuntu and into their proper places on the server.

  1. Move the key to the private SSL directory: sudo mv techclub.macinntech.com.key /etc/ssl/private
  2. Move cert.crt to the SSL certs directory: sudo mv cert.crt /etc/ssl/certs
  3. Same for chain.crt: sudo mv chain.crt /etc/ssl/certs

Now we have the private key and the certificates in the right places on the server and we are ready to do the configuration.


Configure Apache.

  1. Enable the SSL module: sudo a2enmod ssl
  2. Open the Virtualhost file for the (sub-)domain: sudo vi /etc/apache2/sites-available/techclub.macinntech.com.conf
  3. At the very top of the file, we need to tell Apache that this is now a Virtualhost for HTTPS, not HTTP. Change <VirtualHost *:80> to <VirtualHost *:443>
  4. Below the existing configuration, add the following lines, change the KeyFile name as needed:
    • SSLEngine on
    • SSLCertificateFile /etc/ssl/certs/cert.crt
    • SSLCertificateKeyFile /etc/ssl/private/techclub.macinntech.com.key
    • SSLCertificateChainFile /etc/ssl/certs/chain.crt
  5. NOTE: if you are doing this for a full domain or a wildcard (all subdomains too), you will want to tell Apache to ignore port 80 (HTTP) altogether, and only listen for requests on port 443 (HTTPS). To do this, open sudo vi /etc/apache2/ports.conf and comment out Listen 80. I'm not doing this because I need to listen on both ports since macinntech.com will remain HTTP and only techclub.macinntech.com will be HTTPS
  6. Test the new Apache config: sudo apachectl configtest, ensure it says Syntax OK
  7. Restart Apache: sudo service apache2 restart
  8. Enter the passphrase of the private key. We will automate this step below, since it would be annoying to type it each time

Configure AWS. All we need to do here is change the inbound security settings to allow requests into port 443 for HTTPS.

  1. Log into AWS and go to EC2
  2. Go to Security Groups on the left
  3. Right click "my-security-group" (the name we gave the security group from Deploy the server)
  4. Choose "Edit inbound rules"
  5. Click "Add rule", then choose Type HTTPS, make sure Source is Anywhere, as shown, then click Save
  6. NOTE: if you are doing this for a full domain or a wildcard, you will want to remove HTTP altogether, and only allow requests via HTTPS

Now it should work! Test 3 things:

  1. Check that the parts of the site that were meant to be unaffected, remain so. For me, this means for example refreshing this page
  2. Check that you can't access the SSL'd (sub-)domain with HTTP any more, e.g. http://techclub.macinntech.com/
  3. Check that you can access the SSL'd (sub-)domain with HTTPS now, e.g. https://techclub.macinntech.com/. Congratulations!

Finally, we do a bit of configuration to prevent us from having to type in the private key passphrase each time we restart Apache.

  1. Make a new file which will simply echo the passphrase: sudo vi /etc/ssl/pp.sh
  2. Add this line: #!/bin/sh
  3. Then this line, using your passphrase: echo "<passphrase>"
  4. Make it executable: sudo chmod 715 /etc/ssl/pp.sh
  5. Open the Apache SSL module config: sudo vi /etc/apache2/mods-available/ssl.conf
  6. About 25% down you will find the SSLPassPhraseDialog directive. Replace that line with: SSLPassPhraseDialog exec:/etc/ssl/pp.sh
  7. Restart Apache: sudo service apache2 restart and ensure you don't get asked for the passphrase anymore


comments powered by Disqus