tdnss
Table of contents
A Python API wrapper for Technitium DNS Server.
TLDR
I was looking for a DNS server that fits the needs of my homelab (mainly A and CNAME records) and came with an API. Technitium's fit the bill, so I'm developing this wrapper to interact with the server programmatically.
The DNS Server
I started my self-hosted adventure by installing Pi-hole on a Raspberry Pi. When I started using Docker in my homelab, I tried Adguard Home. Both are good at what they aim to do: block ads in a home network at the DNS level.
However, when serving self-hosted apps with HTTPS a domain name is required to use LetsEncrypt and thus a DNS server is needed to resolve the domains to (local) IP addresses. Both servers implement a way of customizing the response to queries about certain domains (Pi-hole calls it Local DNS, Adguard calls it DNS Rewrites). What they both lack is a way of configuring these responses without using their web interface. At that point I was testing out more applications and having to constantly add new records was proving tedious.
So I started looking for a self-hosted DNS server that came with an API capable of configuring these settings from the comfort of the command line. I found Technitium DNS server (TDNSS for short), an authoritative DNS server and recursive DNS resolver with an extensive HTTP API. It goes well beyond what I was looking for: the list of features says as much.
The API is the same used by the web console, so it can be used to configure absolutely everything that can be set through the web UI. For me, the important part is being able to configure A and CNAME records for my VMs and apps. It can even do Split Horizon, which means serving different responses depending on the origin of the query.
So the only thing missing for me was a way to interact with it through a script.
Sure, I could just use curl, but I've decided to develop tdnss
, a Python
wrapper of the API. The idea is to then develop a CLI tool using this wrapper,
probably using
Typer,
or maybe even an Ansible module to go along with my playbooks.
Progress
I was quite close to finishing a first version of the wrapper when version 9.0 of the Server came out, which made significant changes to start leveraging API tokens1. So, while the changes are backwards-compatible, I've decided to update at least the basic functions before releasing the code.
These functions are available in the first release of the wrapper, version 0.1.0. The code itself is available on Codeberg, while a Python package is available on PyPI.
Before this update, the user obtained a short-lived session token, which expired 30 minutes after the last interaction with the server.