This repo contains helpful and easy to use utilities for managing the public key infrastructure (PKI) at your organization, or for yourself. You can do a lot here:
- Generate a Root Certificate Authority
- Create Intermediate CAs, like a TLS, Code-signing, or Email CA
- Sign and issue web server certificates for your domains
- Create personal email and browser PKCS-12 certificates for email and web-based authentication
This project heavily utilizes OpenSSL and requires Bash.
- Introduction
- Creating a Root Certificate Authority
- Creating Intermediate Certificate Authorities
- Creating a Web SSL Certificate for a Domain
- Creating a Client SSL Certificate
- Final Notes
All of the utilities are in the bin
directory. These files use the config
files in the etc
directory. There's no reason to ever edit any thing in these
two folders.
When you run the tools, they will create the folders ca
, certs
, and crl
.
These will contain your generated certificates, private keys, certificate
signing requests, certificate revocation lists, database, and serial files that
OpenSSL generates.
The first thing you'll want to do is create the Root CA. This is the master certificate and key that will sign all of the Intermediate CAs. Intermediate CAs are the TLS CA for signing both web server and web client certificates, the Software CA for signing software packages, and the Email CA for signing S/MIME certificates.
Structuring your PKI hierarchy this way allows the Root key to stay private or behind multiple layers of security. The Intermediate keys, if ever exposed, could be revoked without putting the entire system in jeopardy. This is a best practice that we'll adhere to in these utilities.
Update the config
file in this directory to have the correct names and info.
These names will be embedded into the certificates.
To generate the Root CA:
$> ./bin/root-ca.sh
This will guide you through the set-up process. It will create the following files and folders:
/ca
Certificate Authority files/root-ca
Root CA files, certificates and signing requests/db
Root CA database and serial files/private
Key files, this is untracked in gitRootCA.key
Private key file for Root CA
RootCA.crt
Certificate fileRootCA.csr
Signing request file
/crl
Ceritificate revocation listsRootCA.crl
Public revocation list file, this should ultimately go on your webserver. The URL will be embedded into certificates.
Now that we have the Root CA, we'll create all of the Intermediate CAs. The only required one to finish this guide is the TLS CA but it's simple to generate them all.
3.1 Run Utilities
To generate the TLS CA:
$> ./bin/tls-ca.sh
This will guide you through the set-up process. It will create the following files and folders:
/ca
/tls-ca
TLS CA files, certificates and signing requests/db
TLS CA database and serial files/private
Key files, this is untracked in gitTLSCA.key
Private key file for Root CA
TLSCA.crt
Certificate fileTLSCA.csr
Signing request fileTLSCAChain.pem
Chained certificate file containing the Root and TLS CA certificates.
/crl
TLSCA.crl
Public revocation list file, this should ultimately go on your webserver. The URL will be embedded into certificates.
Similar files are created for the other two Intermediate CAs. To generate the Software CA:
$> ./bin/software-ca.sh
To generate the Email CA:
$> ./bin/email-ca.sh
The TLS CA is used to sign web server certificates, which is the most common application and use-case for PKI and probably why you're here :P
Creating a new server certificate is simple, and you can just follow the on-screen instructions. Just make sure to read the few instructions included. Please remember these three things:
- The fully qualified domain name (FQDN) is usually of the form www.domain.com.
- When adding FQDNs at the beginning, add both the www and non-www domains. For example, both www.example.org and example.org. The script will prompt you to add as many as you'd like. You can probably even do a wildcard but I haven't tested that yet.
- When adding the
Organization Name
during the CSR questions, make sure it's the same "Company Name" you have in yourconfig
file. Otherwise, the process will halt and you will have to start over! This is an OpenSSL quirk.
To generate a new web server certificate:
$> ./bin/server.sh
This will create the following files and folders:
/certs
Server and client files/tls-ca
TLS CA signed files/private
Key files, this is untracked in gitexample.org.key
Private key file for your web domain. Your web server will need this file.
example.org.crt
Web domain certificate fileexample.org.csr
Signing request fileexample.org.bundle.pem
Certificate bundle containing the server's signed and issued certificate, the Intermediate TLS CA's certificate, and the Root CA's certificate. Your web server will need this file.
An often unused, but very powerful security mechanism is PKCS-12 client
certificate authentication. These are certificates issued to people or devices
that are signed by the Intermediate CA and grant that person or device access to
the web server. In nginx, this is done by using ssl_client_certificate
and
pointing that config optionto the TLSCAChain.pem
file copied to your web
server.
This utility will generate a password protected .p12
file that the user can
import into their web browser. You can then set up your web server to optionally
require a client certificate for access. This client certificate replaces the
need for the user to keep a password and provides greater security to any
application.
To generate a client certificate:
$> ./bin/client.sh
Here are some helpful notes:
- This will prompt you to create a password for the client's private key. Make sure you enter one at least 4 characters long or the script will halt.
- During the CSR process, it will ask your for the "Organization Name". Make
sure this is the same as the "Company Name" in the
config
file. - During the CSR process, enter the user's name into the "Common Name" field, and enter their email address into the "Email Address" field.
- You will need the TLS CA private key password to sign this client certificate.
The following files are generated:
/certs
/tls-ca
/private
stallman_richard.key
Private key file for the client.stallman_richard.p12
P12 browser bundle file. This needs to be imported into the browser along with the trusted Root CA certificate file.
stallman_richard.crt
Client certificate filestallman_richard.csr
Signing request file
At the end of the script, you are asked if you want to generate a "client
certificate bundle". This is the .p12
file from earlier. If you do this, you
will be prompted for a name to embed into the file. This name will display to
the user when they are asked by their browser to select a certificate.
You do not need to enter an export password but it is strongly recommended that
you do. The .p12
files should be treated like private keys since they contain
both the public and private key parts.
Always make sure .key
and .p12
files remain untracked. This is automatically
done for you through .gitignore
files but it's important that you know this.
These files should also be chmod 400
to protect them on the web server.
Your web server will want the example.org.key
and example.org.bundle.pem
files for it to load the SSL correctly. If you're using client certificates,
also copy over the TLSCAChain.pem
file.
Once you create a server certificate, your browser will not immediately trust
it. To do this automatically for all server certificates that you create, add
your Root CA certificate file to your browser's list of trusted authorities.
This is the file RootCA.crt
(or similarly named) in the ca
folder.
If you're on MacOS, double click this file and make sure you open it again in KeyChain, expand the Trust tab, and ensure that everything is always trusted.
For Chrome, go to Settings -> Show Advanced Settings -> Manage Certificates. This will prompt KeyChain in MacOS or show you a window with an Authorites tab. If you see the Chrome Certificates window, then go to the Authorities tab and click "Import" and select the Root CA certificate file. Make sure you trust this authority.
For Firefox, go to Preferences -> Advanced -> Certificates and click "View Certificates". Click the Authorities tab and then click "Import" and select the Root CA certificate file. Make sure you trust this authority.
You may need to restart your browser for this to take effect, since SSL is often cached.
Here is a list of the current limitations and planned updates:
- There's no way to revoke certificates really. This is needed to be added as as a command in some of the scripts.
- CRLs would then need to be inspected to see if they're working with the revokations. CRLs are also difficult to get onto a public web server. This problem, if solved, should be documented here.
At this point, it's still somewhat unclear to me what the databases and serial files are that get generated. I think I need to spend more time with revokations to understand that.