Table of Contents


When performing any data transfer over a network, the information is sent in pieces of data called packets. Packets have basic information about where it originated, where it is going, how much data it contains, and how to interpret its contents. For example, here is an HTTP response packet from a simple website:

HTTP packet in Wireshark

The contents of this packet are plaintext: anyone who intercepts this packet can read its contents. SSL encrypts the TCP layer of this packet, rendering the main contents unreadable by anyone except the recipient for whom it is intended. Here is the same packet, only encrypted with a 2048-bit RSA key.

HTTPS packet in Wireshark
Note: The routing information must remain unencrypted, and there is no way around this. By analogy, The address and return address on a letter cannot be obscured because the letter carrier needs to know where to deliver the letter.

Technically, this stuff is called Transport Layer Security (TLS). TLS is the successor to Secure Socket Layer (SSL) and offers better security, but I call everything here SSL for synchronicity between it and the openssl program used... and because just about everyone else still calls it SSL.

SSL can be used to encrypt just about anything: web pages (HTTP), emails (POP, IMAP, SMTP), and file transfers (FTP) to name a few. Here we will focus on securing HTTP since it is the most common use-case.

Motivation and Goals

Anyone who has set up a site with a self-signed "snakeoil" certificate is familiar with the following panicky message:

Browser screaming an untrusted connection message

This strong message is annoying to us developers/administrators and is quite unsettling for our users. Personally, I think this page would be more appropriately displayed on any page that is not loaded over HTTPS: anything could happen to a plaintext packet in transport, and neither the browser nor the user would notice.

Caution: If you ever encounter this message in the wild, please do take it seriously: it means exactly what it says. When visiting a website whose identity cannot be verified by another trusted party, the choice is left up to the user to indicate whether they trust the site or not. This is usually an indication that a malicious site is posing as a legitimate website.

Think of it like this: suppose we are friends with Alice and Bob, but they have never met before, so we decide to introduce them. Alice feels she can trust Bob because she trusts us as a friend, and Bob feels he can trust Alice for the same reason. In this scenario, we play the role of the trusted certificate authority, and Alice and Bob take turns playing the roles of browser and server.

It is important to note that the information transferred over said untrusted connection is still secure: the information is being encrypted on the server, transmitted to the browser client, and decrypted for display in the viewport. The only hiccup in the process is that the browser cannot verify the source of the content. To continue with the analogy, imagine Alice and Bob meeting as strangers in a restaurant. In this case, they would have to establish trust on their own, which is a lot harder than "piggybacking" on the trust of a mutual friend.

For reference, here is a handy chart showing the different levels of trust and security:

HTTP Plaintext HTTPS (Untrusted) HTTPS (Trusted) HTTPS with Login HTTPS with Client Cert
Data Encryption
Verified Site Identity
User Identity
Verified User Identity

One way to remedy the "untrusted" warning is to purchase a SSL certificate signed by a recognized certificate authority. This method is generally preferred if many users will be accessing the website securely. If only a handful of known users will access the site for a very specific purpose, then it may be more beneficial to save the money and install a certifice yourself. The certificate may be self-signed or signed by a custom certificate authority. The latter option is the primary focus of this tutorial.

Once installed, certificates must be marked as trusted. Self-signed certificates must be marked as trusted individually since each one is entirely unique. Certificates that are signed by a certificate authority can be validated by following the chain of signatures back to the root certificate. The decision to trust the certificate comes from whether the client trusts all of the certificates in the chain. This tutorial will explain how to configure client operating systems and browsers to trust a custom authority.

Finally, as depicted in the table above, SSL allows for users to supply their own certificates as a more secure authentication mechanism. This tutorial also explains how to accomplish this.

Without further ado, let's dive in!