Today, when trying to log in remotely to my home router (a FRITZ!Box), I was greeted with an TLS certificate error. I was pretty sure it’s my router, but am I really keen to type in a password into a field that I have no idea whether it is actual my machine, or a nice-looking replica? A clear indication that it is time to use a better cert than a self-signed one that I cannot verify remotely.
I use Let’s Encrypt for all my other certificates, so why not use it on my router? However, I found precious little information about how to use it with the FRITZ!Box. Fortunately, it’s pretty straightforward.
There is no obvious way to run certbot
straight onto the router, except perhaps when running Freetz, but that is not my case (yet?). So I’m still running FRITZ!OS (6.83 at the time of this writing) which, though not entirely free and sometimes annoying, generally works well.
The next best choice is simply to use certbot
on a machine behind the router, with adequate redirection of its port 80 from the box (it’s actually my public server, in the DMZ).

The next step is, simply, to run cerbot
as usual on the internal server, with the desired domain. I prefer the webroot method, as it doesn’t require restarting my webserver.
sudo certbot certonly -d ${DOMAIN} --webroot --webroot-path /var/www/
Once the certificate issued, all the cryptographic material ends up in /etc/letsencrypt
, in either live
of keys
, for the certificate and private key, respectively.
We need to transfer both those files to the FRITZ!Box, but the relevant form only allows one file to be uploaded, in PEM format. PEM has this nice property that, thanks to its delimiter, multiple files can be concatenated into one. This turns out to be just what the FRITZ!Box needs.
sudo cat /etc/letsencrypt/live/${DOMAIN}/privkey.pem /etc/letsencrypt/live/${DOMAIN}/fullchain.pem > ~/fritz.pem

Note that this file is pretty sensitive, so one would do well do delete any other copy of it once uploaded to the router.

A remaining issue is to automate the renewal of the certificate when needed. certbot
will do it automatically if set up to do so (e.g., via cron or other scheduling mechanism), but the upload part still needs to be manual; the main issue is that FRITZ!OS is pretty-close to a one-page app now, and there doesn’t seem to be any canonical URL that can be used to upload the renewed certificate with, e.g., cURL.
EDIT 2018-08-15: As discussed in the comments below, there are ways to use the FRITZ!Box API endpoints to automatically upload the certificate. Thanks to wikrie’s example, I ended up writing a small Python CLI utility that takes care of the authentication and certificate upload. It should be usable as a library to build upon (particularly the authentication piece). Let me know in the comments if you did something good with it!
Here you find a Skript for autoupdate
https://gist.github.com/wikrie/f1d5747a714e0a34d0582981f7cb4cfb
Thanks for that, Walker.
Unfortunately, I didn’t quite manage to get your script to work for me.
This, however, was sufficient to get me going on a Python equivalent, that I have dumped here https://gist.github.com/shtrom/3d701d4856c9abc8c0ca53811604f27e