July 2, 2020

SSL certificate for your local domain and internal IPs

I have a home server setup that is behind double NATs so I can't (and honestly don't want to) access my home server from the outside of my network. For the past couple of years I have been using HTTP only to access my server. Today I thought that it's enough! I want to see that sweet green lock of HTTPS on my server links. So I decided to pick this mini project up. It was quite frustrating at first because every article I read expected that user had a static IP and a domain. Now, in my case this was not possible since I only wanted SSL inside my home network. So I collected a bunch of info from different sources and put together in the easiest possible way below.

The idea here is to become your own Certificate Authority (CA) and issue the certificates for your local domains or internal IP addresses. (Note: I use local domains only. Ex: deluge.homeserver, vscode.homserver etc. These domains are resolved through a local DHCP RaspberryPi server)
Let's dive in.

Root SSL certificate

The first step is to create a Root SSL certificate. This root certificate can then be used to sign any number of certificates that you will generate for local domains.

Generate an RSA-2048 key and save it to a file called rootCA.key. This file will be used as the key to generate the Root SSL certificate. You will be prompted for a pass phrase which you’ll need to enter each time you use this key to generate a certificate.

openssl genrsa -des3 -out rootCA.key 2048

You can use this generated rootCA.key to create a new Root SSL certificate. Save it to a file named rootCA.pem. This certificate will have a validity of 3650 days (10 years).

openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 3650 -out rootCA.pem

Trust the root SSL certificate

Before you can use the newly created Root SSL certificate to start issuing domain certificates, there’s one more step. You need to to tell your Mac/PC to trust your root certificate so all the individual certificates issued by it are also trusted.

Open Keychain Access on your Mac and go to the Certificates category in your System keychain. Once there, import the rootCA.pem using File > Import Items. Double click the imported certificate and change the “When using this certificate:” dropdown to Always Trust in the Trust section.

Issue individual domain SSL certificate

The root SSL certificate can now be used to issue a certificate specifically for your local server.
Create a new OpenSSL configuration file server.csr.cnf so you can import these settings when creating a certificate instead of entering them each time.

prompt = no
default_bits = 2048
default_md = sha256
distinguished_name = dist

[email protected]
CN = localhost [or insert ip address of your server]

Create a v3.ext file in order to create a X509 v3 certificate.

keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
subjectAltName = @alt_names

DNS.1 = code.homeserver
IP.1= [IP.1 IP.2 for ip addresses or DNS.1 for DNS names]

Create a certificate key for local server using the configuration stored in server.csr.cnf. This key is stored in server.key.

openssl req -new -sha256 -nodes -out server.csr -newkey rsa:2048 -keyout server.key -config <( cat server.csr.cnf )

In case you are using Fish shell:  

openssl req -new -sha256 -nodes -out server.csr -newkey rsa:2048 -keyout server.key -config ( cat server.csr.cnf | psub)

A certificate signing request is issued via the root SSL certificate we created earlier to create a domain certificate. The output is a certificate file called server.crt.

openssl x509 -req -in server.csr -CA rootCA.pem -CAkey rootCA.key -CAcreateserial -out server.crt -days 500 -sha256 -extfile v3.ext

Use your new SSL certificate

You’re now ready to secure your local server with HTTPS. Move the server.key and server.crt files to your Nginx or Apache directory and include them in the .conf files.


How to get green padlock in Firefox -

Even if the rootCA.pem was trusted in my Mac I was getting security warnings in Firefox. So I had to trust the rootCA.pem in Firefox manually -
Import the rootCA.pem in Firefox Preferences > Privacy and Security > View Certificates > Authorities > Import

  • LinkedIn
  • Tumblr
  • Reddit
  • Google+
  • Pinterest
  • Pocket