Modern, lightweight DNS library
Less is more.
This work is partly funded by the Nominet DNS Fund.
Complete and usable DNS library. All Resource Records are supported, including the DNSSEC types. It follows a lean and mean philosophy. Server side and client side programming is supported, i.e. you can build servers and resolvers with it.
We try to keep the main branch as sane as possible and at the bleeding edge of standards, avoiding breaking changes wherever reasonable. We rigorously follow upstream Go versions and use bleeding edge Go language features. But because this version is young, we allow ourselves some more headroom for making backwards incompatible changes.
Many convenience functions are included in dns, dnstest or otherwise in dnsutils. The RR's resource data (RDATA) is split off into its own package: rdata. This means accessing the RR's header and rdata is much simpler now. 1
Example programs are included and benchmarked in
cmd. And
cmd/atomdns is a full blown
production ready name server. Because of these we are depending on a lot more external packages - at some
point these servers will be split off.
Also see the Go documentation.
This new version will not soon see a v1.0.0 release because I want to be able to still make changes. In a year or two (2028?) when things have stabilized it will be blessed with a v1.0.0.
Porting From v1
Everything from https://github.com/miekg/dns works. See
README-v1-to-v2.md
for the differences, if you are porting your application, in cookbook.go are some common recipes.
Note that a design choice has been made to not supported \DDD and \x syntax in domain names. This archaic
way of encoding names was useful way-back-when, nowadays DNS is pretty much a 7-bit protocol and things like
Punycode had to be invented. There is one exception to this and that
is the SOA's mname can contain a \., for the rest it is ignore and interpreted as \ and ..
Performance
The performance should be roughly 2x across the board compared to v1 (also see below).
- Serving DNS queries per second is ~2x (maybe more).
- Parsing zones files in RRs per second is ~1.5x.
- Memory usage can be ~0.5x due to rdata split off.
For developers please read the developer README.
Goals
- KISS.
- Everything is a resource record, EDNS0 pseudo RRs included.
- Easy way to access RR's header and resource data (rdata package).
- Small API.
- Package dnsutil contains functions that help programmers, but are not necessarily in scope the dns package.
- Package dnstest contains functions and types that help you test, similar to the httptest package.
- Package dnsjson contains types for DNS RRs in JSON (RFC 8427).
- Package svcb holds all details of the SVCB/HTTPS record (RFC 9460).
- Pacakge deleg holds details for the DELEG record.
- Many helper/debug functions are moved into internal packages, making the top-level much, much cleaner.
- Fast.
- recvmmsg(2) and TCP pipe-lining support.
- The
cmd/reflectserver does ~420K/340K qps UDP/TCP respectively on the right hardware.- Since a46996c I can get ~400K (UDP) qps on my laptop (M2/Asahi Linux), also see 1766e44, 86b53fe and 06e5e0f.
- On my Dell XPS 17 (Intel) it is similar-ish (~310K/250K qps UDP/TCP).
- On other Intel/AMD hardware it is lower (~200K (UDP) qps) - yet to understand why.
- See
cmd/reflectand do ago build; make new.txtto redo the performance test. Requiresdnsperfto be installed. - The SE zone (8M RRs) is parsed in ~11s (~730K RR/s), the CH zones (15M RRs) is parsed in ~14s (~1M RR/s).
The main difference being that SE use algorithm 8, and CH algorithm 13 (shorter RRSIGs).
See
cmd/parse, tested with M2/Asahi Linux.
Users
A not-so-up-to-date-list-that-may-be-actually-current:
- atomdns - included in
cmd/atomdns- a high performance DNS server, based on the principles of CoreDNS, but faster and simpler. - dnscrypt-proxy - a flexible DNS proxy, with support for encrypted DNS protocols such as DNSCrypt v2, DOH, Anonymized DNSCrypt and ODOH.
- DNSControl - DNSControl is an opinionated platform for seamlessly managing your DNS configuration across any number of DNS hosts, both in the cloud or in your own infrastructure.
- Gonemaster - Gonemaster is a Go implementation of the DNS test framework Zonemaster engine and CLI.
- DNSieve - a DNS filtering proxy that fans out queries to multiple upstream resolvers concurrently and enforces block-consensus.
Send pull request if you want to be listed here.
Comments
What users say:
miekg/dns is probably my favorite Go module in the open source ecosystem. It is very complete (every DNS rtype is defined) and strict (field names match the RFCs, etc). DNSControl has used miekg/dns since the first release.
Your library is a blast and I cannot thank you enough 🙏.
Features
- UDP/TCP queries, recvmmsg(2), TCP query-pipelining, IPv4 and IPv6.
- Fast.
- RFC 1035 zone file parsing ($INCLUDE, $ORIGIN, $TTL and $GENERATE - for all record types) is supported.
- Server side programming (mimicking the net/http package), with
dns.Handleanddns.HandleFuncallowing for middleware servers. - Client side programming.
- DNSSEC: signing, validating and key generation for DSA, RSA, ECDSA, Ed25519 and ML-DSA-44.
- EDNS0, NSID, Cookies, etc, as pseudo RRs in the (fake) pseudo section.
- AXFR/IXFR.
- TSIG, SIG(0).
- DNS over TLS (DOT): encrypted connection between client and server over TCP.
- DNS over HTTP (DOH), see the dnshttp package.
- Improved naming by embracing sub-packages.
- Improved RRs, by having the rdata specified in an rdata package.
- Escapes (\DDD and \x) in domain names is not supported (anymore) - the overhead (50-100%) was too high.
- Easy way for custom RRs and EDNS0 pseudo RRs.
Have fun!
Miek Gieben - 2026- - [email protected]
See anonymous users asking for support on why these kind of requests/issues usually get closed pretty swiftly.
Building/developing
This library uses Go modules and uses semantic versioning. Getting the code and working with the library is done via:
git clone [email protected]:miekg/dns # use https if you don't have a codeberg account
cd dns
# $EDTIOR *.go
If you want to use codeberg/miekg/dns in your own project, just do a go get codeberg.org/miekg/dns@latest
and import codeberg.org/miekg/dns in your Go files.
Examples
A short "how to use the API" is at the beginning of doc.go. The cmd/ directory contains a reflect example
program that is used for benchmarking, and further has atomdns which is full fledged DNS server that is
developed in tandem with the library.
Supported RFCs
all of them and then some
- 103{3,4,5} - DNS standard
1348 - NSAP record- 1982 - Serial Arithmetic
- 1876 - LOC record
- 1995 - IXFR
- 1996 - DNS notify
- 2136 - DNS Update (dynamic updates)
- 2181 - RRset definition
- 2537 - RSAMD5 DNS keys
- 2065 - DNSSEC (updated in later RFCs)
- 2671 - EDNS record
- 2782 - SRV record
- 2845 - TSIG record
- 2915 - NAPTR record
- 2929 - DNS IANA Considerations
- 3110 - RSASHA1 DNS keys
- 3123 - APL record
- 3225 - DO bit (DNSSEC OK)
- 340{1,2,3} - NAPTR record
- 3445 - Limiting the scope of (DNS)KEY
- 3596 - AAAA record
- 3597 - Unknown RRs
- 4025 - A Method for Storing IPsec Keying Material in DNS
- 403{3,4,5} - DNSSEC
- 4255 - SSHFP record
- 4343 - Case insensitivity
- 4408 - SPF record
- 4509 - SHA256 Hash in DS
- 4592 - Wildcards in the DNS
- 4635 - HMAC SHA TSIG
- 4701 - DHCID
- 4892 - id.server
- 5001 - NSID
- 5155 - NSEC3 record
- 5205 - HIP record
- 5702 - SHA2 in the DNS
- 5936 - AXFR
- 5966 - TCP implementation recommendations
- 6605 - ECDSA
- 6672 - DNAME
- 6725 - IANA Registry Update
- 6742 - ILNP DNS
- 6840 - Clarifications and Implementation Notes for DNS Security
- 6844 - CAA record
- 6891 - EDNS0 update
- 6895 - DNS IANA considerations
- 6944 - DNSSEC DNSKEY Algorithm Status
- 6975 - Algorithm Understanding in DNSSEC
- 7043 - EUI48/EUI64 records
- 7314 - DNS (EDNS) EXPIRE Option
- 7477 - CSYNC RR
- 7828 - TCP-keepalive EDNS0 Option
- 7553 - URI record
- 7719 - DNS Terminology
- 7858 - DNS over TLS: Initiation and Performance Considerations
- 7871 - EDNS0 Client Subnet
- 7873 - Domain Name System (DNS) Cookies
- 8080 - EdDSA for DNSSEC
- 8145 - EDNS0 key tag
- 8427 - Representing DNS Messages in JSON
- 8482 - Minimal Answers for ANY
- 8484 - DOH
- 8499 - DNS Terminology
- 8509 - DNSSEC Trusted Key Sentinel
- 8659 - DNS Certification Authority Authorization (CAA) Resource Record
- 8777 - DNS Reverse IP Automatic Multicast Tunneling (AMT) Discovery
- 8914 - Extended DNS Errors
- 8976 - Message Digest for DNS Zones (ZONEMD RR)
- 9250 - DOQ (not implemented, waiting until Go supports QUIC)
- 9461 - Service Binding Mapping for DNS Servers
- 9462 - Discovery of Designated Resolvers
- 9460 - SVCB and HTTPS Records
- 9499 - DNS Terminology
- 9558 - GOST 2012 for DNSSEC
- 9563 - SM2 for DNSSEC
- 9567 - DNS Error Reporting
- 9606 - DNS Resolver Information
- 9660 - Zone version
- 9715 - IP Fragmentation Avoidance in DNS over UDP
- 9824 - Compact Denial of Existence in DNSSEC
- 9859 - DSYNC RR
- draft-ietf-deleg - DELEG RR
- draft-westerbaan-dnssec-mldsa-04 - MLDSA for DNSSEC
-
A function is put in dnsutils, unless (due to cyclic imports) it is utterly impossible to put it there. Only then it is put in the main dns package. ↩︎