svenshi/oxidns

By svenshi

Updated about 9 hours ago

A high-performance, programmable DNS engine in Rust with flexible pipeline-based routing.

Image
Networking
0

6.4K

svenshi/oxidns repository overview

OxiDNS

Stars Forks Issues

GitHub · Documentation · Quick Start · Plugin Reference

A high-performance DNS policy orchestration engine for complex networks.

OxiDNS is a modern DNS engine built with Rust. It is inspired by mosdns, but it is not merely another rule-based DNS forwarder.

It focuses on the full lifecycle of DNS queries in real-world network environments: ingress, matching, caching, forwarding, fallback, rewriting, local answers, and system integrations, while gradually improving metrics, logging, and debugging capabilities.

The core idea of OxiDNS is not to expose more switches. It is to provide a clear, composable, and debuggable policy pipeline that lets you describe complex DNS behavior through declarative configuration.

server -> DnsContext -> matcher / executor / provider -> upstream

The project is under active development. It is designed for users who need fine-grained control over DNS behavior and are willing to understand its policy model.


Image

docker pull svenshi/oxidns:latest

Recommended tags:

svenshi/oxidns:latest
svenshi/oxidns:<version>

For production deployments, prefer a fixed version tag instead of latest.


Quick Start

Create a local configuration directory:

mkdir -p ./oxidns

Place your OxiDNS configuration file at:

./oxidns/config.yaml

Start OxiDNS:

docker run -d \
  --name oxidns \
  --restart unless-stopped \
  -p 53:53/udp \
  -p 53:53/tcp \
  -p 9199:9199/tcp \
  -v "$(pwd)/oxidns:/etc/oxidns" \
  svenshi/oxidns:latest

By default, the container expects the configuration file at:

/etc/oxidns/config.yaml

View logs:

docker logs -f oxidns

Stop and remove the container:

docker rm -f oxidns

Docker Compose

services:
  oxidns:
    image: svenshi/oxidns:latest
    container_name: oxidns
    restart: unless-stopped
    ports:
      - "53:53/udp"
      - "53:53/tcp"
      - "9199:9199/tcp"
    volumes:
      - ./oxidns:/etc/oxidns

Start the service:

docker compose up -d

View logs:

docker logs -f oxidns

Stop the service:

docker compose down

Why OxiDNS

In complex networks, DNS is often more than “resolve this domain”.

You may need to:

  • Select different upstreams based on domain, client, query type, response IP, or response code
  • Apply different policies to different devices, subnets, or scenarios
  • Race, fallback, fail over, or make decisions based on upstream results
  • Adjust TTL, handle ECS, rewrite responses, or return local answers
  • Sync DNS results into ipset, nftset, or MikroTik RouterOS
  • Record query behavior and understand system state through logs, query records, and basic metrics
  • Reload configuration, rules, and providers without interrupting the service

OxiDNS provides a unified orchestration model for these scenarios instead of a collection of isolated feature switches.


Design Principles

Composable

OxiDNS decomposes DNS processing into matcher, executor, provider, and sequence.

Each component has a focused responsibility, and complete policies are built by composing them into pipelines.

Debuggable

Once DNS policies become complex, the most important question is not just “does it run”, but “why did it behave this way”.

OxiDNS is gradually improving its debugging capabilities around query records, real-time logs, metrics collection, and configuration validation. The current focus is helping users understand which matchers were hit, which executors ran, which upstream was selected, and why a fallback path was taken.

Evolvable

OxiDNS is designed for long-running self-hosted network environments.

It supports full hot reload, provider-scoped hot reload, separately built WebUI hosting, and keeps room for future plugin and operations-oriented improvements.

Explicit

OxiDNS does not try to hide complexity from you.

It is better suited for users who want explicit control over DNS behavior, rather than users who only want a one-click DNS dashboard.


Core Capabilities

CategoryCapabilities
ProtocolsUDP, TCP, DoT, DoQ, DoH
Policy modelsequence, matcher, executor, provider
Executorsforward, cache, fallback, hosts, arbitrary, redirect, ecs_handler, ttl, download, upgrade, reload, reload_provider, script, http_request, query_summary, query_recorder, metrics_collector
Matchersqname, question, qtype, qclass, client_ip, resp_ip, rcode, rate_limiter, and more
Data setsdomain_set, ip_set, geoip, geosite, adguard_rule
System integrationsipset, nftset, ros_address_list, reverse_lookup
Debugging and operationsHealth checks, config validation, hot reload, query records, basic metrics, real-time logs
DeploymentMulti-platform builds, Debian packages, standalone WebUI hosting, service installation

Configuration

OxiDNS is configured through a declarative configuration file.

Recommended container layout:

oxidns/
├── config.yaml
├── rules/
├── geo/
└── scripts/

Mounted into the container as:

/etc/oxidns/
├── config.yaml
├── rules/
├── geo/
└── scripts/

If you only use a single configuration file, you can also mount it directly:

docker run -d \
  --name oxidns \
  --restart unless-stopped \
  -p 53:53/udp \
  -p 53:53/tcp \
  -p 9199:9199/tcp \
  -v "$(pwd)/config.yaml:/etc/oxidns/config.yaml:ro" \
  svenshi/oxidns:latest

For a complete configuration guide, see:


Ports

Common ports used by OxiDNS:

PortProtocolPurpose
53UDPDNS over UDP
53TCPDNS over TCP
9199TCPManagement API / WebUI, depending on configuration

Only expose the ports you actually use.

If you enable DoT, DoH, or DoQ in your configuration, expose the corresponding ports explicitly.


Host Networking

For DNS services, host networking is often useful on Linux, especially when OxiDNS needs to bind directly to host interfaces or act as the primary resolver for the machine or LAN.

docker run -d \
  --name oxidns \
  --restart unless-stopped \
  --network host \
  -v "$(pwd)/oxidns:/etc/oxidns" \
  svenshi/oxidns:latest

When using --network host, Docker port mappings such as -p 53:53/udp are not needed.


System Integrations

Some OxiDNS features interact with the host networking stack.

If your configuration uses integrations such as ipset, nftset, or other network-related operations, additional Linux capabilities may be required.

docker run -d \
  --name oxidns \
  --restart unless-stopped \
  --network host \
  --cap-add NET_ADMIN \
  --cap-add NET_RAW \
  -v "$(pwd)/oxidns:/etc/oxidns" \
  svenshi/oxidns:latest

Only grant additional capabilities when your configuration actually requires them.

For MikroTik RouterOS integrations, make sure the container can reach your RouterOS device and that your OxiDNS configuration contains the required RouterOS connection settings.


Good Fits

OxiDNS is a good fit for DNS environments that need to be long-running, debuggable, and extensible.

Typical use cases include:

  • Home gateways, side routers, OpenWrt, NAS, and homelab setups
  • Multi-upstream racing, fallback chains, and mixed protocol environments
  • Fine-grained DNS policy routing based on domains, clients, and response results
  • DNS-result-driven ipset / nftset / MikroTik address list synchronization
  • Ad filtering, domain routing, local overrides, dual-stack preferences, and ECS control
  • Self-hosted DNS infrastructure that needs explicit control and debugging
  • Lightweight deployments that serve a separately built WebUI on the same management port

Non-Goals

OxiDNS is not a one-click DNS dashboard for everyone.

If you primarily need:

  • Simple and ready-to-use home ad blocking
  • A full graphical DNS management experience
  • Authoritative DNS hosting
  • A Kubernetes service discovery plugin framework
  • A zero-configuration tool that does not require understanding its configuration model

Then AdGuard Home, Pi-hole, Technitium DNS Server, or CoreDNS may be a better fit.

OxiDNS is for users who want to describe DNS behavior explicitly through configuration and are willing to accept some complexity in exchange for control.


Upgrade

Pull the latest image:

docker pull svenshi/oxidns:latest

Recreate the container:

docker rm -f oxidns

docker run -d \
  --name oxidns \
  --restart unless-stopped \
  -p 53:53/udp \
  -p 53:53/tcp \
  -p 9199:9199/tcp \
  -v "$(pwd)/oxidns:/etc/oxidns" \
  svenshi/oxidns:latest

With Docker Compose:

docker compose pull
docker compose up -d

For production deployments, pin a specific version tag and upgrade intentionally.


Documentation Map


Project Status

OxiDNS is under active development.

The current version is suitable for advanced users, testing environments, and self-hosted network setups. For production use, make sure you understand the configuration, logs, and fallback behavior before deploying it.

Observability is still being improved. The current version focuses on basic logs, query records, health checks, and operations APIs. Future versions will continue to improve policy-path tracing, metrics dashboards, and troubleshooting capabilities.

Issues, real-world feedback, documentation improvements, and plugin contributions are welcome.



License

This project is licensed under the GNU General Public License v3.0 or later.

Tag summary

Content type

Image

Digest

sha256:286ca472c

Size

9.4 MB

Last updated

about 9 hours ago

docker pull svenshi/oxidns