Show HN: I built a DNS resolver from scratch in Rust – no DNS libraries
69 points
by rdme
9 hours ago
| 18 comments
| github.com
| HN
I built a DNS resolver that lets me use https://frontend.numa instead of localhost:5173 — auto-generated TLS certs, WebSocket passthrough, path routing. No mkcert, no nginx, no /etc/hosts.
rdme
9 hours ago
[-]
Since I needed it to be my primary DNS, I also added: recursive resolution from root nameservers, DNSSEC chain-of-trust validation, ad blocking (385K+ domains), and LAN service discovery.

I wrote about the DNSSEC implementation here: https://numa.rs/blog/posts/dnssec-from-scratch.html It's now my daily system DNS. Single binary (~8MB), macOS/Linux/Windows.

`sudo numa install`

reply
pyprism
4 hours ago
[-]
Very interesting project! I have a couple of questions. With all the default blocked domains loaded, what is the average memory usage? Currently, I am using Pi-hole on a low memory single board computer. Is it possible to use this instead of Pi-hole? If so, I’d like to use it for all of my devices."
reply
rdme
4 hours ago
[-]
With 390K blocked domains: ~31MB total process footprint. Breakdown: - Blocklist: 23.4MB (390K domains) - Cache: 3.8MB (4.4K entries) - Query log, SRTT, runtime: ~4MB

It binds to 0.0.0.0:53 by default, so just point your devices' DNS to the board's IP

reply
rdme
8 hours ago
[-]
Thanks! If you hit any issues during setup, feel free to open an issue — happy to help debug. The dashboard at localhost:5380 shows what's happening in real time.
reply
siruwastaken
5 hours ago
[-]
Why are you replying to your own coment?
reply
happytoexplain
5 hours ago
[-]
I think it's a bot? There's an identical version of this comment in another reply, except it cuts off half way through a sentence.
reply
rdme
5 hours ago
[-]
I hit reply on the wrong post and you can't delete comments or at least I don't see how it can be done
reply
dgb23
3 hours ago
[-]
Above the comments I've written on HN I see:

5 minutes ago | parent | next | edit | delete

reply
hxugufjfjf
3 hours ago
[-]
That only lasts for a few minutes until it’s locked and you can no longer delete after that.
reply
rdme
5 hours ago
[-]
because I clicked reply on the wrong one and you can't delete it...
reply
dwedge
1 hour ago
[-]
I have a couple of projects that once a month need to run a few million dns lookups as quickly as possible. I'm tempted to try this just to see how it performs and if it breaks.
reply
rdme
1 hour ago
[-]
let me know if you do it!
reply
conradludgate
49 minutes ago
[-]
What's the reason you're not using hickory? Or was that the LLMs choice? Genuinely curious
reply
rdme
35 minutes ago
[-]
This was started as a learning project, went from the start to the lowest level then I've just added features I wanted one by one, it just made the most sense
reply
voxadam
4 hours ago
[-]
It's neither here nor there but can I ask about the name? I only ask because when I see "numa" in relation to computing I immediately think "Non-Uniform Memory Access".

Very cool project by the way. I wonder how this would run on an OpenWRT device.

I see in your install.sh that you support Linux and Darwin/MacOS, do you think there would be any major hurdles in supporting FreeBSD?

reply
rdme
4 hours ago
[-]
also in romanian nume = name(dns) and I also get the easter egg of that well known Romanian song numa numa :) https://www.youtube.com/watch?v=YnopHCL1Jk8

On OpenWRT — it's musl-based Linux so the binary should run the arm one would need a crosscompile Free BSD can be done (pr's welcome?)

reply
camdv
4 hours ago
[-]
On the web site, it's named after the second King of Rome
reply
p2hari
5 hours ago
[-]
Nice idea. To test I ran a simple nextjs on port 3000. Added the service via the dashboard. However, when I visit the url, (using chrome latest version), https://{mygivenname}.numa/ I hit a DNS resolution fail error. If I do not use a trailing '/' then it is going to google search for {mygivenname}.numa and shows me some search results. Should I open an issue?
reply
rdme
5 hours ago
[-]
Is it possible you didn't start it as root ( sudo numa install)? Does dig {mygivenname}.numa @127.0.0.1 return 127.0.0.1 ? What OS are you on? Maybe you report it as an issue?
reply
p2hari
5 hours ago
[-]
Thanks for quick response. It started to work. I think it must be some caching issue. But it needs a trailing '/' . Maybe will raise the issue for this. Cool.
reply
arcaen
4 hours ago
[-]
I believe that is actually browser specific behavior. I sometimes use a fake TLD for stuff hosted at home, and both chrome and firefox resort to search if I don't include a trailing '/'. My assumption is the browser does a quick match against known TLDs and if it doesn't match then it resorts to search.
reply
rdme
4 hours ago
[-]
exactly, I'll add a pr soon that tells the os (and browsers) that is'a a valid domain
reply
Asuka-wx
1 hour ago
[-]
Nice work. What made you choose this license?
reply
kevin061
3 hours ago
[-]
The interface looks vibecoded. I have no problem with people vibecoding things. In fact, I have zero frontend skills, so I rely on AI to be able to make easy-to-use interfaces. However, I feel like this should be clearly and prominently displayed in the project page.

Furthermore it is a little off-putting to see a vibecoded UI because I have very little confidence that the rest of the backend code is not vibecoded. I know I am possibly being unfair, but this is how it looks to me. If the developer tells me they didn't use AI at all, I would believe it.

reply
andoando
3 hours ago
[-]
I dont get this criticism at all, would you prefer someone write a shittier UI? And since when were people writing amazing bug free software before hand where not being vibe coded meant you could trust its good software?

I guess to be fair, beforehand no body would be attempting this kind of thing and releasing it unless they knew what they were doing

reply
rdme
3 hours ago
[-]
It definitely is and you can see it in the git commits. The DNS wire protocol parser was the original learning project I wrote to understand the spec. Later features (recursive resolver, DNSSEC validation, the dashboard) were built with the help of AI
reply
dev_l1x_be
3 hours ago
[-]
Given the state of webdev it is not a surprise. LLMs are my rubber gloves when working with web technologies.
reply
6r17
6 hours ago
[-]
Same hack here ; I have no DSN running by default - much more handy than having to set up nginx as it has no opinion on the targeted infrastructure. And the bonus point is that you can see every sneaky request that happens when you browse ; so another side-project connected to this is to make an inventory and policy filter
reply
rdme
6 hours ago
[-]
Yes sir! The query log is at GET /querylog (or on the dashboard) shows every request with domain, type, path (forwarded/recursive/cached/blocked) and latency
reply
dev_l1x_be
3 hours ago
[-]
How is to compare to AdGuard? If it gets those features I would be switching over.
reply
rdme
2 hours ago
[-]
Numa can do recursive resolution from root nameservers + DNSSEC, .numa local domains with auto HTTPS for dev, and LAN service discovery. What features would you be interested in?
reply
dwedge
1 hour ago
[-]
What about split horizon dns so I can locally resolve home servers instead of going to tailscale
reply
bahador
5 hours ago
[-]
feature request: libnuma so i can use it programmatically with configuration. also, multiple user defined blocklists.
reply
rdme
5 hours ago
[-]
Multiple blocklists already work -https://github.com/razvandimescu/numa/blob/main/numa.toml#L4... The pieces are already there for libnuma, it could be done, would you share what use case you have in mind?
reply
arafeq
5 hours ago
[-]
this is really clean. the auto-TLS for local dev is the killer feature imo, so many hours wasted fighting mkcert and nginx configs. do you plan to support docker/container networking? being able to resolve service names across docker compose setups would make this a no-brainer for teams.
reply
rdme
5 hours ago
[-]
Actually, if you point a container's DNS at the host (dns: [host.docker.internal] in compose), it works for resolution + ad blocking for the reverse however, I've added it on the radar, thanks!
reply
Kaliboy
4 hours ago
[-]
How does auto-TLS work? It makes a self signed certificate automatically?
reply
rdme
4 hours ago
[-]
Yes — numa install generates a local CA and stores it in the system trust store. When you register a .numa service, it generates a per-service TLS cert signed by that CA
reply
dgb23
3 hours ago
[-]
I don't want to hijack the thread, because that's a cool project.

Still, if you're looking for something that "just works" and is widely used, have a look at caddy.

reply
rbluethl
9 hours ago
[-]
Cool idea, every developer running apps in dev on their machine knows this pain for sure. I'll give it a spin and let you know how it goes!
reply
rdme
6 hours ago
[-]
Thanks! If you hit any issues during setup, feel free to open an issue — happy to help debug. The dashboard at localhost:5380 (or at https://numa.numa)
reply
_kidlike
6 hours ago
[-]
very interesting. how does the blocklist work? can one manage the lists? like StevenBlack or others.
reply
rdme
6 hours ago
[-]
Yes, it is configurable as a list https://github.com/razvandimescu/numa/blob/main/numa.toml#L4...

There's also a per-domain allowlist and you can pause/unpause blocking from the dashboard or API.

Here's how the resolution pipeline looks like: https://numa.rs/blog/posts/dns-from-scratch.html#the-resolut...

reply
lyfeninja
9 hours ago
[-]
I think I need to give this a go. Cool project.
reply
rdme
8 hours ago
[-]
Thanks! Let me know how it goes.
reply
bulanel
2 hours ago
[-]
nice
reply
EdoardoIaga
5 hours ago
[-]
Rust it’s crazy good
reply
voltagex_
6 hours ago
[-]
Great idea, pity about the slop.
reply
goodpoint
4 hours ago
[-]
we need a [slop] flag in the headlines
reply