# @push.rocks/smartdns/server DNS server module for `@push.rocks/smartdns` — a full-featured authoritative DNS server powered by a Rust backend with DNSSEC, DNS-over-HTTPS, and Let's Encrypt integration. ## Import ```typescript import { DnsServer } from '@push.rocks/smartdns/server'; ``` ## Architecture The server delegates network I/O, DNS packet parsing/encoding, and DNSSEC signing to a compiled **Rust binary** (`rustdns`). TypeScript retains the public API, handler registration, and ACME certificate orchestration. Communication happens via JSON-over-stdin/stdout IPC using `@push.rocks/smartrust`'s `RustBridge`. DNS queries that need handler resolution are forwarded from Rust to TypeScript with correlation IDs, then results are sent back for response assembly and DNSSEC signing. ### Rust Crate Structure | Crate | Purpose | |---|---| | `rustdns` | Main binary with IPC management loop | | `rustdns-protocol` | DNS wire format parsing/encoding, RDATA encode/decode | | `rustdns-server` | Async UDP + HTTPS servers (tokio, hyper, rustls) | | `rustdns-dnssec` | ECDSA/ED25519 key generation and RRset signing | ## Classes ### `DnsServer` The primary class. Manages handler registration, server lifecycle, and certificate retrieval. ```typescript const server = new DnsServer({ udpPort: 53, httpsPort: 443, httpsKey: '...pem...', httpsCert: '...pem...', dnssecZone: 'example.com', primaryNameserver: 'ns1.example.com', }); ``` #### Options | Option | Type | Default | Description | |---|---|---|---| | `udpPort` | `number` | — | UDP DNS port | | `httpsPort` | `number` | — | HTTPS DoH port | | `httpsKey` | `string` | — | TLS private key (PEM) | | `httpsCert` | `string` | — | TLS certificate (PEM) | | `dnssecZone` | `string` | — | Zone to enable DNSSEC for | | `primaryNameserver` | `string` | `ns1.{zone}` | SOA mname field | | `udpBindInterface` | `string` | `0.0.0.0` | IP to bind UDP | | `httpsBindInterface` | `string` | `0.0.0.0` | IP to bind HTTPS | | `manualUdpMode` | `boolean` | `false` | Don't auto-bind UDP | | `manualHttpsMode` | `boolean` | `false` | Don't auto-bind HTTPS | | `enableLocalhostHandling` | `boolean` | `true` | Handle RFC 6761 localhost | #### Key Methods | Method | Description | |---|---| | `start()` | Spawn Rust binary and start listening | | `stop()` | Gracefully shut down | | `registerHandler(pattern, types, fn)` | Add a DNS handler (glob patterns via minimatch) | | `unregisterHandler(pattern, types)` | Remove a handler | | `handleUdpMessage(msg, rinfo, cb)` | Process a UDP message manually | | `processRawDnsPacket(buf)` | Sync packet processing (TS fallback) | | `processRawDnsPacketAsync(buf)` | Async packet processing (Rust bridge, includes DNSSEC) | | `retrieveSslCertificate(domains, opts)` | ACME DNS-01 certificate retrieval | | `filterAuthorizedDomains(domains)` | Filter domains the server is authoritative for | ### `RustDnsBridge` Low-level IPC bridge to the `rustdns` binary. Used internally by `DnsServer` — typically not imported directly. Emits events: `dnsQuery`, `started`, `stopped`, `error`. ## Handler System Handlers use **glob patterns** (via `minimatch`) for domain matching. Multiple handlers can contribute records to a single response. ```typescript server.registerHandler('*.example.com', ['A'], (question) => ({ name: question.name, type: 'A', class: 'IN', ttl: 300, data: '10.0.0.1', })); ``` When no handler matches, the server returns an automatic **SOA record** for the zone. ## DNSSEC Enabled automatically with the `dnssecZone` option. Supports: - **ECDSAP256SHA256** (13) — default - **ED25519** (15) - **RSASHA256** (8) Key generation, DNSKEY/RRSIG/NSEC record creation is fully handled by the Rust backend. ## Dependencies - `@push.rocks/smartrust` — TypeScript-to-Rust IPC bridge - `dns-packet` — DNS wire format codec (used for TS fallback path) - `minimatch` — glob pattern matching for handlers - `acme-client` — Let's Encrypt ACME protocol