Skip to content

MBeijer/csharp-dns-server

 
 

Repository files navigation

csharp-dns-server

GitHub Actions Status

Fully functional DNS server written in C# targeting .NET 8. Ensure the .NET 8 SDK is installed before building or testing.

The project was conceived while working to reduce the cost of datacentre "stamps" while providing robust services within a datacentre, specifically to remove the need for an expensive load-balancer device by providing round-robin DNS services, and retrying connectivity instead.

Licence

This software is licenced under MIT terms that permits reuse within proprietary software provided all copies of the licensed software include a copy of the MIT License terms and the copyright notice. See licence.txt

Getting Started

// clone the repo
>> cd $repo-root
>> git clone https://github.com/stephbu/csharp-dns-server

// check you can build the project
>> cd $repo-root/csharp-dns-server
>> dotnet build

// check that the tests run
>> dotnet test

// use DIG query appconfig'd local server
>> dig -p 5335 @127.0.0.1 www.google.com A 

Note: The solution targets net8.0; all commands above assume the .NET 8 SDK is available on your PATH.

Gotchas

  • if you're running on Windows with Docker Tools installed, Docker uses the ICS SharedAccess service to provide DNS resolution for Docker containers - this listens on UDP:53, and will conflict with the DNS project. Either turn off the the service (net stop SharedAccess), or change the UDP port.

Continuous Integration

All pushes and pull requests against main run through .github/workflows/ci.yml, a GitHub Actions pipeline that restores, builds, and tests the full csharp-dns-server.sln on both Ubuntu and Windows runners using the .NET 8 SDK.

Features

As written, the server has the following features:

  • Pluggable Zone Resolver. Host one or more zones locally, and run your code to resolve names in that zone. Enables many complex scenarios such as:
  • round-robin load-balancing. Distribute load and provide failover with a datacentre without expensive hardware.
  • health-checks. While maintaining a list of machines in round-robin for a name, the code performs periodic healthchecks against the machines, if necessary removing machines that fail the health checks from rotation.
  • Delegates all other DNS lookup to host machines default DNS server(s)
  • Automatic set up of zones for docker instances running on a specific docker server, can be used to get .local or .internal zones, so you can route traffic by hostname via something like Traefik

The DNS server has a built-in Web Server providing operational insight into the current server behaviour.

  • healthcheck for server status
  • counters
  • zone information

Zone Providers

The server ships with several pluggable providers that publish authoritative data into SmartZoneResolver:

  • CSV/AP provider – watches a simple CSV file (MachineFunction, StaticIP) and publishes grouped A records for each function. See docs/providers/AP_provider.md for schema details.
  • IPProbe provider – continuously probes configured endpoints (ping/noop today) and only emits healthy addresses. Configuration and behavior live in docs/providers/IPProbe_provider.md.
  • BIND zone provider – watches a BIND-style forward zone file, parses $ORIGIN, $TTL, SOA/NS/A/AAAA/CNAME/MX/TXT records, and emits address records once the zone validates successfully. Any lexical or semantic validation error (missing SOA/NS, malformed TTLs, unsupported record types, duplicate CNAMEs, etc.) is surfaced with line numbers and the previous zone continues serving traffic.
    • See docs/providers/BIND_provider.md for configuration details, validation rules, and troubleshooting tips.

BIND Provider Configuration

Add the provider via appsettings.json (both Dns and dns-cli hosts read the same shape):

{
  "server": {
    "zone": {
      "name": ".example.com",
      "provider": "Dns.ZoneProvider.Bind.BindZoneProvider"
    }
  },
  "zoneprovider": {
    "FileName": "C:/zones/example.com.zone"
  }
}

The provider reads the file whenever it changes (a 10-second settlement window avoids partial writes), validates the directives/records, and only publishes A/AAAA data to SmartZoneResolver when the parse succeeds. All other record types are parsed/validated so that zone files failing to meet RFC expectations never poison the active zone.

Documentation

  • Product requirements describe the current roadmap, observability goals, and .NET maintenance plans.
  • Project priorities & plan outline the P0/P1/P2 focus areas plus execution notes (DI migration, OpenTelemetry instrumentation).
  • Task list captures the prioritized backlog that tracks to those priorities.
  • Protocol references list the RFCs and supporting standards that guide implementation.
  • AGENTS guide explains how automation/AI contributors should work within this repository.

Interesting Possible Uses

Time-based constraints such as parental controls to block a site, e.g. Facebook. Logging of site usage e.g. company notifications

Challenges

Testing

Two phases of testing was completed.

  1. Verification that the bit-packing classes correctly added and removed bits in correct Endian order, complicated by network bitpacking in reverse order to Windows big-endian packing.

  2. Protocol verification - that well known messages were correctly decoded and re-encoded using the bit-packing system.

Much time was spent using Netmon to capture real DNS challenges and verify that the C# DNS server responded appropriately.

DNS-Sec

No effort made to handle or respond to DNS-Sec challenges.

Contribution Guide

Pull Requests, Bug Reports, and Feature Requests are most welcome.

Contribution Workflow

Suggested workflow for PRs is

  1. Make a fork of csharp-dns-server/master in your own repository.
  2. Create a branch in your own repo to entirely encapsulate all your proposed changes
  3. Make your changes, add documentation if you need it, markdown text preferred.
  4. Squash your commits into a single change (Find out how to squash here)
  5. Submit a PR, and put in comments anything that you think I'll need to help merge and evaluate the changes

If you are using automated tooling or AI agents, please review AGENTS.md to ensure you follow the approved scope and workflow.

Licence Reminder

All contributions must be licenced under the same MIT terms, do include a header file to that effect.

About

Fully functional DNS server written in C#

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C# 97.6%
  • Markdown 2.1%
  • Dockerfile 0.3%