As a Application Security Engineer/Security Researcher, I spend a lot of time tinkering within my home lab. Unfortunately, my home lab has become more than just a habit….. an obsession maybe? However, you can check out some incredible home lab setups by checking out this subreddit r/homelab. I recently posted my current server rack setup, you can find that post here.
Regardless of spending money and time tinkering within my home lab, I have never had a chance to setup a proper SSL Cert management system. I was always reminded with the self-signed certificate error messages from Firefox or Chrome.
So I decided lets go ahead and create a super simple opensource cert management system with OpenSSL.
I had a basic understanding of creating/brute-forcing certificate, however the terms “RootCA” and “Intermediate CA” was just a basic theory knowledge, not practical. So I ran to google to assist me in creating a Root certificate for internal application. I quickly ran into a ton of different “methods” of creating certs, some of these “methods” definitely was not best practice.
Risks with Wildcard certificates
I have seen many companies buy a Wildcard cert for their domain, example:
And then just upload it to each server and viola, it works! Very Bad idea! The issue with just buying a wildcard cert from Godaddy or Comodo is that everyone will trust that cert. You might be thinking, isn’t that the idea? Buy a wildcard cert and be done with it? The answer is yes….. and no.
The problem with throwing a wildcard cert on every server is if that certificate gets compromised you now must get a new certificate for each server you used that wildcard certificate on. That might be hundreds if not thousands of servers that will need a new certificate. The other big issue is if that certificate gets compromised the attacker can use it to spin up their own service and pose as the domain that is using the wildcard certificate.
The correct method is to generate a root certificate with the following code:
$> sudo openssl genrsa -aes256 -out rootCA.key 4096 $> sudo openssl req -x509 -new -nodes -key rootCA.key -sha256 -days 1024 -out rootCA.crt
This will create your .crt and .key for you root certificate. The root cert will be valid for 1024 days, you may want to change this value. Best practice has the root cert valid for twice as long as the Intermediate certificate. So if your root cert is valid for 1024 days, you should set your Intermediate certificate for 512 days. Another thing you want to consider is to create a really strong password for your root cert. If this password is weak and easily brute forced then an attacker may be able to impersonate your domain with your root certificate.
Now that we have our root certificate created lets move on to the Intermediate certificate. This is where I initially had a lot of issue. I ran into multiple issue with Firefox trusting my Intermediate certificate but IE and Chrome rejected it. I finally came a crossed this blog from google that described that you must use the “X509 version 3” standards which includes multiple DNS entries as well as an IP entry within the certificate, you can find that blog/support entry here.
I have also created a markdown document on my GitHub that outlines step-by-step for creating your root and Intermediate certificate which can be found here. Follow the following code to create your Intermediate certificate:
$> sudo openssl req -new -sha256 -nodes -out <CERT NAME.csr> -newkey rsa:2048 -keyout <KEY NAME.key> -config config.cnf
Before you run the command above you will need to create these two documents for the configuration of your certificates.
# server_rootCA.csr.cnf [req] default_bits = 2048 prompt = no default_md = sha256 distinguished_name = req_distinguished_name [req_distinguished_name] C=US ST=TN #State L=Knoxville #City O=Sorsnce LLC #Company OU=IT #Department emailAddressemail@example.com CN = subdomain.sorsnce.com #FQDN
# v3.ext authorityKeyIdentifier=keyid,issuer basicConstraints=CA:FALSE keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment subjectAltName = @alt_names [alt_names] DNS.1 = subdomain.sorsnce.com IP = 192.168.8.15
Signing the Intermediate Certificate
Now we need to sign the Intermediate certificate with the Root certificate. You can do that with the following code:
$> sudo openssl x509 -req -in <CERT NAME.csr> -CA rootCA.crt -CAkey rootCA.key -CAcreateserial -out <CERT NAME.crt> -days 512-sha256 -extfile v3.ext
You must enter the password you set for the root certificate, this will sign the Intermediate certificate with the keys from the root certificate.
Pushing the Root Certificate out
The last step in our process will include pushing/installing the root certificate on our endpoints. You can achieve this in multiple ways such as, GPO, BigFix, or SCCM. For myself I just manually installed my root CA on my endpoints.
All-in-all I am happy with my current set-up for managing my internal SSL certificates. However I might write a blog post in the future with ways to automate this processes with containers and make it more fluid rather than a manual process.