Setting up an SSL certificate manually is easy if you're willing to copy/paste some commands into your terminal. I'll explain what they do as we walk through the process.

You can also take a look at the post about SSL certificates with Let's Encrypt for free automatic SSL certificates, with a slightly more complicated setup, still.

Prerequisites

There are a few prerequisites you need to consider before buying and setting up SSL on your server.

You cannot have multiple https domains on the same IP unless you use SNI - but SNI is not supported in older browsers. So what to do? I want to support as many browsers as possible and thus this guide is about installing single domain or wildcard certificates. I don't know if it works for a SNI installation, I haven't tried it, yet.

Ok, so you are still here. Unless your site is the only one running off your web server, you should request an additional IP address from you hosting provider. Theoretically you could use the default IP of the server, but that is shortsighted – your other domains will then respond to https requests but serve the wrong site.

You need access to an super admin mail box, like hostmaster@yourdomain.com or postmaster@yourdomain.com. The certificate issuer will send a confirmation email to one of these addresses (they typically let you choose from 5 different options) and you won't be able to confirm ownership unless you have access to the chosen account.

You need to provide the issuer with a CSR to buy a SSL certificate. A CSR is a Certificate signing request and it contains the information required for issuing a certificate. It also needs to match a private key stored on your server to make the certificate work.

And finally, you need to have SSL enabled in Apache.

Creating a CSR

Your CSR should contain the domain you want to cover with your new certificate. If you plan on using a single domain certificate with and without www, then include www when prompted for the common name value during the coming adventure. That way you get both with and without www in one certificate. If you are setting up a certificate for a wildcard certificate, simply state *.your-domain.tld# as common name.

To create a CSR and matching private key, you can use this command:

openssl req -nodes -newkey rsa:2048 -keyout www_parentnode_dk.key -out www_parentnode_dk.csr

Follow the instructions. Remember, common name should match the domain you want to use for the certificate.

With you newly created CSR, you should be able to complete the purchase.

Obtaining the certificate

A complete SSL certificate is made up of 5-7 files, depending on the specific provider.

A .csr and a .key, which you obtained when creating your CSR. In the example above, this would be www_parentnode_dk.csr and www_parentnode_dk.key

A www_parentnode_dk.crt which you will receive from the issuer after approving the certificate request. This could be delivered as plain text in an email or as a standalone file. It starts with -----BEGIN CERTIFICATE----- and ends with ----END CERTIFICATE----- and is also sometimes referred to as a Web server certificate. If you received it as plain text in an email, copy the certificate content into www_parentnode_dk.crt.

An Intermediate certificate from you issuer and possibly a Root, and or a Validation certificate. The naming of these may vary but all SSL issuers will tell you about this when you receive your certificate. These third-party certificates should be joined into a CA-bundle to achieve the broadest possible support.

Recently I purchased a new certificate from GeoTrust and I found the CrossRootIntermediate.crt and Intermediate.crt by following the instructions on their site. To create a CA-bundle from these files, use the cat command:

cat Intermediate.crt CrossRootIntermediate.crt > www_parentnode_dk.ca-bundle

This will output a CA-bundle, with the content of the two files and now you have all the files ready to install on your server.

Installing the certificate

Now it is time to copy your certificate files to your web server. In case your web server is located on a cloud server, start by copying the files to the server. You can do that with the scp command (secure copy), Fx:

scp www_parentnode_dk.key martin@162.13.86.13:/home/martin scp www_parentnode_dk.crt martin@162.13.86.13:/home/martin scp www_parentnode_dk.ca-bundle martin@162.13.86.13:/home/ scp Intermediate.crt martin@162.13.86.13:/home/martin scp CrossRootIntermediate.crt martin@162.13.86.13:/home/martin

Once you have your certificate files on your server, you need to copy the .key to /etc/ssl/private and the rest to the /etc/ssl/certs folder. That can be done like this:

sudo mv www_parentnode_dk.key /etc/ssl/private/ sudo mv www_parentnode_dk.crt /etc/ssl/certs/ sudo mv CrossRootIntermediate.crt /etc/ssl/certs/
sudo mv Intermediate.crt /etc/ssl/certs/
sudo mv www_parentnode_dk.ca-bundle /etc/ssl/certs/

The files should automatically have the right permissions, but in case of problems check that they are set to -rw-r--r-- 1 root root. That is equivalent to chmod 644. File permissions are a common cause of SSL problems.

Enable SSL in Apache

That's really easy and there is even a command for it. The command looks like this:

sudo a2enmod ssl

Enable SSL for your site

Finally you need to add the new certificates to VirtualHost configuration for your site.

Start by changing your <VirtualHost> scope. The old entry should look something like this:

<VirtualHost *:80>

You should update it to something like this, which tells Apache only to reply to https requests on the stated IP:

<VirtualHost 162.13.86.13:443>

The next step is to specify certificate location and exact SSL handling. There are endless variations, but I found the following to provide the best available encryption without blocking any browsers.

SSLEngine on
SSLCertificateFile /etc/ssl/certs/www_parentnode_dk.crt
SSLCertificateKeyFile /etc/ssl/private/www_parentnode_dk.key
SSLCertificateChainFile /etc/ssl/certs/www_parentnode_dk.ca-bundle SSLProtocol all -SSLv2 -SSLv3
SSLCipherSuite ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA
SSLHonorCipherOrder on
Header always add Strict-Transport-Security "max-age=15768000"

Once you have added the SSL details to your Apache VirtualHost configuration, restart Apache and you are done.

Safe surfing!