title: "Apache on Ubuntu 18.04 on SSL: HTTPS Tutorial with Namecheap and OpenSSL" date: 2020-04-24
This is a tutorial on configuring an Apache web server, running on Ubuntu 18.04 server, to use HTTPS, or HTTP over SSL/TLS1 to encrypt and secure users' communication with your website or web app. This leads to more secure use of your website, particularly if your users are inputting passwords or sensitive information.
A quick search in your favourite search engine will reveal that the web is moving toward https everywhere, and you should too. It's safer. It's better. But it's a bit confusing if you've never done it before.
This is a guide for someone managing an Apache web server of some sort (probably a VPS in the cloud, but could be a virtual machine, a computer in your home [be careful if you're doing that, and definitely use HTTPS] or workplace, or something else), who has http configured, has their website or web app running pretty well, and now wishes to add HTTPS support. You will need shell access to the server you will be adding the certificate to.
The process can easily take several hours if you're not sure where to start, where to look for help, what the various terms mean and what you need, let alone what is modern or deprecated, what is performant, or what is vulernable. My hope is that if the scenario in this walkthrough maps closely to your use case, you will be able to complete the process very quickly (under an hour), understand what you're doing at each step and why, and finish the process with more knowledge than you started, in addition to having a site now working over HTTPS. A picture of the green padlock on the address bar (which is what Firefox uses to indicate the site is using HTTPS) will be our victory flag.
Here is our programme for this evening:
The first step of the process is to request a certificate. I am aware of 3 ways to do this:
I won't be covering option 3 here, as these are not as secure as one validated by a certificate authority (CA). These are fine for internal networks or testing purposes, but should probably be avoided for most productino enviroments. For a bit more on this option, see Wikipedia's entry.
Options 1 and 2 are quite similar, under the hood, though option 2, using Let's Encrypt, may require marginally more technical sophistication than option 1. Maybe not though. In a vacuum, I'd recommend using Let's Encrypt, as they are a great organization worth supporting, they have excellent documentation, and you get, for free, the same level of protection offered by most low-cost certificate authorities.
For the purposes of this article, however, we're going to cover option 1: buying a certificate from a CA. Most hosting providers, like Namecheap and GoDaddy, offer integrations with CA's, to allow you purchase and install certificates, so the friction is pretty minimal. As an example of cost, at the time of this writing Namecheap offers basic certificates for as low as $5.88/yr (higher-tier offerings can be significantly more, $100 and up).
Here are the steps for purchasing a certificate through Namecheap. These steps will, of course, vary according to which provider you use, but I include them here as an example of the process. It is simple enough.
After clicking Activate, you should be brought to a screen that looks like this:
We will come back to this screen after we generate a CSR.
Once you've purchased the certificate, it's time to begin the Certificate Signing Request process.
A certificate signing request (CSR) is a block of text that you submit to a certificate authortity in the certificate activation process. The CSR is a combination of a public key and some information about you (i.e., the the applicant or applicant organization). You can read more about CSRs on Wikipedia:
To generate our CSR, we are going to use a package called OpenSSL. It describes itself this way: "OpenSSL is a robust, commercial-grade, and full-featured toolkit for the Transport Layer Security (TLS) and Secure Sockets Layer (SSL) protocols. It is also a general-purpose cryptography library." We will be using it to generate our CSR.
In Linux land, many distros either ship with, or include in their package
repositories, the [OpenSSL package]. Typing $ which openssl
on GNU/Linux should
indicate whether you have it installed on your server (no output means no
installation). If it's not installed, you should be able to find it in your
pakckage manager easily enough, e.g., in Ubuntu, it is simply $ sudo apt install
openssl
. Installing on BSD, OSX, or Windows I leave as an exercise to the
reader. As a last resort, the source code, Apache-licensed, is available on
openssl.org.
To generate the CSR, first log in to your server, and remove a deprecated config line from the openssl configuration file (found at /etc/ssl/openssl.cnf):
#RANDFILE = $ENV::HOME/.rnd
Then server and run this command to generate your private key and CSR:
$ openssl req -new -newkey rsa:2048 -nodes -keyout {yourdomain.com}.key -out {yourdomain.com}.csr
The program will then prompt you for several pieces of information, about your organizational name, location, etc.
Here are the fields you will be prompted to fill in:
Email Address []:
Please enter the following 'extra' attributes to be sent with your certificate request
A challenge password []:
An optional company Name:
The one that may be confusing here is the "Common Name". This is where you want to put your website address, e.g., yoursite.com.
For basic certificates (known as 'domain validation' certs), like the PositiveSSL one mentioned above, this additional information will not show up to visitors to your site. If you purchase fancier certs with organization validation or extended validation, this information will be publicly visible. See here for more about validation levels of certificates.
This will generate {yourdomain.com}.csr and {yourdomain.com}.key in the directory where you ran the command.
After generating the CSR, you will need to submit it to the certificate authority. Returning to the CSR screen from Step 1, above, paste the contents of the {yourdomain.com}.csr into the text box. These steps will again differ according to the platform you are using, but they should be roughly this (maybe it's a paste, maybe it's an upload).
From here you may be asked to confirm a few details from the certificate.
Next up is Domain Control Validation, a process of demonstrating to the CA that you control the domain for which the certificate is being requested / issued.
After pasting the contents of your CSR, you will be asked to demonstrate Domain Control Validation (DCV). There are 3 ways to do this:
Options 2 and 3 are slightly more involved than option 1, so if possible, I'd recommend the first option. If you are using option 2 or 3, the issuer should provide you with instructions on what file to download or what content the DNS record must have.
If you choose option 1, you should simply receive an email with the files you need to upload to your server: a .crt file, a .bundle file, or maybe both
The next step will be to copy this certicate to your server (see step 4, below).
Assuming everything is in order, the CA will then cryptographically sign a certificate using it's private key, and then send you that certificate.
A certificate file has contents that look like this:
This part might be tricky. You may receive just a .crt file, or you may receive both a .ca-bundle and a .crt file, or maybe just a .ca-bundle file. Some providers may offer different files again. When ordering from PositiveSSL through Namecheap, I receive both both a .crt file and a .ca-bundle file. The .crt file is the certificate file itself, and here is Namecheap's description of the .ca-bundle file: "CA bundle is a file that contains root and intermediate certificates. The end-entity certificate along with a CA bundle constitutes the certificate chain" source. See the linked article for more information.
The first sub-step, which I believe is not strictly necessary, but probably helps (I need to do a bit more digging on this), is to concatenate the ca-bundle file onto the end of the crt file (in Linux, make a backup of your files (probably a .zip with the files), then run cat your-domain.ca-bundle >> your-domain.crt.
sudo/ Now we get into the server-side work. First, you'll need to copy your .crt file (concatenated or not) and your .key (your private key file) to 2 specific directories on the server. On Ubuntu 18.04, you'll want to do this:
These 2 files will be referenced in your Apache config, momentarily.
The next step is to create a site configuration file for Apache to read, that references the .crt and .key files. In Ubuntu 18.04, you'll want to create this in /etc/apache2/sites-available. The simplest way to do it is simply copy the existing HTTP config, then modify a few things:
In case this is unfamiliar - port 80 is reserved for HTTP traffic, while port 443 is reserved for HTTPS traffic.
Then add these lines:
Note: you may have seen a "Listen 443" directive in Apache config files before. You probably don't need to manually add this anywhere with Ubuntu 18.04 and recent versions of apache2. If you look at /etc/apache2/ports.conf, you should see the following block:
<IfModule ssl_module>
Listen 443
</IfModule>
So if the ssl module is enabled, the server will listen on port 443, and the VirtualHost entry you made above will catch the traffic.
Next we'll use the apache command line interface to enable SSL and enable the new site config (run these as sudo/root):
$ sudo a2enmod ssl
$ sudo a2ensite yoursite-ssl
$ sudo apachectl -t
$ sudo service apache2 reload
Note - sudo apachectl -t
checks your config files, and throws an error if there are
syntax problems. Good sanity check before rebooting into a broken server
config.
Pretty self-explanatory.
Navigate to https://yoursite.com and hope that you see the little green padlock (or whatever symbol your browser uses to indicate that the site is using HTTPS).
Now that you have SSL working (hopefully), you will probably want to point all traffic to port 443. There are two basic steps to this - enable the Apache rewrite module, and change your original HTTP Apache config to redirect to your HTTPS one.
sudo a2enmod rewrite
This will enable the rewrite module.
Then, if you want to redirect all traffic to HTTPS, gut your HTTP config. Just keep the following:
ServerName yoursite.com
Redirect permanent / https://yoursite.com
Simple. If you need more complex redirects, for example only using HTTPS with sub-domains or only certain pages, you'll need to do some searching on the web.
If all went according to plan, you will now have a TLS/SSL protected website. Your users can feel safe in the warm glow of encryption, and you can feel good about the bits you're flinging through the aether. If it didn't feel free to email me. Happy serving!
1. HTTPS means both HTTP over SSL and HTTP over TLS. See here for a great article on the difference between SSL and TLSl and here for a tutorial on disabling deprecated SSL and TLS versions, if you so desire, after configuring the HTTPS defaults. To whit: back the tutorial. return