Scott Hanselman

Exploring DNS with the .NET Core based Technitium DNS Server

April 19, 2019 Comment on this post [12] Posted in DotNetCore
Sponsored By

Earlier this week I talked about how Your Computer is not a Black Box and I spent some time in TCPView and at the command line exploring open ports on my computer. I was doing this in order to debug an issue with a local DNS server I was playing with, so I thought I'd take a moment and look at that server itself.

The Technitium DNS Server is a personal local DNS server (FOSS on GitHub) written in C# and it runs on Windows, macOS, Linux, Raspberry Pi, etc. I downloaded the Portable app.

For Windows folks who aren't used to .tar.gz files, remember to "eXtract Zie Files!" with "tar -xzvf DnsServerPortable.tar.gz -C ./TechnitiumDNS/" and it's also worth reminding you all that tar.exe, curl.exe, wget.exe and more are all included in Windows 10 and have been since 2017. If that's too hard, use 7zip.

Technitium DNS is pretty cool, you just unzip/tar it and run start.sh or start.bat and it "just works." Of course, I did have a process already on port 53 - DNS - so I did a little debugging, but that was my fault.

Here's the local web UI that you can use to administer the server locally. You can forward to whatever upstream DNS server you'd like, with the added bonus that the forwarder can be DNS over HTTPS so you can use things like CloudFlare, Google, or Cloud9. Using DNS over HTTPS means your DNS lookups can be secured with DNSSEC and are far more secure and private than regular DNS over UDP/TCP.

Technitium also includes support for DNS Sinkholes (similar to how I use my Pi-Hole) and Block List URLs. It'll automatically download block lists daily and block ads.

Technitium is a lovely .NET Core based DNS Server

It's also educational to try running your own DNS server and it's fun to read the code! The code for Technitium's DNS Server is up at https://github.com/TechnitiumSoftware/DnsServer and is super interesting from a networking perspective, but also from an C# perspective. It's a very interesting example of some .NET Core code at a very low level and I'm thrilled that it works on every operating system.

There's even bash scripts for setting Technitium up on your RaspberryPi or Ubuntu to make it easy. If you are using Windows and don't care about .NET Core you can use the .NET that's included with Windows and Technitum has a Tray app and Installer as well.

Some of the code isn't "idiomatic" C#/.NET Core but it's interesting to read about. The main DnsWebService.cs is pretty intense as it doesn't use any ASP.NET Core routing or primitives. It's a complete webserver written using only System.Net and its own support libraries, along with some of the lower-level Newtonsoft.Json libraries.

The main DnsServer is also quite low level and very performant. It lives in DnsServer.cs. It opens up n sockets (depending on how many ports you bind to) and starts accepting connections here. DNS Datagrams start getting parsed here, right off the stream. The supporting libraries and networking helper code lives over at https://github.com/TechnitiumSoftware/TechnitiumLibrary which is a wealth of interesting and useful code covering BitTorrent, Mail, and Firewall management. There's a ton of OO representations of networking concepts, and all the DNS records are parsed manually.

Technitium has a DNS Server, client, Mac Address Changer, and open source instant messenger. The developer is extremely prolific. They even host a version of "Get HTTPS for free" that works with Windows and makes getting Let's Encrypt certificates super easy.

Anyway, I've been enjoying exploring DNS again and reminding myself not only that it still works great (since I learned about DNS from sniffing packets in networking class) and it's been updated and improved with caches, DNSSEC, DNS over HTTP and more in the years following.

Here I've set my IPv4 DNS to 127.0.0.1 and my IPv6 DNS to ::1, then I run NSLookup and try some domain lookups.

Looking up domains at the command line with nslookup

Again, to be clear, the local DNS server took these lookups and then forwarded them upstream to another server. However, you have the choice for your upstream lookups to be done over whatever protocols you want, you can use Google, OpenDNS, Quad9 (with DNSSEC or without), and on and on.

Are you running your own DNS Server?


Sponsor: Manage GitHub Pull Requests right from the IDE with the latest JetBrains Rider. An integrated performance profiler on Windows comes to the rescue as well.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Hosting By
Hosted in an Azure App Service
April 23, 2019 19:55
An alternative to 7zip, for those of us who like the console but dislike remembering many single-letter options...


function Expand-TarGzip {
<#
.SYNOPSIS
Expands a .tar.gz or .tgz archive.
.INPUTS
You cannot pipe input to this cmdlet.
.OUTPUTS
Nothing is output from this function.
.NOTES
No rights reserved. Free as in beer. :)
#>
[CmdletBinding(SupportsPaging = $false, SupportsShouldProcess = $false)]
[Alias('tgz')]
PARAM(
# Archive to expand
[Parameter(Position = 0, ValueFromPipeline = $true)]
[string]$TarFile,

# Output destination
[Parameter(Position = 1)]
[string]$OutFolder
)

BEGIN {
if ($OutFolder) {
if (-not (Test-Path -Path $OutFile)) {
New-Item -Path $OutFile -ItemType 'Directory' > $null
}

tar -xfzv $TarFile -C $OutFolder
} else {
tar -xfzOv $TarFile
}
}
}
April 23, 2019 19:59
Doh, in the above PowerShell script, the doc comment line under .INPUTS is completely wrong, should be "Archive file name to expand."
April 23, 2019 22:54
I'm seeing the curl and wget commands being implemented as aliases to the Invoke-WebRequest PowerShell commandlet on Windows 10 (1809), and requiring the same CLI syntax as the commandlet, not the commands themselves.

However, under cmd and not PowerShell, they're working as expected.
April 24, 2019 0:27
Just a quick nitpick: DNS over HTTPS (not to be confused with DNS over TLS) is completely separate from DNSSEC. You can gain the integrity benefits of DNSSEC without using DoH, just as you can have the privacy benefits of DoH (or DoT) without using DNSSEC.

The best method, of course, would be to use both, if possible. :)
April 24, 2019 0:58
I'm going to be "that guy," so please read this with charity.

*Everyone* should be using Cloudflare as their primary external DNS server (i.e. irrespective of whether they are using Pi-Hole or Technitium or anything like that internally).

https://www.cloudflare.com/learning/dns/what-is-1.1.1.1/

1.1.1.1
April 24, 2019 2:06
Donnie Hale, why CloudFlare and not, say, Google or Quad9? Quad9, for example, provides another layer of malware DNS filtering, and does not harvest lookup queries for personal or marketing data.
April 24, 2019 13:22
CloudFlare's DNS isn't without flaws. For example it doesn't support "EDNS Subnet-Client" which is used by some CDN (like Akamai, so not a small one!) and make them fail or delay the request (like 10s to even start to load an image or a .js).

So even if 1.1.1.1 is very good (both in performance thanks to CloudFlare and in privacy thanks to the partnership with APNIC), it is not good for everyone (I did lost a lot of time to troubleshoot the EDNS problem).
April 24, 2019 13:34
Hi Scott, I've missed the news about the new commands being available in Windows 10, that's great. I found tar and curl, but I cannot find wget. Am I the only one? Should I enable something specific? (I have wget under bash, I just cannot find it in the native cmd, and it would be awesome to have it there as well)

https://techcommunity.microsoft.com/t5/Containers/Tar-and-Curl-Come-to-Windows/ba-p/382409
April 24, 2019 17:59
I've been in the process of rebuilding my home network after adding some new hardware. I'm currently nailing down a couple important details, and one of them was DNS.

I think you've helped me finally pick what DNS server to use. I'll give it a try and complain to you on Twitter if I have any problems. ;)
April 25, 2019 18:45
Nice article. This DnsWebService class is huge. I wonder if they would be better of to split it into multiple classes and make it more managable and readable.
April 27, 2019 1:04
Scott, do you use this on your machines only, or for the entire house? Is it's the second, how do you deal with downtime (caused by reboots or whatever)?
Max
April 28, 2019 2:58
Hi. Following you're blog for a few years now. Always doing a great job and inspiring people in very different ways.
I'd try to follow your lead and experiment with different things. So, created a quick docker file to run it on my Synology nas.

https://hub.docker.com/r/ogomes/technitium-dns-server

Please continue the good work

Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.