# How I Developed a DNS Server to Explore Networking: The NexoralDNS Story

### Why This Project Exists (The Real Reason)

NexoralDNS didn’t start as a “product idea”.

It started with **curiosity**.

When I first tried to learn how DNS servers work—from blogs and YouTube—the explanations felt abstract:

* *UDP call on port 53*
    
* *recursive resolver*
    
* *authoritative response*
    
* *domain hierarchy*
    

I understood the words, but not the **flow**.

So I asked myself a simple question:

> *If DNS is just a UDP server listening on port 53, what happens if I build one myself?*

That question is where **NexoralDNS** was born.

---

## The First Curiosity That Changed Everything

DNS uses **UDP**, and Node.js has `dgram`.

So I thought:

* What if I start a UDP server on port **53**?
    
* What if I point my router’s DNS to my laptop’s private IP?
    
* Will it actually resolve domains?
    

I tried it.

**It worked.**

That single experiment changed my understanding completely.

At that moment, DNS stopped being “magic infrastructure” and became:

> **Packets → Buffers → Logic → Response**

And once that clicked, I went deeper.

---

## What NexoralDNS Actually Provides

NexoralDNS is a **LAN-focused, programmable DNS server** built to understand and control DNS behavior at a low level.

It currently provides:

* A custom DNS server handling **UDP 53**
    
* Domain parsing from raw **Buffer data**
    
* Recursive domain hierarchy understanding (`sub → root → TLD`)
    
* Rule-based domain control (block, allow, redirect)
    
* Admin panel to control DNS behavior
    
* Internal service-to-service communication using a **custom TCP broker**
    
* Automatic rebinding when IP changes via DHCP signals
    

It’s not meant to replace Cloudflare or public resolvers.  
It’s meant for **offices, labs, learning, and internal networks**.

---

## Architecture (Why Multi-Folder Matters)

The project is intentionally **multi-folder**, because I designed it for future evolution.

### Folder Breakdown

* **Core DNS Engine**
    
    * Handles UDP packets
        
    * Parses DNS queries from raw buffers
        
    * Generates responses
        
    * Uses Node Cluster for concurrency
        
* **DHCP**
    
    * Listens for IP changes
        
    * Detects when DNS server IP changes
        
    * Notifies other services to rebind port 53
        
* **Broker**
    
    * Custom TCP-based message broker
        
    * Built to understand service notifications
        
    * Replaced RabbitMQ *intentionally* to learn internals
        
* **Server**
    
    * Admin APIs written in **Fastify**
        
    * Controls rules, domains, and configs
        
* **Web**
    
    * Admin UI built with **Next.js**
        
    * Visual control over DNS rules and analytics
        

This separation makes one thing very important:

> **If I replace the Core DNS engine with Golang later,  
> I only need to change the core — not the Web or Admin layers.**

That decision was deliberate.

---

## Why I Chose Node.js Over Golang or Rust (Honestly)

Let me be blunt.

I didn’t choose Node.js because it’s the “best” language for DNS.

I chose it because:

* I **know Node.js deeply**
    
* I understand async behavior
    
* I can move fast with logic
    
* I trust myself to debug it
    

At the beginning, **confidence matters more than performance**.

I knew:

* If I picked Golang *without deep networking confidence*, I’d stall
    
* If I picked Rust, I’d fight the compiler instead of learning DNS
    

My belief:

> **Logic &gt; Language**

Languages can change.  
Understanding **packet flow, recursion, and hierarchy** is permanent.

---

## What I Learned While Building This

This project taught me things no tutorial ever could:

### 1\. DNS Parsing from Raw Buffers

* How queries arrive as binary
    
* How to extract:
    
    * Domain name
        
    * Query type (A, AAAA, CNAME, etc.)
        
* How compression pointers work
    

### 2\. Recursive Domain Hierarchy

* Why DNS is not just a lookup
    
* How delegation works
    
* How recursion actually flows internally
    

### 3\. UDP Is Stateless (And That Matters)

* No connection
    
* No retry guarantee
    
* You must respond **fast**
    

### 4\. Node Cluster for DNS

To improve performance:

* I used **Node.js Cluster**
    
* Spread UDP load across CPU cores
    

With this setup, NexoralDNS handled:

> **~7,000 QPS**, measured using `dnsperf`

That number surprised me.

---

## Performance Reality Check

Let’s be honest again.

* Node.js at ~7k QPS: **good**
    
* Golang at the same logic: **10k+ QPS easily**
    

I know this.

That’s why my **future plan** is clear:

* Rewrite the **Core DNS handler in Golang**
    
* Keep Admin, Web, and Control layers intact
    

Before that:

> I need to *understand networking deeply* — not just write faster code.

I’m learning Go now, slowly and correctly.

---

## Why I Built My Own TCP Broker

Before using RabbitMQ, I asked:

> *Do I really understand how message brokers work?*

So I built one.

A simple **TCP-based message broker** that:

* Allows one service to notify another
    
* Used by DHCP → Web → DNS engine
    
* Handles rebinding and runtime coordination
    

This taught me:

* Why brokers exist
    
* Where RabbitMQ adds value
    
* Where custom solutions make sense
    

This wasn’t about replacing RabbitMQ.  
It was about **earning the right to use it knowingly**.

---

## The Bigger Picture

NexoralDNS is not about DNS alone.

It’s about:

* Understanding networking fundamentals
    
* Removing fear from “core systems”
    
* Proving that curiosity + experiments beat tutorials
    

I didn’t build this to impress anyone.  
I built it because I wanted answers.

And now I have them.

---

## What’s Next

* Rewrite Core DNS engine in **Golang**
    
* Improve rule engine performance
    
* Better analytics for LAN usage
    
* Hardening broker communication
    
* Deeper recursion optimizations
    

This project already did its job:

> **It turned DNS from theory into intuition.**

And that was the real goal.
