Drop #777 (2026-02-27): It’s Always DNS

ipasn.net; Hickory DNS; Go DNS Take Two

While the internet reels from one of the worst actively-exploited vulnerabilities in my lifetime, we’ll quietly take a calm look at a new BGP metadata “API” that works over DNS and two exciting (hey, I have no life, remember?) new (one is new-ish) DNS client libraries.

Bonus link: a helpful (quick) reminder why you should really get out of the curl|bash habit.


TL;DR

(This is an LLM/GPT-generated summary of today’s Drop. Ollama and MiniMax M2.1.)

  • Geoff Huston built ipasn.net, a DNS-based IP-to-ASN lookup service that queries using natural IP addresses instead of reversed formats, eliminating the preprocessing requirement of Team Cymru’s origin.asn.cymru.com service (https://blog.apnic.net/2026/02/09/from-the-stupid-dns-tricks-department-ipasn-net/).
  • Hickory DNS is a complete Rust-native DNS stack created to address memory safety vulnerabilities in C-based DNS implementations, with ISRG/Prossimo funding and Let’s Encrypt planning production deployment in 2026 (https://github.com/hickory-dns/hickory-dns).
  • Miek Gieben is rewriting the canonical Go DNS library with significant performance improvements including 2x throughput via recvmmsg batch reads and TCP pipelining, and 0.5x memory footprint from rdata structural changes (https://codeberg.org/miekg/dns).

ipasn.net

Geoff Huston (APNIC Chief Scientist) built a DNS-based IP-to-ASN enrichment service at ipasn.net. It’s conceptually similar to Team Cymru’s long-standing origin.asn.cymru.com DNS service, but addresses the main usability annoyances of that service.

Team Cymru’s service requires pre-processing the query string: IPv4 octets need to be reversed, and IPv6 addresses need the colon delimiters replaced with a reverse-ordered string of 8-bit octets. The IPv6 queries in particular are painful to construct manually. Huston’s view is that this reversal step is unnecessary.

There are two main ways ipasn.net works differently. DNS authoritative servers don’t require a static zone file. A DNS authoritative server could execute any procedure it wanted that generates a response correlated to the query it received. Huston uses PowerDNS with its plug-in backend capability to run dynamic lookups instead of zone file matching. DNS query labels are also more flexible with characters than the RFCs might suggest. Even the dot character can be used within a zone label in practice.

With Geoff’s implementation, you query with the IP address in its natural, un-reversed form.

The service supports several query patterns, all returning TXT records that the post goes into with examples.

The reply data is assembled by looking up the address prefix in a current BGP routing table snapshot to retrieve the origin AS, a lookup into a geolocation database for the country code, and then a lookup into the RIRs’ statistics reports for the registration details. The RPKI/ROA data comes from the published ROA objects across the five RIR Trust Anchors.

The broader point Huston is making in the post is that the DNS protocol itself is essentially a distributed computation system where the query string encodes instructions for the server. The “zone file” abstraction is convenient but optional, and once you treat the DNS server as a query processor rather than a key-value store, you can build arbitrary lookup services on top of it with the full benefit of DNS caching, recursion, and global distribution infrastructure.

I put a more readable breakdown of Geoff’s ipasn.net “API” over at https://git.sr.ht/~hrbrmstr/gists/tree/main/item/2026/2026-02-25-ipasn-net/ipasn-net-api.md.


Hickory DNS

It’s 2026 and the dominant DNS server implementations are still written in C, and their CVE histories reflect it. There are scads of memory corruption bugs that put foundational internet infrastructure at risk. Hickory DNS exists as a direct response to that: a complete, Rust-native DNS stack covering client, stub resolver, forwarding resolver, recursive resolver, and authoritative name server, all started by Benjamin Fry back in 2015 under the name “Trust-DNS” before moving to its own GitHub org and getting the Hickory rebrand.

The codebase is organized as a Rust workspace with cleanly separated crates. hickory-proto handles the low-level protocol work – encoding, decoding, transports. hickory-client sits on top for query/update/notify operations. hickory-resolver is the stub/forwarding resolver and is explicitly designed as a drop-in replacement for OS-level resolution. hickory-recursor handles full recursive resolution. hickory-server is the authoritative server library, wrapped by a hickory-dns binary for standalone deployment. The whole thing runs on Tokio for async I/O, and cryptography backends — aws-lc-rs or ring — are swappable via feature flags.

This cornucopia of Rust-based resolver goodness is defintely here for the long haul. ISRG (the organization behind Let’s Encrypt) is funding development through their Prossimo project, which is specifically focused on moving security-critical infrastructure to memory-safe languages. ISRG staff developer David Cook came on in 2024, and in January 2025 Dirkjan Ochtman was contracted to prepare Hickory for production use at Let’s Encrypt. Ferrous Systems has contributed DNSSEC work, and ICANN is funding RFC 9539 (opportunistic encryption) implementation.

In a surprise twist (Rust may be memory safe and make it easier to write memory safe code, but a decent chunk of stuff built in the wild with Rust is most assuredly not memory safe) the X41 D-Sec audit commissioned by OSTIF in fall 2024 asserted Hickory DNS ha[ds] no memory safety issues. The findings were two medium and two low severity issues, all DoS-related (the code wasn’t sufficiently limiting resource usage, allowing denial-of-service conditions with low effort).

Protocol coverage is mind-bendingly comprehensive: RFC 1035 base DNS, EDNS0 (RFC 6891), DNSSEC (RFCs 4034/4035/5155 including NSEC3), DNS-over-TLS, DNS-over-HTTPS, DNS-over-QUIC, dynamic updates (RFC 2136), SIG(0) authentication, DANE/TLSA, CAA records, mDNS/DNS-SD (experimental), and the ANAME draft. RFC 9539 is in active development.

hickory-proto has crossed 20 million downloads on crates.io, which suggests production adoption is already happening and ISRG’s target is to deploy Hickory as Let’s Encrypt’s recursive resolver for domain control validation in the first half of 2026. Let’s Encrypt validates certificate issuance at a scale that makes most infrastructure look adorable. If they do end up sticking with the deployment, orgs might want to consider re-thinking their own DNS server deployments, especially since LE is about to shrink renewal times again, and that will put Hickory through some serious paces.

Use the resolver crates today if you need async DNS resolution in Rust as they’re genuinely production-ready. I would hold off on the server binary for anything critical until 1.0 lands, and the Let’s Encrypt deployment will tell us everything we need to know about whether the wait was worth it.

Install just the client with cargo install --bin resolve hickory-util and it can be used with the first resource thusly:

❯ resolve 172.93.49.183.ipasn.net -t TXT -s
Querying for 172.93.49.183.ipasn.net TXT from udp:192.0.2.42:53, tcp:192.0.2.42:53
Success for query 172.93.49.183.ipasn.net. IN TXT
172.93.49.183.ipasn.net. 3600 IN TXT 172.93.49.183|IPv4|ADVERTISED|172.93.48.0/24|29802|Strasmore,_Inc.|US|United_States_of_America|arin|172.93.48.0/21|assigned|2017-01-03|UNK

Go DNS Take Two

Miek Gieben’s Golang dns package has been the legit de facto standard when it comes to doing ANYTHING DNS-related in Go land (it quietly underpins CoreDNS, dnscrypt-proxy, and a substantial chunk of Kubernetes networking). I truly love this package and have used it in many a place at work and in hobby projects.

Miek is not one to rest on laurels and has been hard at work (it’s been super-fun watching him devlog this on Mastodon) on the next generation of Golang dns over at Codeberg.

Most Drop readers do not have DNS-related RFC terminology memorized (y’all shld work on that) and likely grrrrd at the alphabet soup in the first section, so we’ll focus on performance here, since that was/is a major focus for this rewrite. Gieben had explored a pure builder-pattern approach (similar to golang.org/​x/​net/​dns/​dnsmessage) that would’ve kept everything in wire format (the binary representation of a DNS object; typically a Message or a Resource Record) at all times, then benchmarked it against Go structs with targeted optimizations and abandoned it. It turns out that tiny allocations from on-the-fly wire format construction just killed performance. What shipped instead is a Msg struct with a Data []byte slice for referencing wire-format data directly, alongside the new rdata sub-package that splits header fields from record payloads.

And the resulting performance numbers show a roughly 2x serving throughput via recvmmsg(2) batch reads and TCP pipelining, ~0.5x memory footprint from the rdata split, ~1.5x zone parsing. The included cmd/reflect reference server hits ~400-450K UDP qps on an M2. It’s seriously impressive, and watching Miek painstakingly implement this shows LLM coding assistants still have a long way to go before they match the persistence, creativity, determination, and sheer skill of human coders.

I haven’t ported anything over yet, but cookbook.go in the repo is the designated v1 migration guide. If you’ve got Go code touching DNS, this is worth a look sooner rather than later.

Great job, Miek!


FIN

Remember, you can follow and interact with the full text of The Daily Drop’s free posts on:

  • Mastodon via @dailydrop.hrbrmstr.dev@dailydrop.hrbrmstr.dev
  • Bluesky via <https://bsky.app/profile/dailydrop.hrbrmstr.dev.web.brid.gy>

☮️

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.