mirror of
https://github.com/DevVoxel/VectorDNS.git
synced 2026-02-27 05:47:38 +00:00
Add architecture docs and Go microservice to tech stack
This commit is contained in:
@@ -21,7 +21,8 @@ DNS lookup, WHOIS, and domain monitoring tool. Search nameservers, check domain
|
|||||||
- **DNS**: Tangerine (DNS-over-HTTPS via Cloudflare/Google)
|
- **DNS**: Tangerine (DNS-over-HTTPS via Cloudflare/Google)
|
||||||
- **WHOIS**: whoiser (RDAP-based, free)
|
- **WHOIS**: whoiser (RDAP-based, free)
|
||||||
- **Email**: Resend
|
- **Email**: Resend
|
||||||
- **Deployment**: Vercel
|
- **DNS API**: Go microservice on VPS ([`miekg/dns`](https://github.com/miekg/dns) — direct UDP/TCP resolution, DNSSEC, propagation checks)
|
||||||
|
- **Deployment**: Vercel (frontend) + VPS (Go DNS API)
|
||||||
- **Package Manager**: Bun
|
- **Package Manager**: Bun
|
||||||
|
|
||||||
## Getting Started
|
## Getting Started
|
||||||
@@ -63,6 +64,10 @@ Open [http://localhost:3000](http://localhost:3000) to see the app.
|
|||||||
| `CRON_SECRET` | Yes | Secret to authenticate Vercel cron requests |
|
| `CRON_SECRET` | Yes | Secret to authenticate Vercel cron requests |
|
||||||
| `RESEND_API_KEY` | No | Resend API key for email notifications |
|
| `RESEND_API_KEY` | No | Resend API key for email notifications |
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
VectorDNS uses a hybrid architecture: Next.js on Vercel for the frontend, and a Go microservice on a VPS for DNS resolution and monitoring. See [docs/architecture.md](./docs/architecture.md) for details and [docs/api-spec.md](./docs/api-spec.md) for the Go API spec.
|
||||||
|
|
||||||
## Project Structure
|
## Project Structure
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|||||||
135
docs/api-spec.md
Normal file
135
docs/api-spec.md
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
# Go DNS API Specification
|
||||||
|
|
||||||
|
Base URL: `https://<vps-host>/api/v1`
|
||||||
|
|
||||||
|
All requests require the header `X-API-Key: <shared-secret>`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Endpoints
|
||||||
|
|
||||||
|
### `POST /dns/lookup`
|
||||||
|
|
||||||
|
Resolve DNS records for a domain.
|
||||||
|
|
||||||
|
**Request:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"domain": "example.com",
|
||||||
|
"types": ["A", "AAAA", "MX", "TXT", "NS", "CNAME", "SOA", "CAA", "SRV"],
|
||||||
|
"nameserver": "8.8.8.8"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `domain` (required): The domain to query.
|
||||||
|
- `types` (optional): Record types to query. Defaults to all supported types.
|
||||||
|
- `nameserver` (optional): Specific nameserver to query. Defaults to system resolver.
|
||||||
|
|
||||||
|
**Response (200):**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"domain": "example.com",
|
||||||
|
"nameserver": "8.8.8.8",
|
||||||
|
"records": {
|
||||||
|
"A": [{ "value": "93.184.216.34", "ttl": 300 }],
|
||||||
|
"MX": [{ "value": "mail.example.com", "priority": 10, "ttl": 3600 }]
|
||||||
|
},
|
||||||
|
"query_time_ms": 12
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `POST /dns/propagation`
|
||||||
|
|
||||||
|
Check DNS propagation across multiple resolvers.
|
||||||
|
|
||||||
|
**Request:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"domain": "example.com",
|
||||||
|
"type": "A",
|
||||||
|
"resolvers": ["8.8.8.8", "1.1.1.1", "9.9.9.9"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `resolvers` (optional): Defaults to a built-in list of public resolvers.
|
||||||
|
|
||||||
|
**Response (200):**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"domain": "example.com",
|
||||||
|
"type": "A",
|
||||||
|
"results": [
|
||||||
|
{ "resolver": "8.8.8.8", "values": ["93.184.216.34"], "ttl": 300 },
|
||||||
|
{ "resolver": "1.1.1.1", "values": ["93.184.216.34"], "ttl": 280 },
|
||||||
|
{ "resolver": "9.9.9.9", "values": ["93.184.216.34"], "ttl": 295 }
|
||||||
|
],
|
||||||
|
"consistent": true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `POST /dns/validate`
|
||||||
|
|
||||||
|
DNSSEC validation for a domain.
|
||||||
|
|
||||||
|
**Request:**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"domain": "example.com"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Response (200):**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"domain": "example.com",
|
||||||
|
"dnssec": true,
|
||||||
|
"chain_valid": true,
|
||||||
|
"details": "RRSIG verified for A record"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### `GET /health`
|
||||||
|
|
||||||
|
Health check. No authentication required.
|
||||||
|
|
||||||
|
**Response (200):**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"status": "ok",
|
||||||
|
"version": "0.1.0"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Error Responses
|
||||||
|
|
||||||
|
All errors follow this format:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"error": "invalid domain",
|
||||||
|
"code": "INVALID_DOMAIN"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| HTTP Status | Code | Description |
|
||||||
|
|---|---|---|
|
||||||
|
| 400 | `INVALID_DOMAIN` | Malformed or missing domain |
|
||||||
|
| 400 | `INVALID_TYPE` | Unsupported record type |
|
||||||
|
| 401 | `UNAUTHORIZED` | Missing or invalid API key |
|
||||||
|
| 500 | `DNS_ERROR` | Upstream DNS query failed |
|
||||||
|
| 500 | `INTERNAL` | Unexpected server error |
|
||||||
78
docs/architecture.md
Normal file
78
docs/architecture.md
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
# VectorDNS Architecture
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
VectorDNS uses a hybrid architecture: a Next.js frontend on Vercel and a Go DNS microservice on a VPS.
|
||||||
|
|
||||||
|
```
|
||||||
|
┌──────────────────────┐ ┌──────────────────────┐
|
||||||
|
│ Vercel (Frontend) │ │ VPS (DNS API) │
|
||||||
|
│ │ │ │
|
||||||
|
│ Next.js 16 │ HTTP │ Go microservice │
|
||||||
|
│ React 19 │◄──────►│ miekg/dns │
|
||||||
|
│ Supabase SDK │ │ │
|
||||||
|
│ Tailwind + shadcn │ │ - DNS resolution │
|
||||||
|
│ │ │ - DNSSEC validation │
|
||||||
|
│ Handles: │ │ - Propagation checks │
|
||||||
|
│ - UI/SSR │ │ - Monitoring cron │
|
||||||
|
│ - Auth (Supabase) │ │ - Change detection │
|
||||||
|
│ - WHOIS lookups │ │ │
|
||||||
|
│ - Static pages │ └───────────┬───────────┘
|
||||||
|
│ │ │
|
||||||
|
└──────────┬───────────┘ │ UDP/TCP
|
||||||
|
│ ▼
|
||||||
|
│ ┌───────────────────────┐
|
||||||
|
│ │ DNS Resolvers / │
|
||||||
|
▼ │ Authoritative NS │
|
||||||
|
┌──────────────────────┐ └───────────────────────┘
|
||||||
|
│ Supabase │
|
||||||
|
│ │
|
||||||
|
│ - Postgres DB │
|
||||||
|
│ - Auth │
|
||||||
|
│ - Row Level Security│
|
||||||
|
└──────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
## Why Hybrid
|
||||||
|
|
||||||
|
| Concern | Solution |
|
||||||
|
|---|---|
|
||||||
|
| Frontend hosting, SSR, auth | Vercel (serverless, zero-ops) |
|
||||||
|
| DNS resolution, monitoring | Go on VPS (persistent process, no cold starts) |
|
||||||
|
| Database, auth state | Supabase (managed Postgres) |
|
||||||
|
|
||||||
|
## What Each Service Handles
|
||||||
|
|
||||||
|
### Next.js (Vercel)
|
||||||
|
|
||||||
|
- All UI rendering (SSR + client)
|
||||||
|
- Authentication via Supabase
|
||||||
|
- WHOIS lookups (whoiser library)
|
||||||
|
- Domain availability checks (IANA RDAP)
|
||||||
|
- Dashboard, notifications, settings pages
|
||||||
|
- Proxies DNS queries to the Go service
|
||||||
|
|
||||||
|
### Go Microservice (VPS)
|
||||||
|
|
||||||
|
- DNS record lookups via `miekg/dns` (UDP/TCP, not DoH)
|
||||||
|
- Query specific or authoritative nameservers directly
|
||||||
|
- DNSSEC validation
|
||||||
|
- DNS propagation checking across multiple resolvers
|
||||||
|
- Scheduled monitoring (native cron, no serverless time limits)
|
||||||
|
- Change detection (diff DNS snapshots, notify on changes)
|
||||||
|
|
||||||
|
## Communication
|
||||||
|
|
||||||
|
The Next.js API routes call the Go service over HTTPS. The Go service URL is configured via environment variable (`GO_DNS_API_URL`). Requests are authenticated with a shared API key (`GO_DNS_API_KEY`).
|
||||||
|
|
||||||
|
```
|
||||||
|
Next.js API route → HTTPS → Go DNS API → UDP/TCP → DNS resolvers
|
||||||
|
```
|
||||||
|
|
||||||
|
## Why Go Over DoH (Tangerine)
|
||||||
|
|
||||||
|
- Direct UDP/TCP DNS queries — faster, no middleman
|
||||||
|
- Can query authoritative nameservers directly
|
||||||
|
- Supports DNSSEC validation, AXFR, propagation checks
|
||||||
|
- No cold starts, consistent latency
|
||||||
|
- No Vercel function timeout limits for monitoring jobs
|
||||||
Reference in New Issue
Block a user