Skip to content

NyasakiAT/go-dns

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

44 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Go DNS Forwarder

A lightweight DNS forwarder written in Go.
It listens for DNS queries, forwards them to an upstream resolver (e.g. 9.9.9.9), and sends the responses back to the client.

Designed for learning how DNS works at the packet level — parsing headers, handling compression pointers, and building real network logic from scratch.

Go golangci-lint

🚀 Features

  • Parses and builds DNS headers manually (bit-fields, flags, etc.)
  • Handles domain name compression (0xC0 pointer format)
  • Forwards queries to upstream servers (9.9.9.9:53)
  • Non-blocking UDP handling using goroutines
  • Simple logging for requests and responses

🧭 Planned / TODO

🧠 Caching Layer

Goal: reduce upstream lookups and improve response speed.

  • Implement an in-memory cache using sync.Map or LRU.
  • Cache key: (QNAME, QTYPE, QCLASS, DO-bit).
  • Respect DNS TTLs: store expiry timestamp and auto-expire entries.
  • Rewrite transaction ID when serving cached responses.
  • Add optional persistent cache (Ideally redis?)

🚫 Blocklists / Sinkhole

Goal: block unwanted or malicious domains.

  • Load a list of domains from file or URL (blocklist.txt).
  • Match on full domain or suffix (e.g. ads.google.com, *.tracking.net).
  • Return a synthetic A record (0.0.0.0) or NXDOMAIN instead of forwarding.
  • Cache blocked responses with infinite TTL.

🌍 GeoIP Lookup

Goal: log or route queries based on the client’s location.

🏠 Local Overrides / Hosts File

Goal: define custom static records for specific domains.

  • Load mappings from a simple hosts.json or /etc/hosts style file:
    {
      "my.local.dev": "192.168.1.50",
      "printer.lan": "192.168.1.200"
    }
  • When a matching QNAME is found, bypass upstream and reply locally.
  • Cache local overrides as permanent records.

⚙️ Misc Enhancements

  • Support multiple upstream resolvers with round-robin or fallback logic.
  • Return SERVFAIL when upstream times out.
  • Implement EDNS(0) and support larger UDP payloads.
  • Graceful shutdown and metrics summary on exit.
  • Command-line flags:
    • --listen :8053
    • --upstream 9.9.9.9:53,1.1.1.1:53
    • --cache-ttl 300s
    • --geoip-db ./GeoLite2-City.mmdb

🧩 Documentation Used

ristretto Simple DNS Client by Alan Mislove Create a TCP and UDP Client and Server using Go (Video) Bitwise Operators by Alex Hyett RFC1035 RFC2782


📜 License

MIT — free to study, hack, and extend.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors