How to Use SSL/TLS Locally

Words by NJI
Published November 25, 2015
Last Updated July 18, 2024

PART II OF TWO

PART I

Encryption is everywhere and for many websites very important. When building a website or application that will require encryption, it’s best to develop in a test environment with encryption available. This post is written for web developers, specifically OS X or Ubuntu users, and it describes exactly how to set up TLS (SSL) on a local development stack running Apache. Familiarity with using terminal and basic configuration of a website on the Apache web server is assumed.

Overview

A general procedure to use HTTPS locally:

  1. Generate a security key
  2. Use the key to generate a Certificate Signing Request [CSR]
  3. Use the CSR to generate a self-signed certificate
  4. Install the certificate on the web server
  5. Configure the browser to trust the self-signed certificate

Requirements

This article uses the OpenSSL Toolkit to generate the certificate. OS X comes with openssl installed. Install openssl on Ubuntu if you don’t already have it.

Generate a KEY and CSR

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

The script will prompt for the following information. Most of this information will be publicly visible to anyone inspecting the certificate.

  • Country Name
  • State or Province Name
  • Locality Name
  • Organization Name
  • Organizational Unit Name
  • Common Name
  • Email Address
  • Challenge

The Common Name must match exactly the hostname intended for use. If the local site uses the domain name domain.dev, enter exactly that for the Common Name value. Leave blank the values for both Email Address and Challenge.

Alternatively, one could also generate the key and CSR separately, using the following commands:

openssl genrsa -out domain_dev.key 2048 
openssl req -new -sha256 -key domain_dev.key -out domain_dev.csr

The values in the CSR can be verified afterwards, using the following:

openssl req -noout -text -in domain_dev.csr

Create a Self-Signed Certificate

In the same directory, use the key and CSR to create a temporary identity certificate, good for 365 days. The certificate produced is “self-signed, meaning the party responsible for validating identity is the very identity in question. As a result, there is an inherent trust issue, which will be handled later.

openssl x509 -req -days 365 -in domain_dev.csr -signkey domain_dev.key -out domain_dev.crt

The file domain_dev.crt is created as a result of this command. This file is the self-signed identity certificate.

When generating one’s own certificate, it is possible to produce the key, the CSR, and the certificate in a single command. This article describes the processes separately to reinforce the purpose of the different components in the certificate recipe. Also, when obtaining a certificate from a trusted Certificate Authority for use on a production website, one would only need to produce a key and a CSR; these instructions are valid for that purpose as well.

Install the Certificate

Certificate installation is nothing more than storing the certificate and key in a place the web server can access, and configuring the Apache Virtual Host to use them. However, setting up support for SSL (TLS) differs depending on the server OS and version of Apache. An Apache module named mod_ssl must be installed and enabled.

Ubuntu 14.04

Currently, Ubuntu 14.04 is the most recent distribution with Long Term Support. It ships with an Apache package which includes mod_ssl. To enable mod_ssl, run the following command:

sudo a2enmod ssl

RHEL / CentOS

If you prefer Red Hat or CentOS, the setup process is similar. Install the module and the OpenSSL Toolkit like so:

yum install mod_ssl openssl

Apache must be restarted for the changes to take effect.

Configure an Apache Virtual Host

When a port number is not specified with a request, as is often the case, browsers automatically try the default port associated with the specified protocol. The Internet Assigned Numbers Authority is the official registry of standard port numbers. All browsers can be relied upon to use the default port. By default, HTTP protocol uses port 80. HTTPS uses port 443 by default.

To start using HTTPS for development and testing, simply enable the SSL Engine and include the key and the certificate in a Virtual Host listening on port 443:

<VirtualHost *:443>
  ServerName domain.dev
  DocumentRoot /server/path/domain.dev/web/

  <IfModule mod_ssl.c>
    SSLEngine on
    SSLCertificateFile /server/path/secret/domain_dev.crt
    SSLCertificateKeyFile /server/path/secret/domain_dev.key
    SetEnvIf User-Agent ".*MSIE.*" nokeepalive ssl-unclean-shutdown
    CustomLog /server/path/logs/ssl_request_log \
      "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
  </IfModule>

</VirtualHost>

Don’t forget to restart Apache, likely:

Ubuntu

sudo service apache2 restart

Red Hat

sudo systemctl restart httpd

Of course, there is much more to explore; this article provides the minimum needed to start rocking HTTPS. Here is Apache’s official documentation for using HTTPS, getting the SSL module loaded, and configuring listening on port 443. Read about using TLS instead of SSL in Part I, or dive into the module details.

Trust Management for Self-Signed Certificates in OS X

Done? Nope. Because the certificate is not signed by a trusted authority, the browser will still complain that the certificate is not valid.

privacy error

In Firefox, it may not be possible to add a permanent exception without an add-on. Permitting the exception every time Firefox is restarted may be necessary, but it will work.

A web browser window displays the URL "https://domain.dev" with a drop-down notification showing that a secure connection is established. The notification says, "You have added a security exception for this site," with buttons for "More Information" and a close icon.

Using Chrome, it is possible to permanently configure trust for the self-signed certificate. That post by Rob Peck is a great reference and still works nicely. To summarize, use Chrome to inspect the invalid certificate, drag it to your desktop, then open it with the Keychain Access app to configure a permanent trust exception.

Three screenshots displaying a web browser's security warnings and certificate information for a webpage. The first warns of a privacy error on "domain.dev," suggesting users should not proceed. The second shows certificate details, and the third confirms the certificate's trust settings.

Configuring SSL In MAMP

If you’re using MAMP, heaven help you. And by heaven, I mean the people of Stack Overflow. If this drives you bananas, give Vagrant a gander.