atomdns
atomdns is a DNS server/router, written in Go, that chains handlers. Each handler performs a (DNS) function.
Its architecture is identical to HTTP servers with middleware. The order of the handlers in the configuration
determines the order in which they are executed. (If you know CoreDNS; you might know that has a fixed order -
atomdns is different).
atomdns is a fast and flexible DNS server. The key word here is flexible: with atomdns you
are able to do what you want with your DNS data by utilizing handlers. If some functionality is not
provided out of the box, you can add it by writing a handler.
Currently atomdns is able to:
- Serve zone data from a file; with DNSSEC support (dbfile), plus:
- Zone transfers and notifies.
- DNSSEC signing (sign).
- Provide query logging (log).
- Access control for queryes (acl).
- Provide metrics (by using Prometheus) (metrics).
- Serve from a SQLite file (dbsqlite).
- ... and more.
- Serve as a router to router queries to some other (recursive) nameserver (route). [TODO]
Each of these handlers has its own manual page, i.e. see atomdns-dbfile(7) for more information on the
dbfile handler.
Compilation from Source
To compile atomdns, we assume you have a working Go setup. See various tutorials if you don’t have
that already configured. We follow upstream Go closely and use new language features when they come available.
$ git clone https://codeberg.org/miekg/dns
$ cd dns/cmd/atomdns
$ go build
This should yield a atomdns binary.
Examples
The configuration of atomdns is done through a file named Conffile. When atomdns starts, it will
look for the Conffile from the current working directory. A Conffile for atomdns server that listens
on port 1053 and enables whoami handler is:
{
dns {
addr [::]:1053
}
}
. {
whoami
}
Then start ./atomdns -c Conffile.
Or use Conffile-example which has a more complete set:
./atomdns -c Conffile-example
When atomdns starts you are greeted (when not using quiet) a bunch of log lines and a welcome banner:
2025/10/04 08:07:07 INFO 0.0.10.in-addr.arpa. handlers=unpack,log,whoami,refuse
2025/10/04 08:07:07 INFO atoom.net. handlers=unpack,log,dbfile,refuse
2025/10/04 08:07:07 INFO Startup functions total=7
2025/10/04 08:07:07 INFO Startup handler=global dns=[::]:1053 tcp=-1 run=24
2025/10/04 08:07:07 INFO Startup handler=global doh=[::]:10053 run=8 path=/dns-query
2025/10/04 08:07:07 INFO Startup handler=global dot=[::]:8053 tcp=128 run=1
2025/10/04 08:07:07 INFO Startup handler=global tls=manual
2025/10/04 08:07:07 INFO Startup handler=log signal=USR1
2025/10/04 08:07:07 INFO Startup handler=log signal=USR1
2025/10/04 08:07:07 INFO Startup handler=dbfile reload=db.example.org
2025/10/04 08:07:07 INFO Launched config=Conffile-example origins=2 roles=DNS,DOH,DOT
┏━┓ ╺┳╸ ┏━┓ ┏┳┓
┣━┫ ┃ ┃ ┃ ┃┃┃ DNS v011
╹ ╹ ╹ ┗━┛ ╹ ╹
High performance and flexible DNS server
https://atomdns.miek.nl
__________________________________\o/_______
Where the last INFO line shows the config parsed, the number of origins processed and for which protocols the
server can answer, here: DNS, DOH (DNS over HTTPS) and DOT (DNS over TLS). E.g. use dig @localhost -p 1053 A -x 10.0.0.1 to test.
See atomdns-conffile(7) for more information.