Self-signed certificates (SSCs) are less than ideal. The most problematic effect of using an SSC generating numerous warnings from browsers and tools using SSL or TLS, but all of the usual information security limitations also apply. These limitations include weak authentication of remote services, potential issues with application that rely on SSL or TLS to your own servers, and so on. SSCs do not possess a suitable trust chain to a known trusted issuer, and therefore application support can be patchy and interrupt UX.
SSCs are not great if you intend to use your system on other untrusted networks, as it's possible an application will generate a prompt to accept a new SSC from a destination on an untrusted network, and, inadvertently, you accept a certificate from a malicious target. It's much better to build trust through your own CA-generated certificates, to better handle these kinds of eventualities.
Self-signed certificates have advantages. For private IP ranges, it is difficult to find a reputable CA (i.e., a CA that your OS and browser trusts) that will issue a certificate for a private IP. They are quite easy to generate and are sometimes auto generated by server applications. You can self-validate them. In some cases, they can be quick and easy to use and deploy. They are also relatively easy to use compared to establishing your own CA.
However, with EasyRSA, a tool for managing X.509 PKI, it is not that difficult to build your own internal CA. In this blog post I run through the setup of EasyRSA on an Ubuntu server. We’ll then walk through the process of adding the new CA to the trusted roots of a Windows 10 system.
It makes a lot of sense to set up an internal DNS service using Bind for your home network. This provides a lot of flexibility, and is relatively easy to do. I won’t go through this here – a good guide to get started is this article on DigitalOcean and there are many similar guides.
In your forward zone, ensure you have IN A records present for the host names you wish to create certificates for. These can point to the same IP address.
Some examples you may wish to create are:
Where server1 is the first server to create a certificate for.
The installation command is as follows:
# apt install easy-rsa
For simplicity I’ve put this under /home, but there are likely to be more secure options particularly if you are intending to use EasyRSA in a production environment:
# mkdir /home/myca && cd /home && make-cadir myca
This file contains a number of settings to customise for your installation. Updating the following lines in the file to suitable values will complete this step:
# These are the default values for fields
# which will be placed in the certificate.
# Don't leave any of these fields blank.
export KEY_COUNTRY="UK"
export KEY_PROVINCE="England"
export KEY_CITY="London"
export KEY_ORG="Your_organisation_name"
export KEY_EMAIL="Your_email"
export KEY_OU="Your_organisation_name"
# X509 Subject Field
export KEY_NAME="Your_default_key_name"
When executing commands with EasyRSA, you’ll need to load the vars file into the current session. Use the following command:
# cd /home/myca
# . vars
Use the following command:
# ./build-ca
Follow the prompts given. Ensure the "Common Name" refers to the DNS name of the server for the CA. Once complete you will have created your root CA issuing authority. We will later export this certificate and add it to the trusted certificates store under Windows, to ensure subsequent certificates are recognised. The security of the information generated at this stage is critical, as it is the basis of all of the trust for the internal CA.
In a similar way, generate the intermediate CA using the following command:
# ./build-inter interca.yourdomain
Again follow the prompts, ensuring the Common Name reflects the interca DNS entry created in your Bind (or equivalent) internal DNS service. The CA has now been created and can be used to generate certificates as required.
Build a certificate for a host using the following command:
# ./build-key-server server1.yourdomain
Follow the prompts, ensuring the Common Name reflects the corresponding entry in internal DNS for the server.
Export the certificates for the root and intermediate CAs to target devices. How this is done is dependent on your setup. By one means or another, ensure you can get the ca.crt file (located in the "keys" folder) and "interca.yourdomain.crt" files onto the local file system of the target device.
On Windows 10, double-click the ca.crt file and click "Install Certificate". Add this to the "Current User" and manually specify the trust store selecting "Trusted Root Certification Authorities". Similarly, install the Intermediate CA crt file under "Intermediate Certification Authorities".
It's not strictly necessary to add the intermediate CA to the trust store, however Windows does provide the service for this and it can sometimes help if a suitable chain is not presented by a remote application due to a misconfiguration.
Install the server-specific crt files and associated key files into the required applications. Restart services as required.
This is more or less the sequence of steps needed to create a rudimentary Internal CA using EasyRSA, though you’d need to implement further steps to achieve a baseline assurance level.
This has significant limitations, both technical and assurance. These considerations plus a couple of other points are worth bearing in mind:
Internal CAs are complex animals, requiring significant policy, standard, and procedure wraps, supporting operational processes and similar. For most businesses, hiring the services of an external consultant is essential if an Internal CA is to achieve the assurance required.
January 16, 2021