The Problem
Many DNS resolvers cache arbitrary data, but there is no simple way to store and retrieve user‑provided payloads using that cache. The result is a “store‑in‑the‑cloud” capability that relies only on publicly reachable DNS infrastructure, avoiding dedicated storage services.
What This Does
The repository is a portfolio of six small Go utilities that together demonstrate the concept of a DNS‑backed filesystem.
dnsfs/– core server implementation (dns.go,http.go,main.go). It runs a DNS listener, accepts upload/download requests, shards data across resolver IPs, and persists the mapping in the resolver cache.bulk-mmlookup/– a CLI (main.go) that can query many resolvers in parallel, useful for bulk look‑ups.retention-check/&version-check/– small tools that read a CSV of resolver IPs (ReadRes) and perform simple health checks. Their code blocks are duplicated (44‑line repetition).retention-stats/– gathers timing statistics for the checks.data/– sample CSV files used by the check tools.
All Go source lives under vendor/ (third‑party libraries) and the five top‑level utilities. The only build artifact is a Makefile.
How It Is Wired
- Entry point –
dnsfs/main.godefinesmain. It parses a resolver list (parseIPList→ioutil.ReadFile) and callsstartDNSListener. startDNSListener(indnsfs/dns.go) creates a DNS server (github.com/miekg/dns) and spawnsDNSLoop.DNSLoopreceives DNS queries, validates the NS setup (verifyNSsetup), and routes to eitheruploadChunkorfetchFromShard.- Both upload and fetch use
getDNSserverShardto map a data key to a resolver IP; this function is the only one called from two places. uploadChunkwrites the payload into the chosen resolver’s cache;fetchFromShardreads it back.- HTTP handlers (
handleUpload,handleDownloadindnsfs/http.go) wrap the same upload/fetch logic for REST access.
The call graph is shallow: 9 internal edges, with main → ReadRes (used by the check tools) and main → parseIPList being the only filesystem interactions. The hub is getDNSserverShard, which appears in both upload and fetch paths, so changes there affect both directions. No circular dependencies are present.
The check utilities (retention‑check/main.go, version‑check/main.go) each contain a duplicated ReadRes implementation (44 repeated lines). They read the resolver CSV and iterate over entries, but otherwise do not interact with the DNS server.
How To Use It
# clone the repo
git clone https://github.com/moses-y/dnsfs
cd dnsfs
# build the server (Makefile provides a default target)
make # or: go build ./dnsfs
# start the DNS‑FS server (requires a CSV of resolvers)
./dnsfs -resolvers data/Resolvers-To-Internet-Users.csv
The README does not specify flags; the source shows parseIPList expects a path, so the binary must be invoked with that argument.
To perform a bulk lookup:
go run bulk-mmlookup/main.go data/Resolvers-To-Internet-Users.csv
Health‑check tools are invoked similarly:
go run retention-check/main.go data/Resolvers-To-Internet-Users.csv
go run version-check/main.go data/Resolvers-To-Internet-Users.csv
No Dockerfile or CI scripts are present, so containerisation or automated testing must be added manually.
Real‑World Use
A security‑research team could embed short configuration snippets in DNS TXT records of widely used public resolvers, then retrieve them from any network without needing a separate storage endpoint. The team would run the dnsfs server on a host they control, upload the snippets, and distribute the resolver list to their agents, which use bulk-mmlookup to pull the data.
Code Health & Issues
- High – Missing LICENSE – No license file at the repository root; the code cannot be legally reused without clarification.
- High – Duplicated code –
retention-check/main.goandversion-check/main.goshare a 44‑line block (ReadRes). Extracting this into a shared helper would reduce maintenance risk. - Medium – No tests – No
_test.gofiles; code paths are unverified. - Medium – No CI/CD – No
.github/workflowsor other pipeline definitions; builds are not automatically validated.
The Bottom Line
dnsfs provides a functional proof‑of‑concept for storing data in DNS resolver caches, with a clear separation of a server component and several helper utilities. The code is lightweight but lacks test coverage, CI, and a license, and contains duplicated logic in the check tools. It is suitable for experimentation or research, but would need additional engineering (tests, CI, licensing) before production use.