I'm Ozy-666. I build and run DNSDOH.ART - a public, no-logs encrypted DNS resolver on a single carefully-tuned server, where every component in the request path has been rebuilt from source.
It started in 2022 on a free Oracle VPS. Port 53 was open to the internet, and for about a week my server was quietly being used as an amplifier in DNS reflection attacks. I looked at that traffic, decided it wasn't an attack, and did nothing. Oracle deleted the instance - correctly. Almost everything I've built since comes out of that week.
What I run
§1
One server, in the open
DNSDOH.ART serves DoH, DoH3, DoT, DoQ and plain DNS, blocks ads and trackers, keeps no logs, and costs nothing. There's no company behind it and there never will be.
| Cost | None | no account · no app needed |
| Logs kept | 0 | nothing recorded, ever |
| Transports | DoH · DoT · DoQ · H3 | phone · laptop · router |
| Source | All of it | every fork is public |
It is one server, not an anycast network. Cloudflare and Quad9 are genuinely excellent and I'm not pretending to match their reach - that's not something one person replicates. What a single node can be is stable, fast, and extremely hard to abuse. That's what I optimise for: layers of defence in front of it, from XDP at the network card through nftables to filtering at the application layer.
Use it →
The work
§2
What I changed, and how I checked
Every number below was measured on the production host. Where a claim has a verification method, it's stated - a number without one is just a number.
2.1AdGuardHome-edge
−13k LOC · −10 MB
The engine. I stripped ~13k lines of anything that leaks data or wastes time - DHCP, cloud lookups, client-subnet - rebuilt the request pipeline to allocate nothing on the hot path, and made the serve path lock-free so it holds up under flood. A built-in front cache means most repeat lookups never leave the box.
0-alloc pipeline · lock-free serve path · front-cache +60% · −13k LOC
github.com/Ozy-666/AdGuardHome-edge-spec →
2.2dnsproxy
+101% throughput
How requests travel in and out. Rebuilt the UDP and TCP paths to allocate nothing, made upstream RTT tracking lock-free, pooled connections instead of reopening one per query, and sharded the listener across every core with SO_REUSEPORT. It also caps QUIC streams and DoH request sizes so one client can't exhaust it.
0 allocs/op · lock-free RTT map · SO_REUSEPORT · flood caps
github.com/Ozy-666/dnsproxy →
2.3dnscrypt-proxy
security-audited
Encrypts DNS on its way out to the wider internet. Rebuilt the busy paths to allocate nothing, made server selection lock-free, and stripped everything that phones home - the web UI, auto-updates, remote list downloads and ODoH, about 800 lines of protocol removed purely to cut attack surface. It now rejects forged upstream replies.
0 allocs/op · lock-free WP2 · −455 KB · ODoH stripped
github.com/Ozy-666/dnscrypt-proxy →
The matcher that decides what's an ad or a tracker. I changed how it indexes regular-expression rules so they're found by literal extraction instead of scanned one by one - closing a path an attacker could use to slow the resolver with floods of fake subdomains.
Verified: identical results to the original engine across 39,983 real domains plus 130,000 fuzz runs, 0 divergences. The flood benchmark went from 111 µs to 449 ns at 1,000 regex rules, and stays flat as rules are added.
O(1) regex miss path · 0 query-path allocs · 0 divergences
github.com/Ozy-666/urlfilter →
2.5Unbound + BoringSSL
+14% · −27%
The part that proves an answer is genuine. Checking DNSSEC signatures was eating close to half the server's CPU, so I rebuilt Unbound against BoringSSL - keeping a one-command rollback ready, and no Unbound source patched: the customisation is entirely build flags, config and systemd units.
+14% end-to-end DNSSEC throughput, −27% worst-case latency. The mechanism is roughly 30% faster signature verification - ECDSA P-256 +28.8%, RSA-2048 +34.2% against OpenSSL 3.0.16, over 8 paired rounds with the same benchmark compiled against both libraries. DNSSEC crypto was about 44% of Unbound's CPU, so a ~30% gain on 44% of the work predicts ~13% overall; the end-to-end flood measured +14%. The benchmark ships with the repo, so a library bump can be re-checked rather than assumed.
pinned BoringSSL · full DNSSEC validation · Zen 2 tuned · benchmark included
github.com/Ozy-666/unbound-edge →
2.6nginx + BoringSSL
post-quantum · ECH
The front door, answering every encrypted request before anything else sees it. Building on BoringSSL buys three things a stock build cannot do. The name of the site you asked for is encrypted too, with Encrypted Client Hello, instead of travelling in the clear. Traffic recorded today can't be unlocked by a future quantum computer, because the key exchange is already post-quantum. And it speaks HTTP/3, so pages start a round trip sooner.
nginx implements ECH only against the OpenSSL 3.x API, so the repo carries one patch adding the BoringSSL path. The build verifies the PGP signature on every download before it compiles anything, and refuses to proceed on an unpinned signing key.
A DoH3 handshake here started failing about one attempt in twenty, and it was not my build. When the server's ServerHello spans two Initial packets and one of them is lost, nginx never retransmits it: the handshake deadlocks until the client gives up, and nothing is logged. I traced it to the congestion controller rather than the retransmission logic and reported it with a reproduction. nginx opened a fix crediting the report - still open, not merged. Rebuilding their candidate here cleared the case I reported, and showed the deadlock returns once the certificate chain is large enough to fill QUIC's initial congestion window, which post-quantum certificates are big enough to do.
X25519MLKEM768 · Encrypted Client Hello · HTTP/3 + Brotli · PGP-verified builds
github.com/Ozy-666/nginx-edge →
nginx/nginx#1616 →
2.7Everything else
the unglamorous half
Redis holds the leak-test state, in memory only - no RDB, no AOF, nothing on disk. The update scripts for nginx, Unbound and Redis all verify checksums or signatures before building, test the new binary against the live config before installing it, and roll back automatically if the service doesn't answer afterwards. A watcher tracks every upstream and tells me when one moves, and only when there's something to actually do.
verified builds · pre-install gates · automatic rollback · upstream watch