Little helper scripts - Part 3: My homelab CA management scripts
Part 2 of this series is here: Little helper scripts - Part 2: automation.sh / automation2.sh or use the following tag-link for all parts: https://admin.brennt.net/tag/littlehelperscripts
My homelab situation
Like many IT enthusiasts I run my homelab with various services. And of course HTTPS (and SSL/TLS in general) plays a crucial role in securing the transport layer of applications. And using a self-signed certificate without a CA is possible, but then I would get certificate warnings constantly and always would have too add each certificate in every browsers list. Having my own self-signed CA enables me to add the CA certificate once into every browser/truststores an all devices and be done with that.
While I happily use Let's Encrypt on all services reachable via Internet (using getssl or Apache's mod_md as ACME clients) I can't do so for my homelab domains. The reason is that I deliberately choose lan.
as TLD for my home network to prevent overlap with any other registered domain/TLD. And while lan.
is current not used/registered as an official TLD it is also not listed/reserved a Special-Use Domain Name by the IANA. Hence Let's Encrypt won't issue certificates for that domain as it can't verify the domain.
If course I can get in trouble when lan.
is ever registered as a official TLD. But I doubt that will happen at all.
Managing your own self-signed Certificate Authority
Years ago I read Running one's own root Certificate Authority in 2023 and used the scripts to create my own self-signed CA (GitHub). I created my CA certificate using the cacert.sh
script and new certificates for domains got create with hostcert.sh
. The sign.sh
script is called automatically to sign the CSRs but can also be called separately. This worked for a few years.
However recently I noticed that some features are missing. As the logic to add SubjectAltNames only supported DNS AltNames and had some shortcomings. Commit 56fe6a93675818a483be3abe02cc1ac963a76aed fixed that.
The change was rather easy. Just add some regular expressions to differentiate between DNS, IPv4 and IPv6 altnames and add them with the right prefix to the X509v3 Subject Alternative Name
extension (DNS altnames have to be prefixed with DNS:
and IP altnames with IP:
).
Generating a new certificate with DNS, IPv4 and IPv6 altnames
Now my hostcert.sh
supports the following:
user@host:~/ca$ ./hostcert.sh service.lan 192.168.1.114 2a00:2d:bd11:c569:abcd:efff:cb42:1234 service-test.lan
CN: service.lan
DNS ANs: service.lan service-test.lan
IP ANs: 192.168.1.114 2a00:2d:bd11:c569:abcd:efff:cb42:1234
Enter to confirm.
writing RSA key
Reading pass from $CAPASS
CA signing: service.lan.csr -> service.lan.crt:
Using configuration from ca.config
Check that the request matches the signature
Signature ok
The Subject's Distinguished Name is as follows
countryName :PRINTABLE:'DE'
localityName :ASN.1 12:'City'
organizationName :ASN.1 12:'LAN CA'
commonName :ASN.1 12:'service.lan'
Certificate is to be certified until Jul 5 23:08:40 2026 GMT (365 days)
Write out database with 1 new entries
Database updated
CA verifying: service.lan.crt <-> CA cert
service.lan.crt: OK
And the resulting certificate is also fine:
user@host:~/ca# grep "X509v3 Subject Alternative Name" -A1 service.lan.crt
X509v3 Subject Alternative Name:
DNS:service.lan, DNS:service-test.lan, IP Address:192.168.1.114, IP Address:2a00:2d:bd11:c569:abcd:efff:cb42:1234