openssl-https
This guide explains how to use OpenSSL to generate certificates that can be used by HTTPS webservers.
We will see both the Self-signed certificate and the CA-signed certificate scenarios.
Note: we will use
*.lvh.me
domains in the examples, as they always resolve to127.0.0.1
(localhost).
Self-signed certificate
Although using a self-signed certificate for your web server is generally discouraged, creating one is actually quite simple, as it basically involves only a single command:
Bash | |
---|---|
Note: see the Caveats section for more details about the certificate generation command.
Note that browsers always show a warning message like this one for self-signed certificates (e.g. Firefox):
See the Testing section to check that your certificate works as intended.
CA-signed certificate
In order to create a CA-signed certificate, let's create a CA (Certificate Authority) first:
Bash | |
---|---|
Then we need to create a CSR (Certificate Signing Request):
Bash | |
---|---|
We also need a ca.srl
file, which will keep track of the serial numbers assigned to certificates issued by the CA:
Bash | |
---|---|
Note: although the serial number maximum length is 20 bytes, we generate only 16 random bytes as the initial serial number, because the serial must always be positive, so we don't want the first byte to be in the
80
-FF
range.
Finally, we can sign the CSR and get the signed certificate:
Bash | |
---|---|
Note: see the Caveats section for more details about the certificate signing command.
Note: as you may have noticed, we need to specify the validity days and extensions in the final signing command instead of the CSR creation one.
See the Testing section to check that your certificate works as intended.
Testing
You can use the following commands to quickly analyze the generated files:
Bash | |
---|---|
You can also start a simple HTTPS web server to test a certificate, like this:
Bash | |
---|---|
Then you can open a web browser and head over to https://example01.lvh.me:4433/.
Note: we are able to use the TCP port
4433
or any other port we want, because X.509 certificates aren't bound to specific ports, but to domain names (or IP addresses) instead.
For production environments, you may also want to generate and use custom Diffie-Hellman (DH) parameters instead of relying on default ones:
Bash | |
---|---|
Caveats
We set the SANs (Subject Alternative Names) to create a wildcard certificate that also covers all the *.example01.lvh.me
subdomains. You can also see that by inspecting the certificate details in a web browser (e.g. Firefox):
We create a leaf certificate by setting the CA
basic constraint to FALSE
. You can also see that by inspecting the certificate details in a web browser (e.g. Firefox):
That prevents users from adding the server certificate to their browsers as a trusted CA:
Links
- Traefik and self signed SSL certs - wekan/wekan Wiki
- X.509 - Wikipedia
- openssl - OpenSSL command line program - OpenSSL Documentation
- openssl-cmds - OpenSSL Documentation
- How To Create a Self-Signed SSL Certificate for Nginx on Debian 10 - DigitalOcean
- How to Be Your Own Certificate Authority (with Pictures) - wikiHow
- OpenSSL Generate CSR non-interactive - Raymii.org
- Unable to use -subj with Windows Git Bash - Issue #8795 - openssl/openssl - GitHub
- Self Signed Certificate with Custom Root CA - GitHub
- How to setup your own CA with OpenSSL - GitHub
- openssl-req, req - PKCS#10 certificate request and certificate generating utility - OpenSSL Documentation
- Creating the Root CA - Roll Your Own Network
- x509v3_config - X509 V3 certificate extension configuration format - OpenSSL Documentation
- s_server - OpenSSL Documentation