How to properly test a local DNS server locally?

Context

I intended to set up a local DNS server with Technitium and would like to verify the local DNS server returns the correct response when it is being queried for a domain. It does not work while using nslookup mydomain.com. I expect that to be because the local dns server is not reached from a public/internet place.

To exclude that this is caused by my local DNS server not working correctly (locally), I would like to verify that at least the local DNS server returns the correct IP address if it is queried for my domain.

Attempts

The local DNS server runs on local IP address 127.0.0.1 at port 5379 hence I tried the following commands followed by their respective outputs:

nslookup 127.0.0.1 somedomain.com
;; connection timed out; no servers could be reached

nslookup 127.0.0.1:5379 somedomain.com
nslookup: couldn't get address for 'somedomain.com': failure

nslookup http://127.0.0.1:5379 somedomain.com
;; connection timed out; no servers could be reached

nslookup https://127.0.0.1:5379 somedomain.com
;; connection timed out; no servers could be reached

So either the testing command nslookup 127.0.0.1:5379 somedomain.com is a possible way to test whether the local DNS server returns the correct IP address when it is queried some domain, and I have not set up the local DNS server correctly, or I am using an incorrect testing command.

Question

How can one test the whether the response of a local DNS server returns the correct IP address when it is queried for a domain (from the device that hosts the DNS server)?


Your nslookup syntax is backwards: the server goes after the domain name.

nslookup example.com 127.0.0.1

You cannot specify a custom port with Windows' nslookup. (Although it has a hidden -port= option, but unfortunately it is ignored.)

URLs will not work here: DNS is not HTTP-based. (There is a specification for carrying DNS messages inside HTTP, but it requires special clients and servers.)

If you have Linux or some BSD available (Windows Subsystem for Linux will work too), there's a wider variety of tools such as dig, drill, or delv. For example:

host -p 5379 example.com 127.0.0.1

dig @127.0.0.1 -p 5379 example.com

As several people have noted, the weakness with this answer is that a ping resolving doesn't prove that your DNS server answered. It just proves that some DNS server did. Assuming you can't switch from nslookup to a different command that supports specifying the port (as suggested in this answer), then I see two options that might help you:

  1. Turn off your DNS server so that it definitely is not answering. Attempt the ping, if it returns nothing then but does provide results when you turn the server on, then it's working. Weakness: it won't work if the internet can resolve the address.

  2. Unplug the network cable. Verify that you can't reach anything (so you know that you don't have a WiFi connection or anything like that). Attempt the ping with the server off (to make sure it isn't cached). Then turn the DNS server on and try the ping again.

Note that in either case, everything has to be configured correctly. So your computer needs to be configured to use your local DNS server and the local DNS server has to be configured to answer the request. If it doesn't work, either of those things might be broken. That's why switching to a different DNS client that supports port selection might be better. Then you could test the client against known good servers and the now verified client against your server.

Another option would be port forwarding. The nslookup command will use port 53. If you configure things so that requests to 53 get forwarded to the correct port, that would also allow a request to go through. Again though, it adds additional things that can be not working. Is the DNS server broken? Or is port forwarding misconfigured? Either could give the same result.


I will try to put here a complete example, including exposing a zone from a local dns server.

We will use bind9 as name server on a Ubuntu 21 machine.

First of all define your zones in a file, I used etc/bind/example.com.zone, modifying this example
Docs: https://bind9.readthedocs.io/en/latest/reference.html#zone-file

$ORIGIN example.com.
$TTL 30
@       SOA     localhost. admin.example.com.   (
                2001062501 ; serial
                21600      ; refresh after 6 hours
                3600       ; retry after 1 hour
                604800     ; expire after 1 week
                86400 )    ; minimum TTL of 1 day
;
;
        NS      localhost. ;
        NS      dns1.example.com.
        NS      dns2.example.com.
dns1    A       10.0.1.1
        AAAA    aaaa:bbbb::1
dns2    A       10.0.1.2
        AAAA    aaaa:bbbb::2
bar     CNAME   www.example.com

Now you should load this zone from the bind conf file /etc/bind/named.conf, like this

zone "example.com." IN {
  type master;
  file "/etc/bind/example.com.zone";
  allow-update {none; };
};

I have also added some extra option to the named service /etc/bind/named.conf.options

options {
  ;---OTHER STUFF
  listen-on port 53 { any; };
  allow-query       { any; };
  recursion       yes;
};

Then you can restart the services sudo systemctl restart named bind9

Finally test your zones, you can use what you prefer between dig, host, resolvectl or nslookup.

$ host -t A dns1.example.com localhost

Using domain server:
Name: localhost
Address: 127.0.0.1#53
Aliases: 

dns1.example.com has address 10.0.1.1

$ host -t AAAA dns1.example.com localhost

Using domain server:
Name: localhost
Address: 127.0.0.1#53
Aliases: 

dns1.example.com has IPv6 address aaaa:bbbb::1

$ host -t CNAME bar.example.com localhost

Using domain server:
Name: localhost
Address: 127.0.0.1#53
Aliases: 

bar.example.com is an alias for www.example.com.example.com.

bind9 test from host to guest virtual machine