Skip to main content

Bash script to generate self-signed SSL certificates for local development in macOS.

#!/usr/bin/env bash

#
# Generate Self-Signed SSL Certificates for Local Development On A Mac
#
# Have you ever need to develop HTTPS sites locally? To make it work you need to
# generate a SSL certificate of your own and tell your computer to trust it so
# you don't get weird Your connection is not private errors in your browser.
#
# See Github home page for help and usage:
# https://github.com/kingkool68/generate-ssl-certs-for-local-development
#
# Author: Russell Heimlich <https://github.com/kingkool68/generate-ssl-certs-for-local-development>
# Date: October 27, 2018
#


# -------------------------------------------------------------
# certificate-authority-options.conf
# -------------------------------------------------------------
# [req]
# prompt = no
# distinguished_name = req_distinguished_name

# [req_distinguished_name]
# C = US
# ST = Fake State
# L = Fake Locality
# O = Fake Company
# # OU = Org Unit Name
# # emailAddress = info@example.com
# CN = local.dev
# -------------------------------------------------------------
# /certificate-authority-options.conf
# -------------------------------------------------------------


# -------------------------------------------------------------
# options.conf
# -------------------------------------------------------------
# authorityKeyIdentifier=keyid,issuer
# basicConstraints=CA:FALSE
# keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment
# subjectAltName = @alt_names

# [alt_names]
## Local hosts
# DNS.1 = localhost
# DNS.2 = 127.0.0.1
# DNS.3 = ::1

## List your domain names here
# DNS.4 = local.dev
# DNS.5 = another-domain.dev
# DNS.6 = yet-another-domain.dev
# -------------------------------------------------------------
# /options.conf
# -------------------------------------------------------------


# -------------------------------------------------------------
# generate-ssl.sh
# -------------------------------------------------------------
# Make sure this script is run as root
if [ "$EUID" -ne 0 ] ; then
        echo "Please run as root. Try again by typing: sudo !!"
    exit
fi

function command_exists () {
    type "$1" &> /dev/null ;
}

# Make sure openssl exists
if ! command_exists openssl ; then
        echo "OpenSSL isn't installed. You need that to generate SSL certificates."
    exit
fi

NAME=$1
if [ -z "$NAME" ]; then
        echo "No name argument provided!"
        echo "Try ./generate-ssl.sh name.dev"
    exit
fi

## Make sure the tmp/ directory exists
if [ ! -d "tmp" ]; then
    mkdir tmp/
fi

## Make sure the your-certs/ directory exists
if [ ! -d "your-certs" ]; then
    mkdir your-certs/
fi

# Cleanup files from previous runs
rm tmp/*
rm your-certs/*

# Remove any lines that start with CN
sed -i '/^CN/ d' certificate-authority-options.conf
# Modify the conf file to set CN = ${NAME}
echo "CN = ${NAME}" >> certificate-authority-options.conf

# Generate Certificate Authority
openssl genrsa -des3 -out tmp/${NAME}CA.key 2048
openssl req -x509 -config certificate-authority-options.conf -new -nodes -key tmp/${NAME}CA.key -sha256 -days 1825 -out your-certs/${NAME}CA.pem

if command_exists security ; then
    # Delete trusted certs by their common name via https://unix.stackexchange.com/a/227014
    security find-certificate -c "${NAME}" -a -Z | sudo awk '/SHA-1/{system("security delete-certificate -Z "$NF)}'

    # Trust the Root Certificate cert
    security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain your-certs/${NAME}CA.pem
fi

# Generate CA-signed Certificate
openssl genrsa -out your-certs/${NAME}.key 2048
openssl req -new -config certificate-authority-options.conf -key your-certs/${NAME}.key -out tmp/${NAME}.csr

# Generate SSL Certificate
openssl x509 -req -in tmp/${NAME}.csr -CA your-certs/${NAME}CA.pem -CAkey tmp/${NAME}CA.key -CAcreateserial -out your-certs/${NAME}.crt -days 1825 -sha256 -extfile options.conf

# Cleanup a stray file
rm your-certs/*.srl

echo "All done! Check the your-certs directory for your certs."
# -------------------------------------------------------------
# /generate-ssl.sh
# -------------------------------------------------------------