Setting a custom HTTPS certificate in Tomato, AdvancedTomato, or FreshTomato

I’m transitioning all of my local network services toward using an internal CA, but AdvancedTomato is a little trickier in that regard because it doesn’t have support for loading a custom cert or key in the web UI.

Instead, you must connect over SSH and modify the certificate files manually, then write them to nvram. Simply upload cert.pem and key.pem to the root home directory, then save this shell script:

cp ./cert.pem /etc/cert.pem
cp ./key.pem /etc/key.pem
sed -i "/END CERTIFICATE/q" /etc/cert.pem
/bin/tar -C / -cf /tmp/cert.tar etc/cert.pem etc/key.pem
/bin/gzip -f /tmp/cert.tar
nvram set https_crt_file="$(/usr/sbin/openssl enc -base64 < /tmp/cert.tar.gz | tr -d '\n')"
nvram commit
service httpd restart

Running this script should update the certificates. However, you may find that it fails to load the key you provided, and instead regenerates its own. You can usually tell because the restart takes a while and prints a bunch of periods while generating a new key. If you think it hasn’t worked, run cat /var/log/messages and look for the following:

daemon.warn httpd[21376]: Unable to start SSL httpd[21376]: Generating SSL certificate... httpd[21392]: Tomato interface started successfully

This indicates that it couldn’t read your certificate for some reason. For me, this happened because I was trying to use a 4096-bit RSA key, and the combined certificate and private key was simply too large for it. Dropping down to a 2048-bit RSA key solved the problem.

Update 2020-05-18: AdvancedTomato isn’t receiving updates any more. I’ve switched to FreshTomato and I recommend doing the same. The information in this post works just the same on FreshTomato.