Much to my pleasure, many home based devices (routers, media players, IoT etc) are moving away from unencrypted HTTP and moving to HTTPS. To their credit each is generating it’s own self signed certificate. That in of itself is fine however you have to tell your browser to trust every cert. If you are one of those using Firefox for Android, you have to manually override every time (annoying).
What I needed was a certificate authority. Yes, I know about Let’s Encrypt, it’s a wonderful free service. The downside is those public certificates have to be renewed every X months and the devices has to be internet facing (Requiring a static IP & DNS entry). Unfortunately routers don’t use the ACME protocol (yet?).
Goals:
I’ve managed to narrow down the entire process to two script files using OpenSSL
The below script should only be run once to generate your CA key pair. Warning: If you run this a second time it will wipe all of your generated keys!
create-ca.sh
#!/bin/bash
rm cacert.srl
rm -rf keys
openssl genrsa -out cakey.pem 2048
openssl req -x509 -new -nodes -key cakey.pem -sha256 -days 36500 -out cacert.pem -subj '/C=US/ST=New York/L=New York/O=Acme/CN=Acme CA'
mkdir keys
The below script will generate key pairs in PEM format. Be sure to specify your fully qualified hostname or the certificate may not work.
gen-key.sh
#!/bin/bash
if [ "$1" == "" ]; then
echo "Specify FQDN host name"
exit
fi
openssl genrsa -out "keys/$1-key.pem" 2048
openssl req -new -subj "/C=US/ST=New York/L=New York/O=Acme/CN=$1" -key "keys/$1-key.pem" -out "keys/$1.csr"
openssl x509 -req -CAcreateserial -CA ./cacert.pem -CAkey ./cakey.pem -in "keys/$1.csr" -out "keys/$1-cert.pem" -extfile <(printf "subjectAltName=DNS:$1")
rm "keys/$1.csr"
This will let your browser know it’s ok to trust your newly minted key pairs.
Run the following commands to install. You must use a unique name for the .crt file
openssl x509 -inform PEM -in cacert.pem -out /usr/local/share/ca-certificates/myca.crt
update-ca-certificates
Thanks to The Jeroen HD blog for these instructions.
In most cases the PEM format is fine but there are exceptions:
These keys need to be converted to DER format. I added the following lines to gen-key.sh
openssl x509 -in keys/$1-cert.pem -outform DER > "keys/$1-uhttpd.crt"
openssl x509 -in ./cacert.pem -outform DER >> "keys/$1-uhttpd.crt"
openssl rsa -in keys/$1-key.pem -outform DER > "keys/$1-uhttpd.key"
Once done copy the two files to /etc/uhttpd.crt & /etc/uhttpd.key on the device and reboot.
Created: 2025-04-15 | Modified: 2025-04-16 |