RepoPilotOpen in app →

TechnitiumSoftware/DnsServer

Technitium DNS Server

Mixed

Single-maintainer risk — review before adopting

worst of 4 axes
Use as dependencyConcerns

copyleft license (GPL-3.0) — review compatibility; top contributor handles 96% of recent commits…

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit today
  • 5 active contributors
  • GPL-3.0 licensed
Show 4 more →
  • Single-maintainer risk — top contributor 96% of recent commits
  • GPL-3.0 is copyleft — check downstream compatibility
  • No CI workflows detected
  • No test directory detected
What would change the summary?
  • Use as dependency ConcernsMixed if: relicense under MIT/Apache-2.0 (rare for established libs)

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Forkable" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Forkable
[![RepoPilot: Forkable](https://repopilot.app/api/badge/technitiumsoftware/dnsserver?axis=fork)](https://repopilot.app/r/technitiumsoftware/dnsserver)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/technitiumsoftware/dnsserver on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: TechnitiumSoftware/DnsServer

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/TechnitiumSoftware/DnsServer shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

WAIT — Single-maintainer risk — review before adopting

  • Last commit today
  • 5 active contributors
  • GPL-3.0 licensed
  • ⚠ Single-maintainer risk — top contributor 96% of recent commits
  • ⚠ GPL-3.0 is copyleft — check downstream compatibility
  • ⚠ No CI workflows detected
  • ⚠ No test directory detected

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live TechnitiumSoftware/DnsServer repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/TechnitiumSoftware/DnsServer.

What it runs against: a local clone of TechnitiumSoftware/DnsServer — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in TechnitiumSoftware/DnsServer | Confirms the artifact applies here, not a fork | | 2 | License is still GPL-3.0 | Catches relicense before you depend on it | | 3 | Default branch master exists | Catches branch renames | | 4 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>TechnitiumSoftware/DnsServer</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of TechnitiumSoftware/DnsServer. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/TechnitiumSoftware/DnsServer.git
#   cd DnsServer
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of TechnitiumSoftware/DnsServer and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "TechnitiumSoftware/DnsServer(\\.git)?\\b" \\
  && ok "origin remote is TechnitiumSoftware/DnsServer" \\
  || miss "origin remote is not TechnitiumSoftware/DnsServer (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(GPL-3\\.0)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"GPL-3\\.0\"" package.json 2>/dev/null) \\
  && ok "license is GPL-3.0" \\
  || miss "license drift — was GPL-3.0 at generation time"

# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
  && ok "default branch master exists" \\
  || miss "default branch master no longer exists"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/TechnitiumSoftware/DnsServer"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Technitium DNS Server is a self-hosted, open-source authoritative and recursive DNS server written in C# that provides privacy, security, and ad-blocking at the DNS level for entire networks. It supports encrypted DNS protocols (DNS-over-TLS, DNS-over-HTTPS, DNS-over-QUIC) and includes a web-based console for management, with a modular plugin system (Apps/) for extending functionality like advanced blocking, failover, and DNS64. Monorepo structure: DnsServer core engine (main application handling protocol parsing and caching), Apps/ directory contains ~10+ plugin modules (AdvancedBlockingApp, FailoverApp, DnsBlockListApp, Dns64App, etc.) each with their own .csproj, config files (dnsApp.config), and wwwroot assets. Web UI components in JavaScript/HTML (735KB JS, 607KB HTML) separate from backend.

👥Who it's for

Home network administrators and small-to-medium organization IT staff who want to self-host DNS infrastructure for privacy, reduce ISP DNS surveillance, implement network-wide ad/malware blocking, and maintain full control over DNS resolution without relying on third-party DNS providers.

🌱Maturity & risk

This is an actively maintained, production-ready project with a well-organized codebase (3.6MB of C#, modular app architecture, multiple DNS protocol implementations). The presence of multiple complete apps (AdvancedBlockingApp, FailoverApp, Dns64App, etc.), comprehensive feature set, and web UI indicates maturity. However, specific maturity signals (commit recency, test suite size, CI/CD pipeline) cannot be assessed from the provided file list alone.

Primary risks include single-maintainer concerns (Technitium is a personal project by a solo developer based on the README), potential for breaking DNS protocol changes in .NET ecosystem, and dependency on C# runtime. The modular app system is well-designed for isolation, but production deployments handling all network DNS traffic should have fallback strategies. No visible test suite or CI configuration in the provided file list is a concern.

Active areas of work

The file list shows an active plugin ecosystem with recent app additions (AutoPtrApp, Dns64App, DnsRebindingProtectionApp, DropRequestsApp, FailoverApp visible). Dockerfile support suggests containerization efforts. The presence of both Inno Setup (Windows installer) and shell scripts suggests cross-platform deployment tooling being actively maintained.

🚀Get running

Clone the repository and build using .NET tooling (C# project files present): git clone https://github.com/TechnitiumSoftware/DnsServer.git && cd DnsServer && dotnet build. The Dockerfile suggests Docker support: docker build -t technitium-dns .. Consult APIDOCS.md for API integration details.

Daily commands: For development: dotnet build followed by dotnet run in the DnsServer directory. For Docker: docker build -t technitium-dns . && docker run -p 53:53/udp -p 53:53/tcp -p 5380:5380 technitium-dns. Web console runs on port 5380 by default (inferred from standard Technitium deployments).

🗺️Map of the codebase

  • Apps/AdvancedBlockingApp/App.cs: Primary blocking logic template; shows how to extend DnsApp base class for DNS request filtering
  • Apps/FailoverApp/App.cs: Demonstrates stateful app logic (Address.cs, CNAME.cs, EmailAlert.cs) for upstream failover and health checking
  • Apps/DnsBlockListApp/App.cs: Shows integration with domain-blocklist.txt and ip-blocklist.txt for large-scale blocking implementations
  • Apps/AdvancedForwardingApp/adguard-upstreams.txt: Configuration file for upstream DNS provider management; critical for encrypted DNS setup (DoT/DoH/DoQ)
  • APIDOCS.md: API documentation for programmatic DNS control and integration with external systems
  • .github/: GitHub Actions CI/CD configuration (if present) indicates test and release automation

🛠️How to make changes

To add DNS functionality: examine Apps/AdvancedBlockingApp/App.cs or Apps/DnsBlockListApp/App.cs as templates for new DnsApp implementations. Core DNS protocol logic likely in parent DnsServer/ directory (not shown in file list). To modify UI: edit HTML/JavaScript files under Apps/*/wwwroot/. To add blocking rules: update domain-blocklist.txt or ip-blocklist.txt in DnsBlockListApp/.

🪤Traps & gotchas

The dnsApp.config XML format is critical—each app requires a properly formatted config file in its directory or it won't load. Port 53 (DNS) and 5380 (web console) must be available; 53 requires root/admin privileges on Linux/macOS/Windows. The modular app system depends on DnsServer core being compiled first; building individual apps in isolation may fail. Upstream forwarders in AdvancedForwardingApp reference external services (AdGuard, Cloudflare, etc.)—network outages upstream break recursive queries. HTTPS/TLS certificate configuration is likely required for DoH/DoT but not visible in this file list.

💡Concepts to learn

  • DNS-over-TLS (DoT) — Technitium's core feature for privacy; encrypts DNS queries end-to-end using TLS on port 853, preventing ISP snooping—essential for understanding why users choose Technitium over plaintext DNS
  • DNS-over-HTTPS (DoH) — Alternate encrypted DNS protocol Technitium supports; queries wrapped in HTTPS, blending with web traffic to prevent censorship and surveillance
  • DNS-over-QUIC (DoQ) — Latest encrypted DNS standard (RFC 9250) supported by Technitium for lower latency and faster connection setup compared to DoT/DoH
  • Recursive DNS resolver — Technitium acts as recursive resolver (queries upstream DNS for unknown domains and caches results); critical to understanding performance optimization and fallback behavior in AdvancedForwardingApp
  • DNS rebinding attack — DnsRebindingProtectionApp mitigates this vulnerability where attacker DNS returns different IPs to trigger CSRF in browsers; core security feature for home networks
  • Authoritative DNS server — Technitium also acts as authoritative server (responds authoritatively for hosted zones), enabling self-hosting of domains; DefaultRecordsApp and AutoPtrApp leverage this capability
  • Blocklist-based filtering — DnsBlockListApp's domain-blocklist.txt and ip-blocklist.txt use regex/wildcards for ad/malware blocking; understanding list format and matching rules is critical for custom filtering setups
  • pi-hole/pi-hole — Widely-used DNS-level ad blocker for networks; similar blocking philosophy but Technitium adds encrypted DNS upstream support and modular apps for extensibility
  • AdguardTeam/AdGuardHome — Go-based DNS server with ad-blocking and parental controls; direct competitor with similar encrypted DNS (DoT/DoH) and web UI; different language choice and architecture
  • mitmproxy/mitmproxy — Network proxy ecosystem; Technitium's DNS rebinding protection (DnsRebindingProtectionApp) and advanced forwarding relate to mitmproxy's interception patterns
  • coredns/coredns — Go-based DNS server used in Kubernetes; shows alternative DNS engine design with plugin architecture similar to Technitium's Apps/
  • certbot/certbot — ACME client for HTTPS certificate automation; relevant to securing Technitium's DoH and DoT endpoints with valid TLS certificates

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add comprehensive unit tests for Apps framework and core DNS operations

The Apps directory shows 13+ DNS apps (AdvancedBlockingApp, FailoverApp, GeoContinentApp, etc.) but there's no visible test directory structure. Given the complexity of DNS request processing, health monitoring (HealthMonitor.cs, HealthCheck.cs in FailoverApp), and plugin isolation, adding unit tests would catch regressions in critical functionality like failover logic, geo-routing, and request filtering. This is especially important since DNS services have high availability requirements.

  • [ ] Create Tests/DnsServerTests directory with test projects
  • [ ] Add unit tests for Apps/FailoverApp/HealthMonitor.cs and HealthCheck.cs (health monitoring is critical for failover reliability)
  • [ ] Add unit tests for Apps/AdvancedBlockingApp/App.cs (blocking logic correctness)
  • [ ] Add integration tests for Apps/GeoContinentApp/MaxMind.cs (geo-location routing)
  • [ ] Add tests for Apps/DnsBlockListApp domain and IP blocklist parsing
  • [ ] Set up xUnit or NUnit test runner configuration

Document the DNS App plugin architecture in APIDOCS.md with code examples

APIDOCS.md exists but likely lacks detailed documentation for creating custom DNS apps. With 13+ existing apps showing different patterns (blocking, forwarding, failover, geo-routing), new contributors need clear guidance. The Apps/ directory structure suggests there's a standardized App.cs interface and dnsApp.config pattern, but this isn't documented. Adding examples like 'Creating a simple blocklist app' or 'Implementing health checks' would reduce barriers to contribution.

  • [ ] Review the base App.cs interface pattern across existing apps
  • [ ] Add 'DNS App Development Guide' section to APIDOCS.md
  • [ ] Document the dnsApp.config schema with examples from FailoverApp and AdvancedForwardingApp
  • [ ] Provide a minimal 'Hello World' app template with step-by-step creation guide
  • [ ] Document the lifecycle hooks available (initialization, request processing, health checks)
  • [ ] Add examples for the two most common patterns: blocking apps and forwarding apps

Add GitHub Actions CI workflow for building and testing all DNS Apps

With 13 separate app projects (.csproj files across Apps/), there's no visible CI automation to catch breaking changes when the core DNS server API evolves. Currently, a contributor could break multiple app plugins without automated feedback. A multi-target build workflow would ensure all apps compile and tests pass across different .NET versions/platforms, especially important for a self-hosted service where users run various app combinations.

  • [ ] Create .github/workflows/build-and-test.yml
  • [ ] Add matrix build for .NET Core versions (e.g., 6.0, 8.0+)
  • [ ] Add step to build all .csproj files in Apps/ directory
  • [ ] Add step to run tests from Tests/ directory (once created by PR#1)
  • [ ] Add code analysis step (StyleCop or similar for C#)
  • [ ] Configure workflow to trigger on PR and push to main branches
  • [ ] Add badge to README.md showing build status

🌿Good first issues

  • Add unit tests for Apps/AdvancedBlockingApp/App.cs and Apps/DnsBlockListApp/App.cs to validate blocking rule matching logic and domain parsing edge cases (wildcards, Unicode domains)
  • Create comprehensive README.md files for each app in Apps/*/README.md explaining configuration options, use cases, and dnsApp.config schema (currently sparse documentation visible in list)
  • Implement a web UI form in Apps/BlockPageApp/wwwroot/index.html to allow admins to dynamically manage blocked domains without editing config files directly, with AJAX calls to REST endpoints

Top contributors

Click to expand

📝Recent commits

Click to expand
  • aa9044d — updated change log for v15.2 release. (ShreyasZare)
  • d0125b3 — inno: updated version to 15.2 (ShreyasZare)
  • 8196206 — assembly version updated to v15.2 for release. (ShreyasZare)
  • cf1ea4c — updated apidocs. (ShreyasZare)
  • 0c27fe4 — webapp: updated html to support new WebServiceReverseProxyAddresses option. Other minor changes done. (ShreyasZare)
  • 1613d98 — main.js: implemented support for new webServiceReverseProxyAddresses option. Code refactoring changes done. (ShreyasZare)
  • 41b1b21 — WebServiceSettingsApi: Added support for "webServiceReverseProxyAddresses" option in settings. Renamed "reverseProxyNetw (ShreyasZare)
  • 375d4e9 — WebServiceAuthApi: Fixed issue in SetGroupDetails() that caused unable to set empty description. Code refactoring change (ShreyasZare)
  • 2ffa839 — Extensions: Updated GetRemoteEndPoint() to remove support for real ip header. (ShreyasZare)
  • 0ffde4c — code refactoring changes done. (ShreyasZare)

🔒Security observations

  • High · Missing HTTPS in Default Docker Configuration — docker-compose.yml, Dockerfile. The docker-compose.yml exposes the DNS web console on port 5380 (HTTP) by default without HTTPS enabled. The HTTPS port (53443) is commented out, leaving the admin interface vulnerable to man-in-the-middle attacks and credential interception. Fix: Enable HTTPS by default with a valid certificate. Uncomment and configure port 53443 for HTTPS access. Consider disabling HTTP access or redirecting to HTTPS. Generate or mount SSL certificates properly.
  • High · Unrestricted Port Exposure in Docker — docker-compose.yml. Port 5380 (web console) is exposed to all interfaces (0.0.0.0) without authentication requirement visible in compose file. This allows unauthenticated access to the DNS server administration panel from any network. Fix: Restrict port bindings to localhost or specific trusted networks using '127.0.0.1:5380:5380' or use a reverse proxy with authentication. Implement strong authentication on the web console.
  • Medium · Incomplete Security Policy — SECURITY.md. The SECURITY.md file states only the master branch is supported for security updates, which may leave production deployments vulnerable if users are running older releases. No disclosure timeline or patch availability information is provided. Fix: Establish a clear security update policy with defined timelines (e.g., 90 days for critical vulnerabilities). Provide security advisories and release notes detailing security fixes. Consider supporting LTS releases.
  • Medium · Missing Container Security Hardening — Dockerfile. The Dockerfile runs the application without specifying a non-root user, and uses the default aspnet:10.0 base image which may contain unnecessary packages. No security scanning or minimal base image options are evident. Fix: Create a non-root user and run the application with minimal privileges. Use multi-stage builds to reduce attack surface. Consider using distroless or alpine-based images. Implement security scanning in the build pipeline.
  • Medium · Insecure Default Environment Variables — docker-compose.yml. The docker-compose.yml shows environment variable DNS_SERVER_DOMAIN exposed without encryption or security considerations. Sensitive configuration could be logged or exposed in debugging. Fix: Use Docker secrets for sensitive configuration instead of environment variables. Document which configuration values are sensitive and should be passed securely (e.g., through .env files with appropriate permissions or secrets management).
  • Medium · Multiple DNS Protocols Commented Out Without Guidance — docker-compose.yml. Modern DNS protocols (DoQ, DoT, DoH, DoH3) are commented out in the default configuration. Users may unknowingly use unencrypted DNS over plain TCP/UDP, reducing privacy and security. Fix: Provide clear documentation and examples for enabling encrypted DNS protocols. Consider defaulting to DoT or DoH with proper certificate configuration. Include setup guides for DNSSEC validation.
  • Low · Missing Container Resource Limits — docker-compose.yml. The docker-compose.yml does not specify resource limits (CPU, memory) for the DNS server, making it vulnerable to DoS attacks that could exhaust host resources. Fix: Add resource limits using 'deploy.resources.limits' for CPU and memory. Implement rate limiting at the application level for DNS queries.
  • Low · No Network Segmentation in Docker Compose — docker-compose.yml. The service lacks explicit network configuration, using the default bridge network which may allow unintended communication with other containers. Fix: Define explicit networks and isolate the DNS server network from other services. Use network policies to restrict traffic flow.
  • Low · Missing Package Update Information — Package dependencies (not provided). The dependency file content is empty, making it impossible to assess vulnerable dependencies. No lock file or version pinning strategy is visible. Fix: Provide dependency manifest (.csproj, packages.json, requirements.txt). Implement automated dependency scanning tools (Dependabot, Snyk). Pin exact versions for reproducible builds and security audits.
  • Low · — undefined. undefined Fix: undefined

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Mixed signals · TechnitiumSoftware/DnsServer — RepoPilot