With your own Certificate Authority you can get rid of browser security warnings and you don't need to import single site certificates, only the CA root certificate once.
Creating your own Certificate Authority is useful when you run multiple intranet web servers or software with an web interface (Like Routers, PFSense, OPNSense, ESXI etc.).
In this How-To we focus on Https and Browsers, but you can also use your CA for mail servers, databases and other applications.
Like on the internet, instead of generating a self-signed certificate, you generate an private key and a Certificate Signing Request (CSR) from your webserver. With your Certificate Authority keys you generate the public certificate (CRT) for the CSR, which you install on your webserver.
Once your clients trust your CA, they are going to also trust the signed certificate.
An DNS server in your network makes things easier, especially since Chrome 65, else you could also use the hosts file (/etc/hosts
on Linux) in order to set up FQDNs.
Openssl needs to be installed too and your web server needs support for SSL (mod_ssl etc.).
Most software with an web interface, like PFSense or ESXI, allow you to generate a Certificate Signing Request directly from it.
On your Linux computer (not on the server!) use openssl to generate the CA's private key and root certificate.
$ openssl genrsa -aes256 -out ca.key 4096
Generating RSA private key, 4096 bit long modulus
..........................................................................................................................................................................++++
............++++
e is 65537 (0x010001)
Make sure you put in a secure passphrase, this prevents anyone with the private key file to generate root certificates without it.
Next we generate the root certificate for the clients of our CA with 3 years validity. For compatibility reasons we generate an PEM and CRT file.
$ openssl req -x509 -new -nodes -key ca.key -sha256 -days 1095 -out ca.pem
Enter pass phrase for ca.key:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Texas
Locality Name (eg, city) []:Austin
Organization Name (eg, company) [Internet Widgits Pty Ltd]:bytee.net
Organizational Unit Name (eg, section) []:security
Common Name (e.g. server FQDN or YOUR name) []:bytee.local
Email Address []:contact@bytee.net
Converting the PEM file to a CRT file:
$ openssl x509 -in ca.pem -inform PEM -out ca.crt
You now have three files, your private key (ca.key) and your root certificate (ca.pem and ca.crt).
Congratulations your CA is ready to be deployed!
Installing the CA root certificate is quite forward on most Linux distributions. First create a directory for extra certificates in /usr/share/ca-certificates
, if you want want you could also use /usr/local/share/ca-certificates
:
# mkdir /usr/share/ca-certificates/extra
Next copy the CA .crt
file to this directory:
# cp ca.crt /usr/share/ca-certificates/extra
Finally run update-ca-certificates
to generate a new concatenated Linux ca-certificates.crt
file, which Linux uses system-wide for validating certificates.
Please note that Firefox and Chrome don't use the system-wide certificates on Linux. You need to import the certificate in your browser manually. For Chromium / Chrome just navigate to
chrome://settings/certificates
, choose Authorities and click on Import.
As example, we are going to generate a certificate request for an Apache Web Server and the domain web.bytee.local. For most other web servers, like NGINX it's similar.
First you need to generate the private key for the Apache vhost:
$ openssl genrsa -out web.bytee.local.key 4096
Next generate the certificate signing request (CSR):
$ openssl req -new -key web.bytee.local.key -out web.bytee.local.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:US
State or Province Name (full name) [Some-State]:Texas
Locality Name (eg, city) []:Austin
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Bytee.net
Organizational Unit Name (eg, section) []:web
Common Name (e.g. server FQDN or YOUR name) []:web.bytee.local
Email Address []:info@bytee.net
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
With your CA key you can now generate the public certificate (CRT) for the web server.
Starting with Chrome 65 we need to supply subject alternative names (DNS names) to the certificate though, else Chrome is going to show an error message. To prevent this, you need to include an external file in the generation, call it web.bytee.local.ssl.conf
with this content:
subjectAltName = @alt_names
[alt_names]
DNS.1 = web.bytee.local
DNS.2 = web
Now you are ready to sign it:
$ openssl x509 -req -in web.bytee.local.csr -CA ca.pem -CAkey ca.key -out web.bytee.local.crt -days 1095 -sha256 -extfile web.bytee.local.ssl.conf
Signature ok
subject=C = US, ST = Texas, L = Austin, O = Bytee.net, OU = web, CN = web.bytee.local, emailAddress = info@bytee.net
Getting CA Private Key
Enter pass phrase for ca.key:
Now configure Apache to use the newly generated certificate (private key + crt file) and reload the service.
For any other server (or vhost) just repeat the last steps of generating the CSR and creating the CRT.