/fritz-tls

Automate TLS certificate installation for AVM FRITZ!Box

Primary LanguageGoMIT LicenseMIT

Build Go Report Card

FRITZ!Box TLS Certificate Installer

This is a little pet project to install TLS certificates into your FRITZ!Box. I use Let’s Encrypt to get free certificates and I got tired using this tedious process to update the certs all the time. So I started to poke at my FRITZ!Box Fon WLAN 7390 and now it is automated!

Although it should work with other versions as well, it is only tested with:

  • FRITZ!Box Fon WLAN 7530 (FRITZ!OS: 07.59)
  • FRITZ!Box 7490 (FRITZ!OS: 07.57)

In case you want to know how to do that manually, take a look at AVM's knowledge base article.

Installation

Homebrew:

brew install tisba/taps/fritz-tls

Go

go get -u github.com/tisba/fritz-tls

Usage

fritz-tls --domain fritz.example.com

Done :)

General options for fritz-tls are:

  • --help to get usage information
  • --host (default: http://fritz.box) to specify how to talk to your FRITZ!Box. If you want to login with username and password, specify the user in the URL: --host http://tisba@fritz.box:8080.
  • --insecure (optional) to skip TLS verification when talking to --host in case it's HTTPS and you currently have a broken or expired TLS certificate.
  • --verification-url (optional) to specify what URL to use to check certificate installation. Defaults to --host.
  • --authcheck (optional) to only check if the provided credentials are valid.

fritz-tls can install any TLS certificate or acquire one using Let's Encrypt.

Let's Encrypt Mode

By default, Let's Encrypt is used to acquire a certificate, options are:

  • --domain the domain you want to have your certificate generated for (if --host is not fritz.box, --domain it will default to the host name in --host).
  • --email (optional) your mail address you want to have registered with Let’s Encrypt expiration service.
  • --save (optional) to save generated private key and acquired certificate.
  • --dns-provider (default manual) to specify one of lego's supported DNS providers. Note that you might have to set environment variables to configure your provider, e.g. AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_REGION and AWS_HOSTED_ZONE_ID. I use name servers by AWS/Route53 and inwx, so I have to provide INWX_USERNAME, INWX_PASSWORD. I'm not sure if there is a overview, so for now you have to consult the source.
  • --dns-resolver (optional) to specify the resolver to be used for recursive DNS queries. If not provided, the system default will be used. Supported format is host:port.
  • --force-renew to force a renewal, even if the current certificate is valid for the requested domain and still valid for at least the next 30 days.

Manual Certificate Installation

You can also provide a certificate bundle (cert + private key) directly to fritz-tls so they can be installed:

  1. obtain your TLS certificate, e.g. via Let’s Encrypt.
  2. install the newly generated certificate:
fritz-tls --key=./certbot/live/demo.example.com/privkey.pem --fullchain=./certbot/live/demo.example.com/fullchain.pem
  • --key and --fullchain to provide the private key and the certificate chain.
  • --bundle as an alternative for --key and --fullchain. The bundle where the password-less private key and certificate are both present.

Renew Automation

You can use cron (on Linux) or launchd (on macOS) to run fritz-tls automatically. By default, it will check if the cert is still valid and only renew if the remaining validity is less then 30 days. Check out https://www.launchd.info to learn how launchd can be used or use https://launched.zerowidth.com to generate a plist file.

TODOs and Ideas

These are some things I'd like to to in the future:

  • add validation for private keys and certificate before uploading (avoid trying to upload garbage)
  • allow password protected private keys (when not provisioned by LE)

Make Release

Releases are done via Github Actions on push of a git tag. To make a release, run

git tag va.b.c
git push --tags