MaraDNS: A small open-source DNS server
See the codeMaraDNS has a webpage which has an overview and documentation for MaraDNS.
MaraDNS is a free open-source computer program written by Sam Trenholme. MaraDNS is mostly POSIX 2001 compliant, with a small number of exceptions (see POSIX below).
MaraDNS implements the Domain Name System (DNS), an essential internet service. MaraDNS is open source software: This means that anyone is free to download, use, and modify the program free of charge, as per its license.
People like MaraDNS because it’s small, lightweight, easy to set up, and remarkably secure. It’s also cross platform — the program runs both in Windows and in UNIX clones.
MaraDNS has a web page and blog at https://maradns.samiam.org. MaraDNS’s Git tree is hosted at GitHub, GitLab, Bitbucket, Codeberg, SourceForge, and SourceHut (Please use GitHub discussions for bug reports).
MaraDNS has been, since late 2022, in deep freeze and is only being updated to fix important security holes or compile errors in either GCC or clang. The last hole found was in 2026. No attack stronger than remote denial of service has ever been found with MaraDNS.
MaraDNS is future-proof: She has been updated to be Y2038 compliant; any
and all external dependencies MaraDNS has have multiple implementations
(for example, the scripts for converting MaraDNS’s documents have been
updated to be in Lua instead of Perl, because multiple Lua implementations
exist, including one shipping in MaraDNS’s source code). In addition,
MaraDNS is compiled with the std=c99 flag to reduce the chances that
future changes to C compilers cause MaraDNS to be unable to
compile—even though MaraDNS generates no warnings with -Wall in GCC 16
and Clang 20 (both current here in 2026), I’ve seen C compilers, over the
years, decide to not compile code which previously generated no warnings
even with -Wall set (ugh).
MaraDNS is a small and lightweight cross-platform open-source DNS server. The server is remarkably easy to configure for someone comfortable editing text configuration files. MaraDNS is released under a BSD license.
I initially wrote MaraDNS while I was a college student and a travelling English teacher during the first 2000s decade.
During the COVID-19 pandemic, I was actively adding new features
to MaraDNS, most notably the coLunacyDNS service which uses Lua
to customize DNS replies.
Versions of some MaraDNS programs compiled as Windows binaries
(without needing Cygwin or another POSIX emulation library) are
in the folder maradns-win32/
To build MaraDNS, one needs a POSIX system with:
make, which has the POSIX202X
feature of allowing a make target to have a / in it.awk, etc.)stdint, 8-bit, 16-bit,
32-bit, and 64-bit sized integers.chroot
system call.setgroups
system call.mkstemp, which was not implemented in
a secure way with POSIX until 2008.strnlen, which was not part of the POSIX spec until
2008.It is also possible to compile most programs here in Windows using MinGW,
with varying levels of Windows support. MaraDNS (the authoritative
server) needs third party utilities to run as a service in Windows;
Deadwood (the recursive server) and coLunacyDNS (a simple DNS server
with Lua 5.1 scripting support) have built-in Windows service support.
32-bit Windows binaries are supplied in the maradns-win32 folder.
(To build some of the documentation, the non-standard but widely
available unix2dos text conversion utility is used.)
To compile MaraDNS, from the top level directory:
./configure
CC=clang
export CC
make
cd coLunacyDNS
make -f Makefile.default
Should one need to compile MaraDNS on a strictly POSIX compliant platform
without chroot or setgroups, compile as follows:
./configure --strict-posix
CC=cc
export CC
make
cd coLunacyDNS
make clean
make -f Makefile.strict
While MaraDNS will compile with GCC 15 and GCC 16 (2026), GCC is a moving target and I cannot guarantee MaraDNS will compile with future versions of GCC. Use clang (LLVM) instead if there are any issues compiling MaraDNS with GCC. As of 2026-07-04, MaraDNS compiles with no errors nor warnings with the following compilers:
MaraDNS compiles and has been tested in Ubuntu 26 (glibc), cygwin (cygwin1.dll), and both Alpine Linux 14 and 24 (musl libc).
MaraDNS needs the following to compile:
sh, awk, and make(The Windows port is compiled using a version of MinGW and MSYS from the first 2000s decade, but MaraDNS compiles just find in cygwin, and, while untested, should compile with a newer MinGW compiler)
All of these are very standard tools which are included with the vast majority of Linux and BSD distributions; packages usually have names like:
clang (which uses llvm) for the C compilerlibc-dev for the development C standard library, which will have socketsmake for make; if one does not wish to use GNU make (the Linux standard),
other make implementations exist, e.g. https://github.com/samboy/maramakesh, awk, and other utilities are
also almost always included as part of a Linux base install.MaraDNS successfully compiles with gcc, clang, and tcc; it
successfully builds with GNU make and maramake. The version of make
used to compile MaraDNS needs to have the command name make.
MaraDNS compiles and runs with both Busybox versions of the core
POSIX utilities as well as GNU coreutils.
Note that while MaraDNS will compile, on systems without /dev/urandom,
MaraDNS will not start up (the Windows port uses Windows-specific calls
to get entropy). While /dev/urandom is not part of POSIX, and while
it isn’t needed to compile MaraDNS, it is needed to run MaraDNS.
MaraDNS is built and runs on Ubuntu 26.04 as of mid 2026. I also test it in cygwin and Alpine Linux (both Alpine 14 and Alpine 24). There is in addition a MinGW/Cygwin port which uses non-POSIX calls for the Windows environment.
MaraDNS for the most part only needs POSIX libraries to compile and run. There are a small number of exceptions.
Should one need to compile MaraDNS on a strictly POSIX compliant platform compile as follows:
./configure --strict-posix
CC=cc
export CC
make
cd coLunacyDNS
make clean
make -f Makefile.strict
MaraDNS has good reason to use non-POSIX calls, or calls which did not exist until POSIX 2008. All of the system functions which do not exist in POSIX 2001 used by MaraDNS are described below.
MaraDNS uses the chroot system call to, in case of a security issue
which allows MaraDNS to give an attacker a remote shell, restrict that
shell’s access to the underlying filesystem. While there has, as
of 2026, never been a remote shell exploit found in MaraDNS—even
though MaraDNS has been around for over 25 years—chroot minimizes
the impact should such a bug be found in the future.
MaraDNS will run without chroot, but the security implications would
be more significant should someone ever be able to get a remote shell
with MaraDNS.
chroot is not defined in POSIX because “it was not useful to portable
applications”
(page 258) since there isn’t a way to make a usable chroot environment
in the POSIX spec. The POSIX developers failed to consider the case of
using chroot as a portable and widely implemented way of putting an
application in a sandbox—there is no need to have an “environment
in which an application could run” in said sandbox, since MaraDNS
is started and loads configuration files before entering the
chroot jail.
The setgroups call is also used to sandbox MaraDNS. Like chroot,
this minimizes the impact should one be able to get a remote root shell
via a security hole in MaraDNS (again, as of 2026, no security hole with
remote shell access has ever been found in MaraDNS, and it has been over
25 years).
setgroups is not defined in POSIX because it requires elevated privileges
to run.
mkstemp was not mandated to be implemented in a secure manner with
POSIX until 2008. The only file that uses mkstemp is
coLunacyDNS/lunacy/loslib.c, and this file now makes sure
to compile in a POSIX system which is compliant with the 2008 (or later)
POSIX spec.
While mkstemp has been in POSIX since 1997 or
sooner,
it wasn’t until the 2008 version of the POSIX spec that files generated
with mkstemp correctly had 0600
permissions.
MaraDNS uses strnlen instead of strlen to stop the possibility that one
might be able to force coLunacyDNS to allocate a large amount of memory
if the human2DNS function got a name longer than allowed by RFC1034.
strnlen was not part of the POSIX standard until 2008.
While MaraDNS does have scripts for starting up MaraDNS at system boot
time on sysvinit systems, these scripts are no longer fully supported,
since most major Linux distributions have moved on to systemd, which
is a lot better than the older sysvinit process for starting up the
MaraDNS related services.
While make install is only guaranteed to get MaraDNS to start up at
system boot time on Ubuntu 22.04, it should do the right thing in Rocky
Linux, Debian, RedHat, CentOS, Fedora, and other Linux distributions
which use systemd.
There is some scaffolding for getting MaraDNS to run without systemd.
There is a helper, duende, to make MaraDNS a daemon on systems with
classic *NIX style init. While, with systemd, it’s no longer needed
to use this Duende helper, I will keep Duende around for sysvinit and
some level of OpenRC compatibility. There are also shell scripts for
starting MaraDNS on sysvinit systems which may or may not work with
other init systems.
systemd handles the daemonization of the MaraDNS services the way
duende does (did?) on sysvinit and similar systems. The systemd way
is much simpler at the development level, since systemd now handles a lot
of complexity the old init systems forced networking services to handle.
Users of Microsoft Windows are better off downloading a prebuilt Windows
binary: http://maradns.samiam.org/download.html (or, look in the
folder maradns-win32 here)
Be sure to download the file with the .zip extension.
MaraDNS, askmara, Deadwood, and coLunacyDNS binaries are provided.
Deadwood has passed Y2038 tests in Windows 10.
The internet uses numbers, not names, to find computers. DNS is the internet’s directory service: It takes a name, like “www.maradns.org”, and converts that name in to an “IP” number that your computer can use to connect to www.maradns.org.
DNS is one of these things many take for granted that is essential to using today’s internet. Without DNS, the internet breaks. It is critical that a DNS server keeps the internet working in a secure and stable manner.
MaraDNS was started in 2001 in response to concerns that there were only two freely available DNS servers (BIND and DjbDNS) at the time. MaraDNS 1.0 was released in mid-2002, MaraDNS 1.2 was released in late 2005, MaraDNS 2.0 was released in the fall of 2010, and MaraDNS had a version number jump up to 3.3 in 2019 in order to have the same version number as Deadwood.
MaraDNS 1.0 used a recursive DNS server that was implemented rather quickly and had difficult-to-maintain code. This code was completely rewritten for the MaraDNS 2.0 release, which now uses a separate recursive DNS server.
MaraDNS 3.5 consists of three primary components: A UDP-only authoritative
DNS server for hosting domains, a UDP recursive DNS server called
Deadwood for finding domains on the internet, and a Lua-powered DNS
server called coLunacyDNS. MaraDNS’ recursive DNS server Deadwood
shares no code with MaraDNS’ authoritative DNS server.
coLunacyDNS is a Lua-based name server which uses a combination of C
(for the heavy lifting of binding to DNS sockets, processing DNS requests,
and handling pending replies from upstream DNS servers) and Lua (for
deciding how to respond to a given query) to have both performance
and flexibility.
In more detail: MaraDNS has one daemon, the authoritative daemon
(called maradns), that provides information to recursive DNS servers
on the internet, and another daemon, the recursive daemon (called
Deadwood), that gets DNS information from the internet for web
browsers and other internet clients.
A simplified way to look at it: MaraDNS puts your web page on the
Internet; Deadwood looks for web pages on the Internet.
Since MaraDNS’ authoritative daemon does not support TCP, MaraDNS
includes a separate DNS-over-TCP server called zoneserver that
supports both standard DNS-over-TCP and DNS zone transfers.
Neither MaraDNS nor the UNIX version of Deadwood have support for
daemonization; this is handled by a separate program included with
MaraDNS called Duende. Deadwood's Windows port, on the other hand,
includes support for running as a Windows service.
MaraDNS also includes a simple DNS querying tool called askmara and
a number of other miscellaneous tools: Lua 5.1 scripts for processing
MaraDNS' documentation (since MaraDNS comes with a fork of Lua 5.1, these
scripts do not have an external dependency), some Unicode conversion
utilities, scripts for building and installing MaraDNS, automated SQA
tests, etc.
MaraDNS is a native UNIX program which can run in Windows via cygwin.
Both Deadwood, MaraDNS' recursive resolver, and coLunacyDNS, a DNS
server configured with a Lua 5.1 script, are cross-platform applications
with full Windows ports.
MaraDNS 2.0 has full (albeit not fully tested) IPv6 support.
MaraDNS 3.5’s authoritative server uses code going all the way back to 2001. The core DNS-over-UDP server has a number of components, including two different zone file parsers, a mararc parser, a secure random number generator, and so on.
MaraDNS is written entirely in C. No objective C nor C++ classes are used in MaraDNS’ code.
MaraDNS 2.0’s “Deadwood” recursive server was started in 2007 and has far cleaner code. Its random number generator, for example, uses a smaller, simpler, and more secure cryptographic algorithm; its configuration file parser uses a finite state machine interpreter; its handling of multiple simultaneous pending connections is done using select() and a state machine instead of with threads.
The landscape of open-source DNS servers has changed greatly since 2001 when MaraDNS was started. There are now a number of different DNS servers still actively developed and maintained: BIND, Power DNS, NSD/Unbound, as well as MaraDNS. DjbDNS is no longer being updated and the unofficial forks have limited support; notably it took nearly five months for someone to come up with a patch for CVE-2012-1191.
MaraDNS’ strength is that it’s a remarkably small, lightweight, easy to configure, and mostly cross-platform DNS server. Deadwood is a tiny DNS server with full recursion support, perfect for embedded systems.
MaraDNS’ weakness is that it does not have some features other DNS servers have. For example, while Deadwood has the strongest spoof protection available without cryptography, it does not have support for DNSSEC.
As another example, MaraDNS does not have full zone transfer support; while MaraDNS can both serve zones and receive external zone files from other DNS servers, MaraDNS needs to be restarted to update its database of DNS records.
MaraDNS is a mature application, in deep freeze: The only updates being done now are important security updates.
I have revamped MaraDNS so that it can continue to compile and run for as long as possible, minimizing the number of external dependencies so that outside changes are unlikely to break MaraDNS.
For MaraDNS to break, either the C language would have to change to break programs that compile with few to no warnings here in the 2020s, or the POSIX standard would have to change to the point that POSIX compliant scripts which run here in the 2020s no longer run. Both of these are very unlikely to happen.
MaraDNS is fully Y2038 compliant on systems with a 64-bit time_t. Here in the 2020s, even 32-bit Linux distributions, such as Alpine Linux, have a 64-bit time_t.
Deadwood, in addition, for its Windows 32-bit binary, uses Windows filetime to generate internal timestamps; filetime stamps will not run over until the year 30827 or so.
coLunacyDNS, likewise, uses Windows filetime for timestamps with its Win32 binary.
On *NIX systems with a 32-bit time_t, some features which depend on
OS-level time and date libraries are disabled. MaraDNS has support for
showing a human readable timestamp with the timestamp_type parameter;
this parameter is disabled on systems with a 32-bit time_t since the
underlying libraries MaraDNS uses will probably fail at the Y2038 cutoff.
Likewise, MaraDNS has support for generating a human-readable SOA
serial number with the synth_soa_serial parameter, but this feature
is disabled if time_t is 32-bit. In both cases, the feature in
question is, by default, disabled in MaraDNS, so only users who have
explicitly enabled these features will see any change in behavior.
MaraDNS has the ability to generate a synthetic SOA serial number if
a zone file does not have a SOA record. The SOA serial is based on the
timestamp for the zone file. If time_t is 32-bit, MaraDNS assumes that
the stat call will return a negative timestamp after the Y2038 cutoff,
and will adjust timestamps from before 2001 (the year MaraDNS was first
developed) to be after the Y2038 cutoff. If there are systems out there
where a stat call for a file’s modification time fail after the Y2038
cutoff, one can avoid Y2038 issues by having a SOA record with a serial
number in zone files. The Windows port of MaraDNS, as of 3.5.0028,
uses Windows Y2038 compliant system calls instead of POSIX calls to get
zone file timestamps.
Both Deadwood and coLunacyDNS make some effort to generate accurate timestamps on *NIX systems with a 32-bit time_t until later than 2106; this code assumes that 32-bit systems will have the time stamp “wrap around” after 2038 but still have the 32-bit time be updated.
MaraDNS is open source software, and, as such, is not subject to the regulations of the Cyber Resilience Act.
MaraDNS, as always, is provided free of charge but with no warranty. That said, I do take security reports seriously---the last time there was a confirmed important security hole in MaraDNS, back in 2023, I addressed the issue within 24 hours and had a fix out shortly afterwards.
In 2023, someone found a “packet of death” bug with MaraDNS. This is the second “packet of death” bug MaraDNS has ever had (another one was found in 2011) and I fixed it within a couple of days.
In 2026, an extensive security audit of MaraDNS was performed, and the security “holes” were issues like “If MaraDNS (Deadwood, actually) gets this weird packet, it takes longer than it should have to release resources and stop trying to resolve the name in question”. When it looked like there was a “packet of death” bug, I wrote a test to reproduce the issue, realized it was not an actual packet of death, and the reporter realized the issue was with their testing apparatus.
MaraDNS has never had a security hole worse than “packet of death”.
MaraDNS was updated in 2022 to have its automated tests run in an Ubuntu 22.04 Docker container instead of an Ubuntu 20.04 Docker container. The tests have also been updated to be more portable, running in both Alpine Linux (Busybox-based Linux distro) and Ubuntu 22.04.
I also fixed a minor security issue, which also affected other DNS servers, where a clever attacker with access to the recurisve DNS server could had kept records in the cache longer than desired.
min_ttl now correctly sets a minimum TTL for direct answers to queries.
I have backported the min_ttl parameter to the older legacy 3.4 version
of MaraDNS.
While using Deadwood as a fully recursive server is not guaranteed to be fully supported, I have fixed a long standing bug with how Deadwood handled certain CNAME chains, and have added tests to make sure this bug stays fixed.
MaraDNS no longer uses non-POSIX scripting languages not included with MaraDNS:
lunacy in coLunacyDNS/lunacy)
instead of Perl scripts.bind2csv2.py tool has been removed, so that MaraDNS no
longer needs Python to run any of its components.Deadwood has a new parameter: source_ip4. This optional parameter
is used to specify the source IP when sending queries upstream. The
majority of users should be able to leave this untouched; this is for
cases when Deadwood is multi-homed and we need to specify which IP
to use when querying root or upstream DNS servers.
One line change to zoneserver.c to make it work better with systemd.
Synthetic IP generator example added to coLunacyDNS
I have updated things so that the Git version of MaraDNS is the authoritative “One source of truth” for MaraDNS’s source code. The Git code is, every time a new MaraDNS release is made, converted in to tarballs (with full Git history) which can be downloaded at Sourceforge and MaraDNS’s web page.
I have added block list support to Deadwood, to allow a large list of host names to be blocked.
I have created a new service: coLunacyDNS, a simple Lua-based DNS server
which can return IPv4 (A) and IPv6 (AAAA) DNS records. It has the
ability to query other DNS servers, and customize the answer given to
the client based on the contents of a Lua script. All programs have IPv6
support in Linux as well as *NIX clones, and the Windows 32-bit binary of
coLunacyDNS has IPv6 support.
C
50.5%
HTML
26.9%
Shell
19.4%
Roff
1.4%
MaraDNS: A small open-source DNS server
See the codeMaraDNS has a webpage which has an overview and documentation for MaraDNS.
MaraDNS is a free open-source computer program written by Sam Trenholme. MaraDNS is mostly POSIX 2001 compliant, with a small number of exceptions (see POSIX below).
MaraDNS implements the Domain Name System (DNS), an essential internet service. MaraDNS is open source software: This means that anyone is free to download, use, and modify the program free of charge, as per its license.
People like MaraDNS because it’s small, lightweight, easy to set up, and remarkably secure. It’s also cross platform — the program runs both in Windows and in UNIX clones.
MaraDNS has a web page and blog at https://maradns.samiam.org. MaraDNS’s Git tree is hosted at GitHub, GitLab, Bitbucket, Codeberg, SourceForge, and SourceHut (Please use GitHub discussions for bug reports).
MaraDNS has been, since late 2022, in deep freeze and is only being updated to fix important security holes or compile errors in either GCC or clang. The last hole found was in 2026. No attack stronger than remote denial of service has ever been found with MaraDNS.
MaraDNS is future-proof: She has been updated to be Y2038 compliant; any
and all external dependencies MaraDNS has have multiple implementations
(for example, the scripts for converting MaraDNS’s documents have been
updated to be in Lua instead of Perl, because multiple Lua implementations
exist, including one shipping in MaraDNS’s source code). In addition,
MaraDNS is compiled with the std=c99 flag to reduce the chances that
future changes to C compilers cause MaraDNS to be unable to
compile—even though MaraDNS generates no warnings with -Wall in GCC 16
and Clang 20 (both current here in 2026), I’ve seen C compilers, over the
years, decide to not compile code which previously generated no warnings
even with -Wall set (ugh).
MaraDNS is a small and lightweight cross-platform open-source DNS server. The server is remarkably easy to configure for someone comfortable editing text configuration files. MaraDNS is released under a BSD license.
I initially wrote MaraDNS while I was a college student and a travelling English teacher during the first 2000s decade.
During the COVID-19 pandemic, I was actively adding new features
to MaraDNS, most notably the coLunacyDNS service which uses Lua
to customize DNS replies.
Versions of some MaraDNS programs compiled as Windows binaries
(without needing Cygwin or another POSIX emulation library) are
in the folder maradns-win32/
To build MaraDNS, one needs a POSIX system with:
make, which has the POSIX202X
feature of allowing a make target to have a / in it.awk, etc.)stdint, 8-bit, 16-bit,
32-bit, and 64-bit sized integers.chroot
system call.setgroups
system call.mkstemp, which was not implemented in
a secure way with POSIX until 2008.strnlen, which was not part of the POSIX spec until
2008.It is also possible to compile most programs here in Windows using MinGW,
with varying levels of Windows support. MaraDNS (the authoritative
server) needs third party utilities to run as a service in Windows;
Deadwood (the recursive server) and coLunacyDNS (a simple DNS server
with Lua 5.1 scripting support) have built-in Windows service support.
32-bit Windows binaries are supplied in the maradns-win32 folder.
(To build some of the documentation, the non-standard but widely
available unix2dos text conversion utility is used.)
To compile MaraDNS, from the top level directory:
./configure
CC=clang
export CC
make
cd coLunacyDNS
make -f Makefile.default
Should one need to compile MaraDNS on a strictly POSIX compliant platform
without chroot or setgroups, compile as follows:
./configure --strict-posix
CC=cc
export CC
make
cd coLunacyDNS
make clean
make -f Makefile.strict
While MaraDNS will compile with GCC 15 and GCC 16 (2026), GCC is a moving target and I cannot guarantee MaraDNS will compile with future versions of GCC. Use clang (LLVM) instead if there are any issues compiling MaraDNS with GCC. As of 2026-07-04, MaraDNS compiles with no errors nor warnings with the following compilers:
MaraDNS compiles and has been tested in Ubuntu 26 (glibc), cygwin (cygwin1.dll), and both Alpine Linux 14 and 24 (musl libc).
MaraDNS needs the following to compile:
sh, awk, and make(The Windows port is compiled using a version of MinGW and MSYS from the first 2000s decade, but MaraDNS compiles just find in cygwin, and, while untested, should compile with a newer MinGW compiler)
All of these are very standard tools which are included with the vast majority of Linux and BSD distributions; packages usually have names like:
clang (which uses llvm) for the C compilerlibc-dev for the development C standard library, which will have socketsmake for make; if one does not wish to use GNU make (the Linux standard),
other make implementations exist, e.g. https://github.com/samboy/maramakesh, awk, and other utilities are
also almost always included as part of a Linux base install.MaraDNS successfully compiles with gcc, clang, and tcc; it
successfully builds with GNU make and maramake. The version of make
used to compile MaraDNS needs to have the command name make.
MaraDNS compiles and runs with both Busybox versions of the core
POSIX utilities as well as GNU coreutils.
Note that while MaraDNS will compile, on systems without /dev/urandom,
MaraDNS will not start up (the Windows port uses Windows-specific calls
to get entropy). While /dev/urandom is not part of POSIX, and while
it isn’t needed to compile MaraDNS, it is needed to run MaraDNS.
MaraDNS is built and runs on Ubuntu 26.04 as of mid 2026. I also test it in cygwin and Alpine Linux (both Alpine 14 and Alpine 24). There is in addition a MinGW/Cygwin port which uses non-POSIX calls for the Windows environment.
MaraDNS for the most part only needs POSIX libraries to compile and run. There are a small number of exceptions.
Should one need to compile MaraDNS on a strictly POSIX compliant platform compile as follows:
./configure --strict-posix
CC=cc
export CC
make
cd coLunacyDNS
make clean
make -f Makefile.strict
MaraDNS has good reason to use non-POSIX calls, or calls which did not exist until POSIX 2008. All of the system functions which do not exist in POSIX 2001 used by MaraDNS are described below.
MaraDNS uses the chroot system call to, in case of a security issue
which allows MaraDNS to give an attacker a remote shell, restrict that
shell’s access to the underlying filesystem. While there has, as
of 2026, never been a remote shell exploit found in MaraDNS—even
though MaraDNS has been around for over 25 years—chroot minimizes
the impact should such a bug be found in the future.
MaraDNS will run without chroot, but the security implications would
be more significant should someone ever be able to get a remote shell
with MaraDNS.
chroot is not defined in POSIX because “it was not useful to portable
applications”
(page 258) since there isn’t a way to make a usable chroot environment
in the POSIX spec. The POSIX developers failed to consider the case of
using chroot as a portable and widely implemented way of putting an
application in a sandbox—there is no need to have an “environment
in which an application could run” in said sandbox, since MaraDNS
is started and loads configuration files before entering the
chroot jail.
The setgroups call is also used to sandbox MaraDNS. Like chroot,
this minimizes the impact should one be able to get a remote root shell
via a security hole in MaraDNS (again, as of 2026, no security hole with
remote shell access has ever been found in MaraDNS, and it has been over
25 years).
setgroups is not defined in POSIX because it requires elevated privileges
to run.
mkstemp was not mandated to be implemented in a secure manner with
POSIX until 2008. The only file that uses mkstemp is
coLunacyDNS/lunacy/loslib.c, and this file now makes sure
to compile in a POSIX system which is compliant with the 2008 (or later)
POSIX spec.
While mkstemp has been in POSIX since 1997 or
sooner,
it wasn’t until the 2008 version of the POSIX spec that files generated
with mkstemp correctly had 0600
permissions.
MaraDNS uses strnlen instead of strlen to stop the possibility that one
might be able to force coLunacyDNS to allocate a large amount of memory
if the human2DNS function got a name longer than allowed by RFC1034.
strnlen was not part of the POSIX standard until 2008.
While MaraDNS does have scripts for starting up MaraDNS at system boot
time on sysvinit systems, these scripts are no longer fully supported,
since most major Linux distributions have moved on to systemd, which
is a lot better than the older sysvinit process for starting up the
MaraDNS related services.
While make install is only guaranteed to get MaraDNS to start up at
system boot time on Ubuntu 22.04, it should do the right thing in Rocky
Linux, Debian, RedHat, CentOS, Fedora, and other Linux distributions
which use systemd.
There is some scaffolding for getting MaraDNS to run without systemd.
There is a helper, duende, to make MaraDNS a daemon on systems with
classic *NIX style init. While, with systemd, it’s no longer needed
to use this Duende helper, I will keep Duende around for sysvinit and
some level of OpenRC compatibility. There are also shell scripts for
starting MaraDNS on sysvinit systems which may or may not work with
other init systems.
systemd handles the daemonization of the MaraDNS services the way
duende does (did?) on sysvinit and similar systems. The systemd way
is much simpler at the development level, since systemd now handles a lot
of complexity the old init systems forced networking services to handle.
Users of Microsoft Windows are better off downloading a prebuilt Windows
binary: http://maradns.samiam.org/download.html (or, look in the
folder maradns-win32 here)
Be sure to download the file with the .zip extension.
MaraDNS, askmara, Deadwood, and coLunacyDNS binaries are provided.
Deadwood has passed Y2038 tests in Windows 10.
The internet uses numbers, not names, to find computers. DNS is the internet’s directory service: It takes a name, like “www.maradns.org”, and converts that name in to an “IP” number that your computer can use to connect to www.maradns.org.
DNS is one of these things many take for granted that is essential to using today’s internet. Without DNS, the internet breaks. It is critical that a DNS server keeps the internet working in a secure and stable manner.
MaraDNS was started in 2001 in response to concerns that there were only two freely available DNS servers (BIND and DjbDNS) at the time. MaraDNS 1.0 was released in mid-2002, MaraDNS 1.2 was released in late 2005, MaraDNS 2.0 was released in the fall of 2010, and MaraDNS had a version number jump up to 3.3 in 2019 in order to have the same version number as Deadwood.
MaraDNS 1.0 used a recursive DNS server that was implemented rather quickly and had difficult-to-maintain code. This code was completely rewritten for the MaraDNS 2.0 release, which now uses a separate recursive DNS server.
MaraDNS 3.5 consists of three primary components: A UDP-only authoritative
DNS server for hosting domains, a UDP recursive DNS server called
Deadwood for finding domains on the internet, and a Lua-powered DNS
server called coLunacyDNS. MaraDNS’ recursive DNS server Deadwood
shares no code with MaraDNS’ authoritative DNS server.
coLunacyDNS is a Lua-based name server which uses a combination of C
(for the heavy lifting of binding to DNS sockets, processing DNS requests,
and handling pending replies from upstream DNS servers) and Lua (for
deciding how to respond to a given query) to have both performance
and flexibility.
In more detail: MaraDNS has one daemon, the authoritative daemon
(called maradns), that provides information to recursive DNS servers
on the internet, and another daemon, the recursive daemon (called
Deadwood), that gets DNS information from the internet for web
browsers and other internet clients.
A simplified way to look at it: MaraDNS puts your web page on the
Internet; Deadwood looks for web pages on the Internet.
Since MaraDNS’ authoritative daemon does not support TCP, MaraDNS
includes a separate DNS-over-TCP server called zoneserver that
supports both standard DNS-over-TCP and DNS zone transfers.
Neither MaraDNS nor the UNIX version of Deadwood have support for
daemonization; this is handled by a separate program included with
MaraDNS called Duende. Deadwood's Windows port, on the other hand,
includes support for running as a Windows service.
MaraDNS also includes a simple DNS querying tool called askmara and
a number of other miscellaneous tools: Lua 5.1 scripts for processing
MaraDNS' documentation (since MaraDNS comes with a fork of Lua 5.1, these
scripts do not have an external dependency), some Unicode conversion
utilities, scripts for building and installing MaraDNS, automated SQA
tests, etc.
MaraDNS is a native UNIX program which can run in Windows via cygwin.
Both Deadwood, MaraDNS' recursive resolver, and coLunacyDNS, a DNS
server configured with a Lua 5.1 script, are cross-platform applications
with full Windows ports.
MaraDNS 2.0 has full (albeit not fully tested) IPv6 support.
MaraDNS 3.5’s authoritative server uses code going all the way back to 2001. The core DNS-over-UDP server has a number of components, including two different zone file parsers, a mararc parser, a secure random number generator, and so on.
MaraDNS is written entirely in C. No objective C nor C++ classes are used in MaraDNS’ code.
MaraDNS 2.0’s “Deadwood” recursive server was started in 2007 and has far cleaner code. Its random number generator, for example, uses a smaller, simpler, and more secure cryptographic algorithm; its configuration file parser uses a finite state machine interpreter; its handling of multiple simultaneous pending connections is done using select() and a state machine instead of with threads.
The landscape of open-source DNS servers has changed greatly since 2001 when MaraDNS was started. There are now a number of different DNS servers still actively developed and maintained: BIND, Power DNS, NSD/Unbound, as well as MaraDNS. DjbDNS is no longer being updated and the unofficial forks have limited support; notably it took nearly five months for someone to come up with a patch for CVE-2012-1191.
MaraDNS’ strength is that it’s a remarkably small, lightweight, easy to configure, and mostly cross-platform DNS server. Deadwood is a tiny DNS server with full recursion support, perfect for embedded systems.
MaraDNS’ weakness is that it does not have some features other DNS servers have. For example, while Deadwood has the strongest spoof protection available without cryptography, it does not have support for DNSSEC.
As another example, MaraDNS does not have full zone transfer support; while MaraDNS can both serve zones and receive external zone files from other DNS servers, MaraDNS needs to be restarted to update its database of DNS records.
MaraDNS is a mature application, in deep freeze: The only updates being done now are important security updates.
I have revamped MaraDNS so that it can continue to compile and run for as long as possible, minimizing the number of external dependencies so that outside changes are unlikely to break MaraDNS.
For MaraDNS to break, either the C language would have to change to break programs that compile with few to no warnings here in the 2020s, or the POSIX standard would have to change to the point that POSIX compliant scripts which run here in the 2020s no longer run. Both of these are very unlikely to happen.
MaraDNS is fully Y2038 compliant on systems with a 64-bit time_t. Here in the 2020s, even 32-bit Linux distributions, such as Alpine Linux, have a 64-bit time_t.
Deadwood, in addition, for its Windows 32-bit binary, uses Windows filetime to generate internal timestamps; filetime stamps will not run over until the year 30827 or so.
coLunacyDNS, likewise, uses Windows filetime for timestamps with its Win32 binary.
On *NIX systems with a 32-bit time_t, some features which depend on
OS-level time and date libraries are disabled. MaraDNS has support for
showing a human readable timestamp with the timestamp_type parameter;
this parameter is disabled on systems with a 32-bit time_t since the
underlying libraries MaraDNS uses will probably fail at the Y2038 cutoff.
Likewise, MaraDNS has support for generating a human-readable SOA
serial number with the synth_soa_serial parameter, but this feature
is disabled if time_t is 32-bit. In both cases, the feature in
question is, by default, disabled in MaraDNS, so only users who have
explicitly enabled these features will see any change in behavior.
MaraDNS has the ability to generate a synthetic SOA serial number if
a zone file does not have a SOA record. The SOA serial is based on the
timestamp for the zone file. If time_t is 32-bit, MaraDNS assumes that
the stat call will return a negative timestamp after the Y2038 cutoff,
and will adjust timestamps from before 2001 (the year MaraDNS was first
developed) to be after the Y2038 cutoff. If there are systems out there
where a stat call for a file’s modification time fail after the Y2038
cutoff, one can avoid Y2038 issues by having a SOA record with a serial
number in zone files. The Windows port of MaraDNS, as of 3.5.0028,
uses Windows Y2038 compliant system calls instead of POSIX calls to get
zone file timestamps.
Both Deadwood and coLunacyDNS make some effort to generate accurate timestamps on *NIX systems with a 32-bit time_t until later than 2106; this code assumes that 32-bit systems will have the time stamp “wrap around” after 2038 but still have the 32-bit time be updated.
MaraDNS is open source software, and, as such, is not subject to the regulations of the Cyber Resilience Act.
MaraDNS, as always, is provided free of charge but with no warranty. That said, I do take security reports seriously---the last time there was a confirmed important security hole in MaraDNS, back in 2023, I addressed the issue within 24 hours and had a fix out shortly afterwards.
In 2023, someone found a “packet of death” bug with MaraDNS. This is the second “packet of death” bug MaraDNS has ever had (another one was found in 2011) and I fixed it within a couple of days.
In 2026, an extensive security audit of MaraDNS was performed, and the security “holes” were issues like “If MaraDNS (Deadwood, actually) gets this weird packet, it takes longer than it should have to release resources and stop trying to resolve the name in question”. When it looked like there was a “packet of death” bug, I wrote a test to reproduce the issue, realized it was not an actual packet of death, and the reporter realized the issue was with their testing apparatus.
MaraDNS has never had a security hole worse than “packet of death”.
MaraDNS was updated in 2022 to have its automated tests run in an Ubuntu 22.04 Docker container instead of an Ubuntu 20.04 Docker container. The tests have also been updated to be more portable, running in both Alpine Linux (Busybox-based Linux distro) and Ubuntu 22.04.
I also fixed a minor security issue, which also affected other DNS servers, where a clever attacker with access to the recurisve DNS server could had kept records in the cache longer than desired.
min_ttl now correctly sets a minimum TTL for direct answers to queries.
I have backported the min_ttl parameter to the older legacy 3.4 version
of MaraDNS.
While using Deadwood as a fully recursive server is not guaranteed to be fully supported, I have fixed a long standing bug with how Deadwood handled certain CNAME chains, and have added tests to make sure this bug stays fixed.
MaraDNS no longer uses non-POSIX scripting languages not included with MaraDNS:
lunacy in coLunacyDNS/lunacy)
instead of Perl scripts.bind2csv2.py tool has been removed, so that MaraDNS no
longer needs Python to run any of its components.Deadwood has a new parameter: source_ip4. This optional parameter
is used to specify the source IP when sending queries upstream. The
majority of users should be able to leave this untouched; this is for
cases when Deadwood is multi-homed and we need to specify which IP
to use when querying root or upstream DNS servers.
One line change to zoneserver.c to make it work better with systemd.
Synthetic IP generator example added to coLunacyDNS
I have updated things so that the Git version of MaraDNS is the authoritative “One source of truth” for MaraDNS’s source code. The Git code is, every time a new MaraDNS release is made, converted in to tarballs (with full Git history) which can be downloaded at Sourceforge and MaraDNS’s web page.
I have added block list support to Deadwood, to allow a large list of host names to be blocked.
I have created a new service: coLunacyDNS, a simple Lua-based DNS server
which can return IPv4 (A) and IPv6 (AAAA) DNS records. It has the
ability to query other DNS servers, and customize the answer given to
the client based on the contents of a Lua script. All programs have IPv6
support in Linux as well as *NIX clones, and the Windows 32-bit binary of
coLunacyDNS has IPv6 support.
C
50.5%
HTML
26.9%
Shell
19.4%
Roff
1.4%