|
| 1 | +# Managed DNS Server |
| 2 | + |
| 3 | +A DNS server implementation written in Go from **scratch**, |
| 4 | +supporting a management service via a RESTful API. |
| 5 | +This project includes custom DNS record handling, database |
| 6 | +integration for record persistence, and configuration management. |
| 7 | + |
| 8 | +## Features |
| 9 | + |
| 10 | +- Custom _authorative_ DNS server and client implementation. |
| 11 | +- REST API for managing DNS records. |
| 12 | +- Supports `A`, `CNAME`, and other common DNS record types. |
| 13 | +- Uses PostgreSQL for persistent record storage. |
| 14 | +- Implements EDNS (Extension Mechanisms for DNS) with optional support. |
| 15 | + |
| 16 | +# Background |
| 17 | + |
| 18 | +## How DNS Resolution Works |
| 19 | + |
| 20 | +When you type a domain name into your browser (e.g., `www.example.com`), your computer needs to convert that domain name into an |
| 21 | +IP address so it can communicate with the correct server. This process is known as **DNS resolution** and involves several steps: |
| 22 | + |
| 23 | +1. **Root Name Servers** |
| 24 | + The process begins with a request to a **root name server**. |
| 25 | + The root name servers are responsible for directing the query to the appropriate **Top-Level Domain (TLD)** server based |
| 26 | + on the suffix of the domain name (e.g., `.com`, `.org`, `.net`). |
| 27 | + |
| 28 | +2. **TLD Servers** |
| 29 | + The TLD servers are responsible for handling the domain extensions (such as `.com`, `.org`, etc.). |
| 30 | + When the root name server directs the query to the correct TLD server, the TLD server then provides information about the authoritative name servers for the requested domain. |
| 31 | + |
| 32 | +3. **Authoritative Name Servers** |
| 33 | + The **authoritative name servers** hold the final DNS records for the domain. |
| 34 | + They are responsible for returning the IP address of the requested domain. |
| 35 | + These servers can be the domain's hosting provider or a DNS service you configure (such as Cloudflare or Google DNS). |
| 36 | + **This implementation works as an authoritative name server** |
| 37 | + |
| 38 | +### Types of Resolvers |
| 39 | + |
| 40 | +There are two main types of DNS resolvers that interact with these name servers: |
| 41 | + |
| 42 | +- **Recursive Resolver** |
| 43 | + A **recursive resolver** is responsible for making the full query process. |
| 44 | + It starts at the root name servers and follows the chain through the TLD servers until it |
| 45 | + reaches the authoritative servers. It then returns the final result (IP address) to the client. |
| 46 | + This type of resolver performs all the necessary steps and provides a complete answer. |
| 47 | + |
| 48 | +- **Iterative Resolver** |
| 49 | + An **iterative resolver**, on the other hand, only provides partial answers. |
| 50 | + It queries the root name servers for a direction to the TLD servers and then asks the TLD servers for the authoritative servers. |
| 51 | + The iterative resolver does not follow the full path and relies on the client (or a recursive resolver) to complete the final step. |
| 52 | + |
| 53 | +## DNS Message Format |
| 54 | + |
| 55 | +The DNS protocol uses a specific binary message format for communication between clients (resolvers) and servers. |
| 56 | +Each DNS message consists of a **header**, a **question section**, and optional **answer**, **authority**, and **additional sections**. |
| 57 | +Below is a detailed explanation of each part of the DNS message. |
| 58 | + |
| 59 | +--- |
| 60 | + |
| 61 | +### DNS Message Structure |
| 62 | + |
| 63 | +1. **Header (12 bytes)** |
| 64 | + The header contains metadata about the DNS query or response. |
| 65 | + |
| 66 | + | Field | Size (bits) | Description | |
| 67 | + | ------------------- | ----------- | ------------------------------------------------------------ | |
| 68 | + | Transaction ID | 16 | Unique identifier for matching requests and responses. | |
| 69 | + | Flags | 16 | Control and status flags (e.g., QR, Opcode, AA, TC, RD, RA). | |
| 70 | + | Question Count | 16 | Number of questions in the Question section. | |
| 71 | + | Answer Record Count | 16 | Number of resource records in the Answer section. | |
| 72 | + | Authority Count | 16 | Number of resource records in the Authority section. | |
| 73 | + | Additional Count | 16 | Number of resource records in the Additional section. | |
| 74 | + |
| 75 | + #### Header Flags Breakdown (16 bits) |
| 76 | + |
| 77 | + The flags field is divided into individual control flags and operation codes: |
| 78 | + | Bit | Name | Description | |
| 79 | + |-----|---------------|-----------------------------------------------------------------------------| |
| 80 | + | 0 | QR | Query (0) or Response (1). | |
| 81 | + | 1-4 | Opcode | Type of query (e.g., 0 for standard query). | |
| 82 | + | 5 | AA | Authoritative Answer (set by authoritative servers in responses). | |
| 83 | + | 6 | TC | Truncated Message (set if the message is too large for the transport). | |
| 84 | + | 7 | RD | Recursion Desired (set by clients to request recursion). | |
| 85 | + | 8 | RA | Recursion Available (set by servers that support recursion). | |
| 86 | + | 9-11| Z | Reserved for future use; must be set to 0. | |
| 87 | + | 12-15 | RCODE | Response Code (e.g., 0 for NOERROR, 3 for NXDOMAIN). | |
| 88 | + |
| 89 | +--- |
| 90 | + |
| 91 | +2. **Question Section** |
| 92 | + The question section specifies the query details sent by the client. |
| 93 | + |
| 94 | + | Field | Size (variable) | Description | |
| 95 | + | ------ | --------------- | --------------------------------------------- | |
| 96 | + | QNAME | Variable | Domain name being queried, encoded in labels. | |
| 97 | + | QTYPE | 16 bits | Type of query (e.g., A, AAAA, CNAME, MX). | |
| 98 | + | QCLASS | 16 bits | Class of query (e.g., IN for Internet). | |
| 99 | + |
| 100 | + #### Example: |
| 101 | + |
| 102 | + For the domain `example.com`, the `QNAME` is encoded as: [7]example[3]com[0] |
| 103 | + |
| 104 | +Where each label is preceded by its length, and the name is terminated by a zero byte. |
| 105 | + |
| 106 | +--- |
| 107 | + |
| 108 | +3. **Answer Section** |
| 109 | + Contains resource records (RRs) that answer the query. Each RR has the following fields: |
| 110 | + |
| 111 | +| Field | Size (variable) | Description | |
| 112 | +| -------- | --------------- | ---------------------------------------------------------- | |
| 113 | +| NAME | Variable | Domain name to which the RR applies (often a pointer). | |
| 114 | +| TYPE | 16 bits | Type of RR (e.g., A, AAAA, CNAME). | |
| 115 | +| CLASS | 16 bits | Class of RR (e.g., IN for Internet). | |
| 116 | +| TTL | 32 bits | Time-to-live, in seconds, for caching the RR. | |
| 117 | +| RDLENGTH | 16 bits | Length of the RDATA field. | |
| 118 | +| RDATA | Variable | Data associated with the RR (e.g., IP address for A type). | |
| 119 | + |
| 120 | +--- |
| 121 | + |
| 122 | +4. **Authority Section** |
| 123 | + Contains RRs pointing to authoritative servers for the queried domain. The format is identical to the Answer section. |
| 124 | + |
| 125 | +--- |
| 126 | + |
| 127 | +5. **Additional Section** |
| 128 | + Provides additional data, such as: EDNS cookies or resolved records that might be useful for the resolver |
| 129 | + |
| 130 | +## Name Compression in DNS Messages |
| 131 | + |
| 132 | +To reduce the size of DNS messages, domain names can be encoded using **name compression**. Name compression replaces repeated domain name labels with pointers to their previous occurrences in the message. |
| 133 | + |
| 134 | +### Pointer Format |
| 135 | + |
| 136 | +A pointer uses the most significant 2 bits of a label length byte to indicate a compressed label: |
| 137 | + |
| 138 | +- **Pointer Indicator:** The first two bits of the byte are set to `11` (binary). |
| 139 | +- **Offset:** The remaining 14 bits represent the pointer's offset from the start of the DNS message. |
| 140 | + |
| 141 | +### Example: |
| 142 | + |
| 143 | +Consider the domain name `example.com` appearing multiple times in a DNS response: |
| 144 | + |
| 145 | +- The first occurrence is encoded as: [7]example[3]com[0] |
| 146 | + |
| 147 | +- Subsequent occurrences use a pointer: [C0 0C] |
| 148 | + |
| 149 | +## Extended DNS (EDNS) |
| 150 | + |
| 151 | +EDNS extends DNS by adding an **OPT pseudo-record** in the additional section, enabling features like larger message sizes and DNS Cookies. |
| 152 | + |
| 153 | +### OPT Record Structure: |
| 154 | + |
| 155 | +| Field | Size | Description | |
| 156 | +| -------------- | -------- | ---------------------------------------- | |
| 157 | +| NAME | 0 bytes | Must be 0 (root domain). | |
| 158 | +| TYPE | 16 bits | Always `OPT` (value 41). | |
| 159 | +| UDP Size | 16 bits | Maximum UDP payload size supported. | |
| 160 | +| Extended RCODE | 8 bits | Extended response codes. | |
| 161 | +| Version | 8 bits | EDNS version (currently 0). | |
| 162 | +| Flags | 16 bits | Various flags (e.g., DO bit for DNSSEC). | |
| 163 | +| Data | Variable | Optional data like DNS Cookies. | |
| 164 | + |
| 165 | +--- |
| 166 | + |
| 167 | +## Requirements |
| 168 | + |
| 169 | +- [Go 1.20+](https://go.dev/dl/) |
| 170 | +- [PostgreSQL 12+](https://www.postgresql.org/) |
| 171 | +- [GORM](https://gorm.io/) ORM for database operations |
| 172 | +- [GIN](https://gin-gonic.com/) Web framework for REST API interface |
| 173 | +- Docker (optional, for containerized deployment) |
| 174 | + |
| 175 | +## Installation |
| 176 | + |
| 177 | +1. Clone the repository: |
| 178 | + |
| 179 | +```bash |
| 180 | +git clone https://github.com/XxRoloxX/dns.git |
| 181 | +cd dns |
| 182 | +``` |
| 183 | + |
| 184 | +2. Set up environment variable for database configuration |
| 185 | + |
| 186 | +```bash |
| 187 | +export DB_HOST=localhost |
| 188 | +export DB_USER=youruser |
| 189 | +export DB_PASSWORD=yourpassword |
| 190 | +export DB_NAME=yourdb |
| 191 | +export DB_PORT=5432 |
| 192 | +``` |
| 193 | + |
| 194 | +or just write them to the .env file |
| 195 | + |
| 196 | +3. Build and run docker-compose |
| 197 | + |
| 198 | +```bash |
| 199 | +docker compose up -d |
| 200 | +``` |
| 201 | + |
| 202 | + |
| 203 | + |
| 204 | +## Deployment |
| 205 | + |
| 206 | +To begin using this server in production, register a NS |
| 207 | +(Name Server) record with your domain registrar and point it |
| 208 | +to the instance hosting this server. Once this is done, |
| 209 | +the server will be able to manage the **delegated zone**, and |
| 210 | +all DNS queries for the associated subdomain will be directed to the newly deployed server. |
| 211 | + |
| 212 | +For example, if your domain is `example.com` and the subdomain is `sub.example.com`, |
| 213 | +you would add a NS record pointing sub.example.com to the IP address or |
| 214 | +hostname of the new server, allowing it to handle all DNS traffic for that subdomain. |
| 215 | + |
| 216 | +## API ENDPOINTS |
| 217 | + |
| 218 | +### BASE URL |
| 219 | + |
| 220 | +`http://localhost:8080/` |
| 221 | + |
| 222 | +### For DNS server |
| 223 | + |
| 224 | +`localhost:53` (udp) |
| 225 | + |
| 226 | +### Endpoints |
| 227 | + |
| 228 | +#### Get all Records |
| 229 | + |
| 230 | +_GET_ `/records` |
| 231 | + |
| 232 | +- Request response |
| 233 | + |
| 234 | +```json |
| 235 | +[ |
| 236 | + { |
| 237 | + "name": "example.com", |
| 238 | + "type": "A", |
| 239 | + "class": "IN", |
| 240 | + "data": "192.168.1.1" |
| 241 | + } |
| 242 | +] |
| 243 | +``` |
| 244 | + |
| 245 | +#### Create record |
| 246 | + |
| 247 | +_POST_ `/records` |
| 248 | + |
| 249 | +- Request body |
| 250 | + |
| 251 | +```json |
| 252 | +[ |
| 253 | + { |
| 254 | + "name": "example.com", |
| 255 | + "type": "A", |
| 256 | + "class": "IN", |
| 257 | + "data": "192.168.1.1" |
| 258 | + } |
| 259 | +] |
| 260 | +``` |
| 261 | + |
| 262 | +#### Delete record |
| 263 | + |
| 264 | +_DELETE_ `/records/:id` |
| 265 | + |
| 266 | +```json |
| 267 | +{ |
| 268 | + "message": "Record deleted succefully" |
| 269 | +} |
| 270 | +``` |
| 271 | + |
| 272 | + |
| 273 | + |
| 274 | +## Resources |
| 275 | + |
| 276 | +- [RFC 1035: Domain Names - Implementation and Specification](https://datatracker.ietf.org/doc/html/rfc1035) |
| 277 | +- [RFC 1034: Concepts and Facilities](https://www.ietf.org/rfc/rfc1034.txt) |
| 278 | +- [RFC 6891: Extension Mechanisms for DNS (EDNS)](https://datatracker.ietf.org/doc/html/rfc6891) |
0 commit comments