Eon is a Nameserver using MirageOS’s functionally pure Domain Name System (DNS) library with direct-style IO (as opposed to monadic IO) using OCaml 5’s effect handlers [1] created as the basis to implement some of ideas from the Spatial Name System.
§DNS Tunnelling
DNS is well-known to be used for data exfiltration and tunneling, since DNS is one of the few protocols that’s almost always allowed through a firewall (at least through a recursive resolver) since it’s so fundamental to the operation of the Internet. I’ve implemented a transport layer over DNS in Eon, a simple netcat example shows how this can be used to transport data using DNS queries. Many thanks to Paul-Elliot for helping clean up the transport interface and making it more idiomatically functional. At the moment there’s no multiplexing – a server can only handle one communication at a time, but that could addresses by adding a demultiplexing field (a ‘port’).
The well-defined interfaces that OCaml gives us allows this to be combined in interesting ways, such as a shell over DNS (SoD), or an IP tunnel. Note that you wouldn’t want to use this in production without some form of encryption (maybe ocaml-tls?) and authentication (e.g. public/private keys, or capabilities). A standalone example of a capability interface to a shell can be found at capability-shell.
There’s some interesting performance
characteristics of this tunneling in a variable asymmetry of latency
between the sender and receiver, since we’re retrofitting bidirectional
packet switching onto a request response protocol. That is, for the DNS
server to send data to a client it has to have a query to respond to. We
can’t wait to respond to a query until we have data, since recursive
resolvers aggressively timeout and return a SERVFAIL
in the case of a delayed reply. So we
have the client periodically poll the server with queries containing no
data, so the latency of the server to client link is bounded by the
period of this polling.
This is interesting as it allows us to bootstrap communication with a nameserver using nothing but DNS.
§Capability Interface
DNS is an old protocol, and has some baked-in limitations due to protocol ossification (such as a maximum domain name length of 255 bytes). The ‘back-end’ of the protocol, interactions between services under your control, is easier to evolve. The AXFR zone transfers defined with the Domain Name System [2] are often replaced with some form of database replication in nameserver implementations. Dynamic updates [3] using secret key transaction signatures [4] are often eschewed in favour of custom APIs1.
§Names Have Power
Having a programmable interface into the domain name system is powerful, because domain names are powerful. Domain names are the root of identity for the Internet protocol suite. Federated communication networks derive user’s identify from domain names including Matrix, Mastodon, Bluesky’s AT Protocol [5], and good old E-Mail.
The DNS is also used to prove owership of domains. The security of the modern internet is built on the Transport Layer Security (TLS) protocol [6], which uses X509 certificates signed by certificate authorities. The Internet Security Research Group (ISRG)’s Let’s Encrypt certificate authority (CA) provides the majority of the Internet’s certificates, over 500 million in 2025. Traditionally provisioning a certificate was costly and manual process, but the Automatic Certificate Management Environment (ACME) protocol [7] used by Let’s Encrypt allows for an automated provisioning of certificates by proving ownership of a domain by displaying a token with one of a number of challenges; HTTP, TLS-ALPN, and DNS.
Only the DNS challenge is possible if the address the domain name points to is not publicly accessible, which is often the case for remote and resource constrained devices behind NATs or firewalls. However, it requires a complex dance of managing DNS UPDATE keys and specifying the subdomain and zone which it can modify. With our capability interface to the nameserver we can expose fine-grained access control to provision a certificate for a subdomain.
§Wake-on-DNS
Motivated by a desire to curb the power use of self-hosted services which are often idle for large periods of time, such as storage servers, we implemented hibernia nameserver than can wake a machine up on a name resolution with Eon and a OCaml Wake-on-LAN implementation. We published this idea as ‘Carbon-aware Name Resolution’ in LOCO2024.
§What next?
I’m looking at extending this interface to support additional functionality for networked services such as storage, identity, and more. Eilean is an attempt to parameterise a federated service deployment by a domain name leveraging the NixOS deployment system to do so, but it lacks a runtime component.
Note that prior to TSIG introduced with DNSSEC, DNS UPDATEs and zone transfers were typically enforced with IP-based access control. While using these protocols allows an variety of nameserver implementations to interoperate, in practice they are often replaced with custom solutions.
We’ve experimented with a programmable interface to the nameserver with Cap’N Proto capability-based RPCs. This creates capabilities for dynamically updating a domain, or receiving a zonefile and dynamic updates as a secondary nameserver. Please feel free to try deploying it for your own domain, and get in touch if you’d like to set up a reciprocal secondarying relationship.↩︎