Setting up a custom dnsmasq resolver

author:ketz
readingTime:5 mins
date:15/Jan/2020

DISCLAIMER: I have NOT looked into the full extent of implications that this configuration results in. There could be unintended side-effects that may be dangerous. I recommend that you evaluate the effects of the changes before carrying them out.

Also, I used a clean instance of Kali 2019.4.

Intro

Setting up a custom resolver using dnsmasq is pretty quick and easy to do. With an additional amount of special scripting sauce, it can be used to elevate your workflow when dealing with IP addresses that may be used for multiple vhosts (like different subdomains www.miau.io, git.miau.io, etc).

Rationale

I came across this because I was looking for a solution that would:

My use case was for playing hackthebox, and attacking machines that served multiple services on different subdomains from the same IP address, however I’m sure that this solution could be used for more varied purposes as it essentially gives you your own private DNS server.

In short, this is a slightly better way to deal with resolving of custom hosts that doesn’t involve messing around with /etc/hosts. The other side to this argument is that it may require you to run additional processing to run successfully so if your system requirements are lacking, then it may be better to stick with the old methods.

Steps

1. Update network-manager configuration

Using your favourite editor, update the /etc/NetworkManager/NetworkManager.conf file. You will want to add an entry under the [main] section which instructs NetworkManager to use dnsmasq to cache DNS results (see line 3 below).

1
2
3
4
5
6
[main]
plugins=ifupdown,keyfile
dns=dnsmasq

[ifupdown]
managed=false

Restart the network-manager.service using the command below.

>> sudo systemctl restart network-manager.service

NetworkManager will now restart and additionally spawn a process for dnsmasq1. We now have our DNS caching server running, so the next step is to add some custom records to it so that we can resolve the names that we choose.

2. Add some DNS configuration

In the /etc/NetworkManager/dnsmasq.d/ directory, add a new *.conf file which will be where dnsmasq will look for your custom records.

Subsequently, add a line to this file to add a record. In the example below, a wildcard entry for anything belonging to *.wildcard.box will resolve to the 10.10.10.1 IP address. This is because the name is prefixed by a . character.

address=/.wildcard.box/10.10.10.1

The lines in this file can be used for much more than just adding address options, but that is as far as is worth mentioning for the purposes of this article2.

3. Restart the dnsmasq process

I’ve found that the easiest way to do this is to kill the dnsmasq process, and let NetworkManager restart it automatically. This causes the program to reload the settings and also clear out the cache. This can be achieved with the following command.

>> sudo killall dnsmasq

4. Test that the configuration is working

Use the dig command to check that the local dnsmasq server is catching the provided address pairings from the configuration file.

>> dig wildcard.box

; <<>> DiG 9.11.5-P4-5.1+b1-Debian <<>> wildcard.box
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4518
;; flags: qr aa rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;wildcard.box               IN      A

;; ANSWER SECTION:
wildcard.box        0       IN      A       10.10.10.1

;; Query time: 0 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu Jan 02 18:37:24 AEDT 1994
;; MSG SIZE  rcvd: 61

Caveats

Things (I think) I have found out whilst testing this configuration:

Conclusion

This is a different, but not necessarily better way of dealing with localized DNS resolution, in comparison with using /etc/hosts. I would consider it easier to manage and also with the additional benefit of being extendable with the other powerful features that dnsmasq has to offer2.

This approach is easy to activate, and generally requires no extra dependencies as long as your distribution is using NetworkManager.

As soon as your local dnsmasq instance can’t find a DNS query it will defer to /etc/hosts and then the DNS servers defined in your network connections, therefore aside from the modifications that you make, it should be entirely unnoticable.

~~~

bonus round: bash script (WIP)

With some bash scripting it makes adding custom hosts to dnsmasq much quicker. You could do something similar to this if you wanted to:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash

# dnsmasq-update.sh
# by ketz

# Usage: ./dnsmasq-update.sh <domain> <host>

domain=$1
host=$2
config_path="/etc/NetworkManager/dnsmasq.d/"
dom_array=(`echo $domain | tr '.' '\n'`)
tld=${dom_array[${#dom_array[@]}-1]}

if [ $# -eq 2 ]; then
    mkdir -p $config_path 2> /dev/null;
    touch ${config_path}${tld}".conf" 2> /dev/null;
    echo "address=/.$domain/$host" >> ${config_path}${tld}".conf";
    sudo killall dnsmasq;
else
    echo "ERR: Incorrect arguments.";
    exit 1;
fi

This script stores the configuration for each top level domain in their own configuration file under /etc/NetworkManager/dnsmasq.d/, this makes it easier to read and manage later on. You could use this to create a custom TLD for a particular engagement and then simply delete the file once it is no longer relevant.


  1. This appears to only work as long as the machine has an external network connection.

    There may be another way to get around this, but until you have an external connection, running dnsmasq is probably not particularly useful. ↩︎

  2. You can see more about dnsmasq configuration options here. ↩︎

sha256: 9b0e3f5cb74eb2c311dbeceb3e248b060e1da7afc3a7228a1221d29422182ae7 (1058)
created: 2020-01-15 21:39:54 +1100 +1100