Skip to content

nx9-dns-server is a high-performance, fully RFC-compliant authoritative DNS server, purpose-built to serve the any domain and its subdomains. This server is implemented in Rust, leveraging modern async networking and a robust SQLite backend for DNS record management.

License

Notifications You must be signed in to change notification settings

thakares/nx9-dns-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

28 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

nx9-dns-server

nx9-dns-server is a high-performance, RFC-compliant authoritative DNS server implemented in Rust. It is designed for any domain (e.g., anydomain.tld), supporting a wide range of DNS record types, DNSSEC, and robust operational features. The server is optimized for reliability, security, and ease of deployment in production environments.


Table of Contents


Features

  • Authoritative DNS: Serves authoritative responses for all queries to your domain (e.g., anydomain.tld).
  • Multi-Record Support: Handles A, AAAA, MX, NS, SOA, PTR, TXT, and CNAME records.
  • DNSSEC Ready: Supports DNSSEC key management and secure record signing.
  • High Performance: Asynchronous networking (UDP/TCP) via Tokio for handling thousands of concurrent queries.
  • RFC Compliance: Strict adherence to DNS protocol standards for interoperability.
  • Extensible Storage: Uses SQLite for DNS record storage, allowing easy updates and migrations.
  • Easy Deployment: Includes deployment and update scripts for smooth operational workflows.
  • Comprehensive Logging: Integrates with env_logger for detailed runtime diagnostics.
  • Web Interface: (Coming soon) Administrative web UI for DNS record management.
  • API Service: (Coming soon) RESTful API service for programmatic DNS record management.
  • User Management: (Coming soon) Multi-user access control with role-based permissions.

Architecture

  • Language: Rust (2021 edition)
  • Async Runtime: Tokio
  • Database: SQLite via rusqlite
  • Logging: log and env_logger
  • Error Handling: thiserror
  • DNSSEC: Built-in support for key loading and RRSIG/DS/DNSKEY records
  • Web Framework: (Coming soon) Rocket or Axum for UI and API endpoints
  • Authentication: (Coming soon) JWT-based authentication and role-based authorization
  • Containerization: Docker support with Alpine Linux for minimal footprint
  • Cross-Compilation: Support for building from Debian to Alpine Linux (musl) target

DNS Record Management

DNS records are managed in an SQLite database (dns.db). The schema supports multiple records per domain and type, and can be easily updated using SQL scripts.

Example schema (dns_records.sql):

CREATE TABLE IF NOT EXISTS dns_records (
  domain TEXT NOT NULL,
  record_type TEXT NOT NULL,
  value TEXT NOT NULL,
  ttl INTEGER DEFAULT 3600,
  PRIMARY KEY (domain, record_type, value)
) WITHOUT ROWID;

Sample records:

INSERT OR REPLACE INTO dns_records VALUES
('anydomain.tld', 'A', '203.0.113.10', 3600),
('anydomain.tld', 'MX', '10 mail.anydomain.tld', 3600),
('anydomain.tld', 'NS', 'ns1.anydomain.tld', 3600),
('anydomain.tld', 'NS', 'ns2.anydomain.tld', 3600),
('anydomain.tld', 'SOA', 'ns1.anydomain.tld hostmaster.anydomain.tld 1 10800 3600 604800 86400', 3600),
('anydomain.tld', 'TXT', '"v=spf1 a mx ~all"', 3600),
('www.anydomain.tld', 'A', '203.0.113.10', 3600);

Web UI

🚧 Under Development - Seeking Contributors! 🚧

We're actively looking for community contributions to our Web UI implementation. If you have experience with Rust web frameworks (Rocket/Axum) and modern frontend technologies (React/Vue/Svelte), please consider contributing!

The planned Web UI will provide:

  • Dashboard: Visual overview of DNS zone statistics and recent queries
  • Record Management: Intuitive interface for creating, viewing, updating, and deleting DNS records
  • DNSSEC Management: UI for key generation, rotation, and signature verification
  • Audit Logging: Visual timeline of all record changes with user attribution
  • Responsive Design: Mobile-friendly interface for management on any device

Tech Stack (Proposed):

  • Backend: Rust with Rocket or Axum
  • Frontend: TypeScript with React or Svelte
  • Authentication: JWT-based with session management

Contribution Areas:

  • UI/UX design mockups
  • Frontend component development
  • API integration
  • Automated testing
  • Documentation

If interested in contributing, please open an issue discussing your implementation approach before submitting PRs.


API Service

🚧 Under Development - Seeking Contributors! 🚧

We're building a RESTful API service for programmatic DNS record management. Contributors with experience in API design and Rust web services are welcome!

The DNS record management API will provide:

  • Full CRUD Operations: Create, read, update, and delete DNS records via REST endpoints
  • Batch Operations: Support for bulk record changes in a single request
  • Validation: Strict validation of record syntax and domain integrity
  • Rate Limiting: Protection against API abuse
  • Authentication: Secure token-based authentication with scoped permissions
  • Webhooks: (Planned) Event notifications for record changes

Planned Endpoints:

GET    /api/v1/zones                  # List all zones
POST   /api/v1/zones                  # Create new zone
GET    /api/v1/zones/{zone}           # Get zone details
PUT    /api/v1/zones/{zone}           # Update zone properties
DELETE /api/v1/zones/{zone}           # Remove zone

GET    /api/v1/zones/{zone}/records               # List all records in zone
POST   /api/v1/zones/{zone}/records               # Create new record
GET    /api/v1/zones/{zone}/records/{id}          # Get record details
PUT    /api/v1/zones/{zone}/records/{id}          # Update record
DELETE /api/v1/zones/{zone}/records/{id}          # Remove record

POST   /api/v1/zones/{zone}/records/batch         # Batch create/update/delete

If you're interested in contributing to the API service, please refer to our API design document in the project wiki.


User Management

🚧 Under Development - Community Input Requested! 🚧

We're designing a user management system and need input from the community on requirements and features.

Planned user management features:

  • Multi-User Support: Multiple administrator and operator accounts
  • Role-Based Access Control: Granular permissions for different user roles
  • Authentication Options: Local accounts and potential OAuth/LDAP integration
  • Audit Trail: Comprehensive logging of all user actions
  • Password Policies: Configurable password requirements and rotation policies
  • Two-Factor Authentication: Additional security layer for administrative access
  • API Tokens: Management of scoped API tokens for programmatic access

User Roles (Proposed):

  • Administrator: Full system access
  • Operator: Can manage DNS records but not system settings
  • Viewer: Read-only access to records and statistics
  • API Client: Programmatic access via API tokens

We welcome community input on:

  • Authentication mechanisms
  • Additional role definitions and permission scopes
  • UI/UX design for user management interfaces
  • Enterprise integration requirements

Please open an issue with the tag user-management to share your feedback and requirements.


DNSSEC Support

  • Key Management: DNSSEC keys are loaded from environment-configured paths.
  • Record Signing: Supports RRSIG, DS, and DNSKEY records for secure, signed DNS responses.
  • Preprocessing: Key files can be preprocessed using provided scripts before deployment.

How to Create DNSSEC_KEY_FILE

To enable DNSSEC for nx9-dns-server, you need to generate a DNSSEC key pair and provide the public key file to the server via the DNSSEC_KEY_FILE environment variable. Here's how you can do it using BIND's dnssec-keygen tool:

1. Install dnssec-keygen

On most Linux systems, you can install it via the package manager:

sudo apt-get install bind9-dnsutils   # Debian/Ubuntu
# or
sudo yum install bind-utils           # CentOS/RHEL

2. Generate DNSSEC Key Pair

Run the following command to generate a 2048-bit RSA key for your domain (replace anydomain.tld with your actual domain):

dnssec-keygen -a RSASHA256 -b 2048 -n ZONE anydomain.tld
  • This will produce two files in your current directory:
    • K.+008+.key (public key)
    • K.+008+.private (private key)

3. Set the DNSSEC_KEY_FILE Environment Variable

Copy the public key file (.key) to your server's key directory (e.g., /var/nx9-dns-server/):

cp Kanydomain.tld.+008+24550.key /var/nx9-dns-server/

Then, set the environment variable in your deployment environment or systemd service:

export DNSSEC_KEY_FILE="/var/nx9-dns-server/Kanydomain.tld.+008+24550.key"

Or in your systemd unit file:

Environment="DNSSEC_KEY_FILE=/var/nx9-dns-server/Kanydomain.tld.+008+24550.key"

4. (Optional) Preprocess the Key

If your deployment uses a preprocessing script (as referenced in your deploy.sh), run:

sudo chmod +x /var/nx9-dns-server/preprocess-key.sh
sudo -u dnsuser /var/nx9-dns-server/preprocess-key.sh

This may normalize the key format or permissions as required by your server.

5. Restart the DNS Server

After setting the key file, restart your DNS server to load the new key:

sudo systemctl restart dns-server.service

6. Verify DNSSEC is Working

Use the provided dnscheck.sh script or dig to verify DNSSEC records:

bash dnscheck.sh
# or manually:
dig @localhost anydomain.tld DNSKEY +dnssec

Note:

  • Keep your .private key file secure and never expose it publicly.
  • Only the .key (public) file should be referenced by the server.
  • The server will load and use the public key for signing DNS responses.

Deployment

Traditional Deployment

Deployment is automated and robust, using the provided deploy.sh script. This script handles permissions, key preprocessing, SOA updates, binary replacement, and service management.

Typical deployment steps:

#!/bin/bash

set -e

SRC_BIN="/home/youruser/apps/your-ddns/dns_server"
DEST_DIR="/var/nx9-dns-server"
DEST_BIN="$DEST_DIR/dns_server"
PREPROCESS_SCRIPT="$DEST_DIR/preprocess-key.sh"
SOA_UPDATE_SCRIPT="$DEST_DIR/soa-update.sh"

echo "πŸ” Fixing permissions and running preprocess..."
sudo chmod +x "$PREPROCESS_SCRIPT"
sudo -u dnsuser "$PREPROCESS_SCRIPT"

echo "πŸ›  Updating SOA record..."
sudo chown dnsuser:dnsuser "$SOA_UPDATE_SCRIPT"
sudo chmod +x "$SOA_UPDATE_SCRIPT"
sudo -u dnsuser "$SOA_UPDATE_SCRIPT"

echo "πŸ“„ Verifying processed.key content..."
sudo cat "$DEST_DIR/processed.key"

echo "πŸ›‘ Stopping DNS server..."
sudo systemctl stop dns-server.service

echo "πŸ“¦ Deploying new dns_server binary..."
sudo cp "$SRC_BIN" "$DEST_BIN"
sudo chown dnsuser:dnsuser "$DEST_DIR"

echo "πŸ” Reloading systemd and restarting service..."
sudo systemctl daemon-reload
sudo systemctl restart dns-server.service

echo "πŸ“ˆ Checking service status..."
sudo systemctl status dns-server.service

See deploy.sh for the full deployment script.

Docker Deployment

We provide a Docker-based deployment option using Alpine Linux for a minimal and secure container.

Dockerfile

# Build stage
FROM rust:1.72-slim-bookworm AS builder

# Install necessary build dependencies
RUN apt-get update && apt-get install -y \
    musl-tools \
    build-essential \
    pkg-config \
    libssl-dev \
    && rm -rf /var/lib/apt/lists/*

# Add support for cross-compilation to Alpine
RUN rustup target add x86_64-unknown-linux-musl

# Create a new empty project
WORKDIR /app
COPY . .

# Build the project with musl target
RUN cargo build --target x86_64-unknown-linux-musl --release

# Runtime stage
FROM alpine:3.18

# Install runtime dependencies
RUN apk --no-cache add ca-certificates sqlite tzdata

# Create a non-root user for running the application
RUN addgroup -S dns && adduser -S dnsuser -G dns

# Create necessary directories
RUN mkdir -p /var/nx9-dns-server /var/log/nx9-dns-server /etc/nx9-dns-server
RUN chown -R dnsuser:dns /var/nx9-dns-server /var/log/nx9-dns-server /etc/nx9-dns-server

# Copy the compiled binary
COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/dns_server /usr/local/bin/
RUN chmod +x /usr/local/bin/dns_server

# Copy configuration files
COPY --from=builder /app/conf/dns_records.sql /etc/nx9-dns-server/
COPY --from=builder /app/conf/dns.db.sample /etc/nx9-dns-server/

# Expose DNS ports
EXPOSE 53/udp 53/tcp
# Expose Web UI port
EXPOSE 8080/tcp
# Expose API port
EXPOSE 8081/tcp

# Set working directory
WORKDIR /var/nx9-dns-server

# Switch to non-root user
USER dnsuser

# Command to run the application
CMD ["/usr/local/bin/dns_server"]

Building the Docker Image

# Clone the repository
git clone https://github.com/thakares/nx9-dns-server.git
cd nx9-dns-server

# Build the Docker image
docker build -t nx9-dns-server:latest .

Running the Container

# Run with basic configuration
docker run -d --name nx9-dns \
  -p 53:53/udp -p 53:53/tcp \
  -p 8080:8080 -p 8081:8081 \
  -v /path/to/dns.db:/var/nx9-dns-server/dns.db \
  -v /path/to/keys:/etc/nx9-dns-server/keys \
  -e DNS_BIND=0.0.0.0:53 \
  -e DNS_DB_PATH=/var/nx9-dns-server/dns.db \
  -e DNSSEC_KEY_FILE=/etc/nx9-dns-server/keys/Kanydomain.tld.key \
  -e WEB_UI_BIND=0.0.0.0:8080 \
  -e API_BIND=0.0.0.0:8081 \
  nx9-dns-server:latest

Using Docker Compose

For more complex deployments, a docker-compose.yml file is recommended:

version: '3.8'

services:
  dns:
    image: nx9-dns-server:latest
    container_name: nx9-dns
    ports:
      - "53:53/udp"
      - "53:53/tcp"
      - "8080:8080"
      - "8081:8081"
    volumes:
      - ./data/dns.db:/var/nx9-dns-server/dns.db
      - ./keys:/etc/nx9-dns-server/keys
      - ./logs:/var/log/nx9-dns-server
    environment:
      - DNS_BIND=0.0.0.0:53
      - DNS_DB_PATH=/var/nx9-dns-server/dns.db
      - DNSSEC_KEY_FILE=/etc/nx9-dns-server/keys/Kanydomain.tld.key
      - DNS_FORWARDERS=8.8.8.8:53,1.1.1.1:53
      - DNS_NS_RECORDS=ns1.anydomain.tld.,ns2.anydomain.tld.
      - WEB_UI_BIND=0.0.0.0:8080
      - API_BIND=0.0.0.0:8081
    restart: unless-stopped

To run with Docker Compose:

docker-compose up -d

Configuration

Configuration is environment-driven and highly flexible.

Key environment variables:

  • DNS_BIND: Bind address (default: 0.0.0.0:53)
  • DNS_DB_PATH: Path to the SQLite database (default: dns.db)
  • DNSSEC_KEY_FILE: Path to DNSSEC key file
  • DNS_FORWARDERS: Comma-separated list of upstream DNS resolvers
  • DNS_NS_RECORDS: Comma-separated list of NS records
  • DNS_CACHE_TTL: Cache TTL in seconds
  • WEB_UI_BIND: Bind address for web interface (default: 127.0.0.1:8080)
  • API_BIND: Bind address for API service (default: 127.0.0.1:8081)
  • AUTH_SECRET: Secret key for JWT token signing
  • ADMIN_PASSWORD: Initial admin password (only used if no users exist)

Example:

export DNS_BIND="0.0.0.0:53"
export DNS_DB_PATH="/var/nx9-dns-server/dns.db"
export DNSSEC_KEY_FILE="/var/nx9-dns-server/Kanydomain.tld.+008+24550.key"
export DNS_FORWARDERS="8.8.8.8:53,1.1.1.1:53"
export DNS_NS_RECORDS="ns1.anydomain.tld.,ns2.anydomain.tld."
export WEB_UI_BIND="0.0.0.0:8080"
export API_BIND="0.0.0.0:8081"
export AUTH_SECRET="your-secure-random-string-here"

Testing & Diagnostics

A suite of shell scripts is provided for diagnostics and record verification:

  • dnscheck.sh: Runs a series of dig queries for all major record types and DNSSEC.
  • dns_dump.sh: Dumps all record types for a given domain.
  • api_test.sh: (Coming soon) Tests the API endpoints with sample requests.
  • performance_test.sh: (Coming soon) Benchmarks server performance under load.

Example usage:

bash dnscheck.sh
bash dns_dump.sh anydomain.tld

Roadmap

Our planned features and improvements:

Short-term (1-3 months)

  • Core DNS server functionality
  • DNSSEC implementation
  • Web UI development (in progress)
  • RESTful API service (in progress)
  • User management system (planning)
  • Docker container support

Medium-term (3-6 months)

  • Clustered deployment support
  • Metrics and monitoring integration (Prometheus)
  • Zone transfer (AXFR/IXFR) support
  • Dynamic DNS update protocol (RFC 2136)
  • DNSSEC key rotation automation
  • Kubernetes Helm charts for enterprise deployment

Long-term (6+ months)

  • Secondary/slave DNS server support
  • Geo-based DNS responses
  • DNS over HTTPS (DoH) support
  • DNS over TLS (DoT) support
  • Record templating system

Contributing

Contributions, bug reports, and feature requests are welcome! Please open issues or pull requests via GitHub.

Priority Contribution Areas

We're actively seeking contributions in these areas:

  1. Web UI Development: Frontend components and integration with the backend
  2. API Service: RESTful API implementation for DNS record management
  3. User Management: Authentication, authorization, and user interface
  4. Documentation: Improving guides and examples
  5. Testing: Unit tests, integration tests, and automated CI pipelines

How to Contribute

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Commit your changes: git commit -m 'Add some amazing feature'
  4. Push to the branch: git push origin feature/amazing-feature
  5. Open a Pull Request

Please see CONTRIBUTING.md for detailed contribution guidelines.


License

This project is licensed under the GNU General Public License v3.0 (GPLv3).


Acknowledgements

  • Tokio for async runtime
  • rusqlite for SQLite integration
  • dig for DNS diagnostics
  • Community contributors and supporters

nx9-dns-server is developed and maintained by Sunil Purushottam Thakare sunil@thakares.com.
For more information, see the source code or contact the maintainer via GitHub.


Tip:
Replace anydomain.tld with your actual domain throughout the configuration and database files.

About

nx9-dns-server is a high-performance, fully RFC-compliant authoritative DNS server, purpose-built to serve the any domain and its subdomains. This server is implemented in Rust, leveraging modern async networking and a robust SQLite backend for DNS record management.

Topics

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

No packages published