DANE TLSA records updater using certbot internals
Go to file
2024-04-13 17:37:03 +02:00
assets Adding README.md 2024-04-13 17:37:03 +02:00
scripts Intermediate commit 2024-03-23 18:36:08 +01:00
src/daneupdate More certbot_emu logic fixing 2024-04-09 22:55:03 +02:00
.gitignore Update 2024-02-14 17:45:36 +01:00
.isort.cfg Initial commit 2024-02-12 16:49:19 +01:00
config.sample.yaml Rearrange configuration data 2024-04-08 19:59:48 +02:00
credits.txt Comparing existing records with required 2024-04-05 17:01:46 +02:00
LICENSE Initial commit 2024-02-12 16:49:19 +01:00
pyproject.toml Restructure things, parsing config 2024-02-15 16:44:16 +01:00
README.md Adding README.md 2024-04-13 17:37:03 +02:00
requirements.txt Py3.9 compatibility 2024-04-07 17:58:24 +02:00


Python-based TLSA records updater hooking into certbot internals. It entirely replaces the certbot renew command, managing renewals and proper certificate rollovers. It aims to provide the same renewal functionality that certbot does, added with the TLSA record management.

The earliest supported Python version is 3.9 now.


This tool was born out of my need to rotate TLSA records for rotated certificates of hostnames that serve TLS encrypted traffic. The idea came in light of the jabber.ru MitM attack. There are a couple alternative TLSA record managers out there (e.g. letsdns, shuque's generator, or letoams's hash-slinger) but none of those served my needs properly, that is to handle rollovers with external daemons using the certificates, without having to hack around significantly.

As mentioned in the related certbot issue, this tool manages the rollover the following way, when a certificate renewal is due:

  • Daneupdate (hooking into certbot) gets a newly signed key and certificate, puts it into the upcoming directory
  • Immediately places a TLSA record next to the original one
  • Waits for 24 hours (customizable) to pass for DNS caches to expire, then moves the certificate from the upcoming directory and set it as live (by symlinking to the latest version, also done by hooking into certbot internals)
  • After another 24 hrs (also configurable), it is assumed that the respective daemons have reloaded and are using the new certificate
  • At which point, the 'old' TLSA record can be cleared.

All of this happens upon repeated execution of daneupdate renew, for which cron is the ideal candidate.

At its current state, daneupdate uses the DNS update (with TSIG) method to delete/set TLSA records. It can be expanded in the future, but this fits my current needs. Feel free to open a PR if you have made code changes to fit your scenario.



Just clone this repo and execute scripts/install-freebsd.sh. It will install daneupdate into a virtualenv and also use the FreeBSD ports patch to make certbot see the custom certificate directory paths.


Using python and a virtualenv is the easiest way:

  • Clone the repo (master branch should suffice), cd into its directory
  • python -m venv venv
  • . venv/bin/activate
  • python -m pip install -U pip wheel setuptools
  • python -m pip install -e .
  • You can then symlink venv/bin/daneupdate (the full path of it) into /usr/bin or whatever path you prefer, as to be able to execute it without its full installation path.

Maybe an installer script for Linux would be nice, PRs for that are also welcome. I use FreeBSD as a server platform, and thus I use install-freebsd.sh, that does the job.



After having the tool installed, make a copy of the sample configuration file to a directory that will persist between installations — assuming you're using docker or some kinda automated FreeBSD jail redeployment like I do). This directory — and the configuration files within — is best be restricted to be read by root (or the user you use to renew certificates).

After having copied the sample configuration, use your infrastructure properties to set up proper values in the copied file.

Certificate maintenance

You still have to use certbot for getting your initial certificates. This tool only manages the renewal of them.

For all supported commands, use daneupdate -h or daneupdate -c <path-to-your-config-yaml> <command> -h for help on the respective subcommands below.

If you have a certificate installed, you can use daneupdate to adopt the hostname associated with it:

Listing adoptable certificates

daneupdate -c <path-to-your-config-yaml> list-adoptables will list hostnames with certificates that can be adopted by daneupdate.

Adopting a certificate

daneupdate -c <path-to-your-config-yaml> adopt hostname [hostname ...] will adopt one or more hostnames from the aforementioned list. It will put its runtime configuration file at the path you've configured in your config.yaml.

When having adopted a certificate, you can look into the runtime configuration and make changes to fit your needs. The structure of the file is explained at the commented version at the start of the runtime configuration.

Upon adoption, daneupdate will set up the initial TLSA records. You can skip that with specifying -s or --skip-tlsa-update. Then, you can use update-tlsa to add/update the respective records later on.


daneupdate -c <path-to-your-config-yaml> renew [hostname ...]

This command will renew all the adopted certificates and set up TLSA records for them, when necessary. The necessity of a renewal is checked by using certbot internals (should_update()).

You can specify one or more hostnames, in which case only those will be processed for renewal.

This is the command you want to put into cron, replacing certbot renew with it.

Manually updating TLSA records

daneupdate has an update-tlsa command that will only run the TLSA updates on an adopted certificate configuration, or on all of them.

Errors, bugs

This tool is not foolproof, so bugs might occur. Also, it is not responsible for a code exception due to misconfiguration. Having a proper infrastructure set up with the right configuration values and TCP port 53 access to your DNS server is your job.

That said, if you find something that you think is a bug that is not a result of a misconfiguration, feel free to open an issue, or submitting a PR with a fix is even better.


I have the following platforms, should you want to drop me a couple bucks :)


Buy me a coffee (or more): https://www.buymeacoffee.com/karolyi

Paypal: https://paypal.me/masterkarolyi

I also used to have a Github: https://github.com/sponsors/karolyi

Patreon: https://www.patreon.com/karolyi

For more generous donations, feel free to contact me :)