Generating self-signed certificates is a common task that every admin needs to do from time to time for any number of reasons. Here’s how to make an OpenSSL configuration file to generate properly formed certificates quickly.
Previously, it was only necessary to specify a common name (cn) that matched your test server and life was good. A while ago though, Google led the charge by making Chrome require SAN entries on all certificates. This meant that self-signed certificates now needed their SAN DNS.1 property specified and matched to the cn. No biggie, but nearly impossible to do via the command-line. So, that’s why a certificate request config file that you can edit and reuse is a great idea. Let’s make one.
OpenSSL configuration file
Open your favourite text editor and type/copy the following text.
default_bits = 4096 default_md = sha256 distinguished_name = dn req_extensions = san x509_extensions = san prompt = no [ dn ] countryName = CA stateOrProvinceName = Alberta localityName = Calgary organizationName = My Techie-Thoughts OU = TESTING CN = myserver.mytechiethoughts.com [ san ] subjectAltName = @alt_names [ alt_names ] DNS.1 = myserver.mytechiethoughts.com DNS.2 = altserver.mytechiethoughts.com DNS.3 = somanynames.mytechiethoughts.com
The value for DNS.1 MUST match CN or the certificate will be invalid. Following that line of reasoning, if your system has no alternate names, then only list DNS.1.
I’d suggest saving this somewhere that’s easy to find and with a name that makes sense. I’m partial to naming my file /etc/ssl/selfsigned.cnf. That’s what I’ll be using throughout this post.
What everything means
Curious, aren’t you? If you’re actually not, then skip this section. If you are, then go ahead and expand the following sections!
request stanza (unlabelled)
|default_bits||This is the RSA key size we want to use. You can change this to 2048 as a minimum, but most modern systems can easily generate a 4096 bit key.|
|default_md||The default digest algorithm we want to use. SHA256 is the default here in most cases. Note that Google-stuff sometimes barfs if you exceed SHA384. Run “openssl list –digest-commands” to see all your options.|
|distinguished_name||Tells OpenSSL to read the [ dn ] section when forming this certificate’s distinguished (full) name. You can specify any name, like [ name ], for example. Just remember to update the rest of the file.|
|req_extensions||Tells OpenSSL to read the [ san ] section when assigning extensions to our request. You can specify any name, like [ othernames ], for example. Just remember to update the rest of the file.|
|x509_extensions||Tells OpenSSL to read the [ san ] section when assigning extensions to our certificate. Again, you can use any name just like above. In this configuration, you should be referencing the same section as above.|
|prompt||We say ‘no’ here so that OpenSSL just reads our defaults and doesn’t bother us with prompts.|
Distinguished Name (dn) stanza
|countryName||The ISO standard two-letter abbreviation for the certificate subject’s country of residence.|
|stateOrProvinceName||Full name of the State, Province, Canton, etc. where the certificate subject is located.|
|localityName||The region/city/village/etc. where the certificate subject is located.|
|organizationName||The company, organization or individual to which the certificate subject belongs.|
|OU||This means ‘organizational unit’ and is optional. I use ‘TESTING’ for all my test certificates. In larger companies, you may use department names like “HR”, “Finance”, etc.|
|CN||This MUST match the primary DNS name of your server.|
Subject Alternate Name (san) stanza
In this section we just refer OpenSSL to an array list of alternate names for the subject of our certificate. In this case, I called it alt_names but you can call it anything you want. The ‘@’ just means it’s going to be an array list.
Alternate Names (alt_names) array
Here we list alternate names that our certificate’s subject answers to and should also be covered by the certificate we’re issuing. Pay attention to DNS.1 – it MUST match your certificate’s common name otherwise the certificate is invalid on face! That’s why we’re making this file in the first place since you can’t really specify SANs on the command line.
Issue the certificate and self-sign
Here’s the magic – just run this command:
openssl req -new -x509 -days 365 -nodes -out /etc/ssl/certs/mycert.crt -keyout /etc/ssl/private/mycert.key -config /etc/ssl/selfsigned.cnf
Let’s go though what that all means quickly:
|req||Process a certificate signing request.|
|-new||Create a new request and, since we’re not supplying a key, generate a key for us.|
|-x509||Generate a self-signed certificate.|
|-days||How long should this certificate be valid for? A year is good. Less than 90 days will generate warnings in most browsers.|
|-nodes||Don’t encrypt the generated private key. If it’s encrypted, we need to enter a password every time we use it!|
|-out||Where to save the issued certificate.|
|-keyout||Where to save the generated private key. Make sure you choose a safe spot!|
|-config||Tell OpenSSL to use the fancy configuration file we created in the last step!|
Optional: Add to local trusted certificates
If you want your (I assume Debian-based) system to trust your certificate, it’s a good idea to add it to the trusted store that’s contained in the /etc/ssl/certs/ca-certificates.crt file. While you can just do this yourself, there is a script that makes it super easy. Follow these steps:
- Copy your generated self-signed certificate to /usr/local/share/ca-certificates/ and make sure it has the extension .crt
update-ca-certificates. It should report that it imported 1 certificate.
Reusing your configuration file
Whenever you need to generate other self-signed certificates, simply change the CN parameter and update the alt_names list as necessary. Remember that DNS.1 MUST match CN or the certificate is invalid. Then run the same openssl command and generate your new certificates :-) If you need to trust the certificate, just go through the same procedure in the previous section with your new certificate.
That’s it! You have a properly formed self-signed certificate you can use for all sorts of testing, etc. Remember that other systems will not trust this certificate unless you install it on them first! That’s why self-signed certificates are usually just for test purposes. Otherwise, knock yourself out getting whatever you need setup and running with your shiny new certificate.
Thanks for reading my techie-thoughts on this issue. Have any comments or suggestions? Want to add your tips? Things you want me to cover in a future article? Comment below!