Linux Systems Administration

A bind9 Rest API tool – bind-rest-api

I made an API for bind9! Want to see it in action – jump to here in the setup vid:

Recently I have been looking for an api for a bind server. I found an existing project,, which is quite nice but didn’t have some of the functionality I needed. I looked at updating the existing project, but instead decided to write a new API from scratch, inspired by that project.

So what I have written is:

  • FastAPI-based framework
  • input validation, provided by FastAPI
  • Ability to create, replace, get, and delete DNS records
  • Ability to get JSON dump of whole DNS zonefile
  • auto-created documentation from API framework

The project lives here:

I’ve also make a docker image for running the project easily:

I have made a demo video of myself setting up the project on my machine:

Participation is welcome! If you have questions or encounter issues don’t hesitate to leave a comment or get in contact:

14 replies on “A bind9 Rest API tool – bind-rest-api”

Thanks for your work. Can you explain how the username and password work? What do I need to configure on BIND’s end?

Hello Jay,

Great job, I will try to implement your code.
Just to confirm me, I would like to be able to modify multples zones included on the db bind9 files.
It will be OK ?

Take care


Hi Thomas,
Yes it should be able to modify anything that bind9 will accept as a `dynamic zone update` – see the docs here on dynamic update in bind9:

The way the tool works is it creates dynamic update messages from the API calls, then sends them to the bind9 server.

Don’t forget to add the zones you want to allow updates for into the config.env file:,
– Jay

I got it “mostly” working but the API is failing on “dns.tsig.PeerBadKey: The peer didn’t know the key we used” The key name and password match. Uvicorn and bind on same server. UFW active. Hints? I also ran uvicorn bindapi:app –reload –host so I could get to the API WWW.

Hmm, interesting issue. I would guess that your TSIG key isn’t working properly.
Basic process is:
* create TSIG key if needed
* Add the TSIG key to the bind9 config (either include or in the config file)
* Add the TSIG key to the zone config with permissions to update the zone
* Test the TSIG key with `nsupdate` tool

I’ve added some instructions run on my bind server on Ubuntu 22.04 you should be able to copy/customise to your needs.

The command I use to test the api key is:

echo '
update delete A
' | nsupdate -k /etc/bind/api-tsig-key.key -L 1

Hopefully this helps! 🙂

Well….I did not understand that Dynamic DNS needed to be setup and tested beforehand. So, I figured Dynamic DNS out and tested my env with nsupdate. All that is now good. I am going to try the Docker out. Docker up and running and I can add records, what I can’t do is a domain xfer (I can using nsupdate) This is my conf file:
allow-transfer {
key api-tsig-key;

I got it working by adding the Docker IP address to the allow-transfer. I was assuming I only needed the key plus my slave server.

Can you use a wild card for BIND_ALLOWED_ZONES, I have a lot of zones.
Maybe add an API call to restart named.

Thank you, this is really helpful and will be more so when phpipam adds webhooks.

Regarding BIND_ALLOWED_ZONES – what’s your use case here, and where would you want the wildcard? Would the zones all be sub-domains of a known zone?

Currently records can be created in any sub-domain of the zone, but only the top-level zone can be dumped. For example, if:

You can create a record but also can create or

However, you can only dump the whole domain

I could change this to allow dumping of any sub-domains of a domain in the BIND_ALLOWED_ZONES, so dumping of would work? Would this be enough for your needs? However, this only works if a valid zone file exists for the subdomain. If you are just trying to dump records of a subdomain it fails.

Happy to discuss further via email if that’s easier – my email address is at

Regarding “Maybe add an API call to restart named.”

Hmmm, this could be done – but would the ability to call the rndc reload command in a subprocess be enough for your needs? To do a full restart of named it would probably involve trying to ssh to the server and issue commands, which is quite complicated, but rndc can go over the network, it looks like.

From the docs:
rndc communicates with the name server over a TCP connection, sending commands authenticated with digital signatures. Looks like TCP/953 by default.

This functionality isn’t part of the dnspython library I’ve been using, so would need to be done in a subprocess.

Thoughts on this?

Hello, I got same trouble with TSIG error. Seems like some libraries had changed. Logs are here Using nsupdate with tsig. key have no problems
My pip list:
Package Version Editable project location
—————– ——- ————————–
annotated-types 0.6.0
anyio 4.3.0
astroid 3.1.0
bindapi 1.4.1 /home/admins/bind-rest-api
black 23.12.1
click 8.1.7
dill 0.3.8
dnspython 2.6.1
fastapi 0.109.2
greenlet 3.0.3
h11 0.14.0
idna 3.7
isort 5.13.2
mccabe 0.7.0
msgpack 1.0.8
mypy-extensions 1.0.0
packaging 24.0
pathspec 0.12.1
pip 24.0
platformdirs 4.2.0
pydantic 2.7.0
pydantic_core 2.18.1
pylint 3.1.0
pynvim 0.5.0
setuptools 69.5.1
sniffio 1.3.1
starlette 0.36.3
tomlkit 0.12.4
typing_extensions 4.11.0
uvicorn 0.26.0

Leave a Reply

Your email address will not be published. Required fields are marked *