axfrdns

## Name

axfrdns — a UCSPI-TCP general-purpose content DNS server

## Synopsis

`axfrdns`

## Description

axfrdns is a content DNS server that speaks the DNS/TCP protocol. It accepts DNS queries on its standard input, and responds with locally configured information from a static database on its standard output. It runs in a system-secured environment and requires no privileges nor any filesystem access other than read access to its static database. It logs a record of its operation simply to its standard error.

axfrdns respects a location code system encoded in its database and differentiates amongst requesting clients according to their locations, determined by their IP addresses. It is designed to be Internet-facing; and its normal use is for answering Internet DNS queries from hosts around the Internet. It is used for the "zone transfer" mechanism and for where the response size exceeds the packet size for the DNS/UDP protocol. It can also be employed locally on a LAN, or even locally within a single machine, for providing information to hosts on an intranet.

### Note

tinydns(1) supports EDNS0 and clients negotiating packet sizes up to 64KiB. Since this is also the DNS/TCP protocol size limit, EDNS0-capable clients can in theory avoid falling back to DNS/TCP. (In practice, the world has yet to grow DNS data sets to where this is an everyday occurrence; or fully adopt EDNS0 in all clients. However, for local use it may be possible to rule out any need for axfrdns nowadays if all permissible clients speak EDNS0 and negotiate big-enough big packet sizes, and "zone transfer" is not required. And for all uses it has long been possible to rule it out if "zone transfer" is not required and it is administratively known or constrained that no data set in the database can ever hit the (non-EDNS0) 512-byte DNS/UDP size limit.)

It is possible to run multiple entirely isolated instances of axfrdns on a single machine, each with their own static databases and listening on particular IP addresses for different purposes. It is conversely possible to run multiple instances on a single machine, each listening on particular IP addresses, all sharing a single database.

Normally axfrdns is run under a UCSPI-TCP server program (tcp-socket-accept, s6-tcpserver, or tcpserver spawning a server program per connection) to handle DNS/TCP connections from hosts around the Internet. It can also be run under a UCSPI-SSL server program. When it starts it changes its root to the directory specified by the `ROOT` environment variable, and drops privileges to run as the user ID and group ID specified by the `UID` and `GID` environment variables. The latter can be set up with envuidgid(1).

axfrdns aborts if it runs out of memory, or has trouble reading `data.cdb`, or receives a request larger than 512 bytes, or receives a truncated request, or receives a non-Internet-class query, or receives an inverse query, or receives a request containing anything other than a single query (and optionally 1 authority record), or receives a request not answered by `data.cdb`, or waits 60 seconds with nothing happening.

## Answers

axfrdns answers queries as specified by `data.cdb`, a binary file in its root directory created by tinydns-data(1). It is used for the "zone transfer" mechanism and for where the response size exceeds the packet size for the DNS/UDP protocol. It provides "zone transfer" results from that file; and also answers normal client queries, such as the `SOA` queries sent via DNS/TCP that usually precede "zone transfer" requests.

axfrdns answers the same as tinydns(1) (q.v.), except that its response size limit is 64KiB, as determined by the DNS/TCP protocol. It is usually configured to work in the same root directory as an instance of tinydns(1) listening on the same IP address.

### Zone transfer

The UCSPI-TCP or UCSPI-SSL server is responsible for rejecting connections from clients that are not authorized to perform "zone transfers", and for setting up control variables that limit authorized clients.

axfrdns allows "zone transfers" for any domain name listed in the value of the `AXFR` environment variable, which is a slash-separated list of domain names. If `AXFR` is not set axfrdns allows "zone transfers" for all domain names that exist in `data.cdb`. For any "zone transfer" request that is not allowed by `AXFR`, it aborts. Thus, in order to prevent all "zone transfers" and only support ordinary DNS/TCP queries, set `AXFR` to an empty string.

axfrdns provides every record that it can find inside the target domain. This may include records that are, to the client, in child zones. Some of these records (such as "glue" inside a child zone) are essential; others are not. It is up to the client to decide which out-of-zone records to keep. axfrdns does not provide glue records outside the target domain.

### Caution

The "zone transfer" protocol does not support timestamps, comments, temporarily disabled address records (`-` lines), or location codes. It also splits up `@`, `.`, and `S` lines, with IP addresses and intermediate names together in a single line, into multiple component parts.

If a record is scheduled to be created in the future, axfrdns does not send it; after the starting time, the "zone transfer" client will continue claiming that the record doesn't exist, until it contacts axfrdns again. Similarly, if a record is scheduled to die in the future, axfrdns sends it (with a 2-second TTL); after the ending time, the "zone transfer" client will continue providing the old record, until it contacts axfrdns again.

"Zone transfer" clients rely on `SOA` serial numbers changing for every zone modification. tinydns-data(1) uses the modification time of the data file as its serial number for all zones. So do not make more than one modification per second, or use something other than "zone transfer".

"zone transfers" are special transactions, with rules different to normal DNS/TCP transactions, with types `AXFR` or `IXFR`. The `data.cdb` file does not hold old, superseded, data from before a tinydns-data(1) recompilation; so axfrdns always falls back from the latter to the former, and never returns "incremental" responses. The standard `SOA`, check serial number, then optionally `AXFR` form is the better way to perform "zone transfers" from axfrdns.

BIND's "zone transfer" client, named-xfer, converts "zone transfer" data to "zone-file" format.

### Warning

That "zone-file" format has no generic mechanism to express records of arbitrary types; named-xfer chokes if it does not recognize a record type used in `data.cdb`. named-xfer also chokes according to various internal arbitrary (and optionally configured) BIND rules that are not on-the-wire protocol restrictions. You may find the BIND client unable to receive a `+` record where a name happens to begin with an underscore, for just one example.

## History

axfrdns was originally part of Daniel J. Bernstein's djbdns toolset in 2000.

tinydns(1) gained EDNS0 capability, and axfrdns gained `IXFR` capability, in 2025.

## Author

Original code and documentation by Daniel J. Bernstein. Documentation modernizations by Jonathan de Boyne Pollard.