Skip to content

Instantly share code, notes, and snippets.

Last active December 22, 2021 17:13
Show Gist options
  • Save magnetikonline/6236150 to your computer and use it in GitHub Desktop.
Save magnetikonline/6236150 to your computer and use it in GitHub Desktop.
Using Dnsmasq with Ubuntu 16.04LTS/14.04LTS/12.04LTS for virtual machine web application testing.

Using Dnsmasq with Ubuntu for VM web application testing

When running virtual machines under a Linux host system for testing web apps in various browsers (e.g. Internet Explorer), I found it rather tedious having to continually tweak the hosts file within each VM for the purpose of adding entries pointing back to the host machine's development web server address.

Instead the steps below will setup Dnsmasq on a Ubuntu 16.04LTS, 14.04LTS or 12.04LTS host machine for the purpose of serving both it's own DNS queries and that of virtual machine guests. Dnsmasq will parse the /etc/hosts file on your host machine where we will keep a single set of DNS entires to our test web application(s).

Method 1

Ubuntu 12.04LTS and above by default runs their own instance of Dnsmasq via the NetworkManager service, sadly it's configured to ignore /etc/hosts and to only listen on the loopback interface By moving the Dnsmasq binary to an alternative filename and creating our own dnsmasq bash script we can correct this behaviour.

Idea has been taken from a post at the Ask Ubuntu StackOverflow website. Bash scripts are slightly different between 16.04-14.04/12.04.

Ubuntu 16.04LTS / 14.04LTS

$ sudo mv /usr/sbin/dnsmasq /usr/sbin/dnsmasq.bin
$ sudo curl \
	-o /usr/sbin/dnsmasq \
$ sudo chmod a+x /usr/sbin/dnsmasq
# update ETH_INTERFACE to your network interface name

# restart dnsmasq...

# for Ubuntu 16.04LTS
$ sudo systemctl restart NetworkManager

# for Ubuntu 14.04LTS
$ sudo restart network-manager

Ubuntu 12.04LTS

$ sudo mv /usr/sbin/dnsmasq /usr/sbin/dnsmasq.bin
$ sudo curl \
	-o /usr/sbin/dnsmasq
$ sudo chmod a+x /usr/sbin/dnsmasq

# restart dnsmasq...
$ sudo restart network-manager

Method 2

Alternatively, we can stop NetworkManager running Dnsmasq entirely and install our own managed instance of Dnsmasq. Whilst this does work, I have found it a little flakey on system startup - Dnsmasq starts too early, before NetworkManager can do it's setup resulting in no DNS until Dnsmasq is restarted - so would suggest the above method 1 as the better solution.

Stop NetworkManager running it's own Dnsmasq

$ sudo cp /etc/NetworkManager/NetworkManager.conf /etc/NetworkManager/NetworkManager.conf.pkg
$ sudo cat /etc/NetworkManager/NetworkManager.conf \
	| sed "s/dns=dnsmasq/#dns=dnsmasq/" \
$ sudo restart network-manager

Install Dnsmasq and config

$ sudo apt-get install dnsmasq
$ sudo cp /etc/dnsmasq.conf /etc/dnsmasq.conf.pkg
$ sudo wget \ \
	-O /etc/dnsmasq.conf
$ sudo /etc/init.d/dnsmasq restart

Your host machine will now be running it's own configured instance of Dnsmasq, not one managed via NetworkManager.

Virtual machine & host entry setup

  • Modify guest virtual machine to use host machine's IP address as it's primary DNS server see note.
  • Add required DNS entries to your hosts /etc/hosts file.
  • Restart Dnsmasq to reload /etc/hosts and add entries to it's own local DNS lookup list:
    • Method 1: sudo restart network-manager
    • Method 2: sudo /etc/init.d/dnsmasq restart
  • Guest virtual machines will now be able to resolve DNS via the running Dnsmasq instance for both world-wide and /etc/hosts entries.

Note regarding guest VM DNS server change and VirtualBox

YMMV, but with regards to Windows VMs I find it only necessary to change primary DNS server details to the local host Dnsmasq listening IP for Windows XP OSes.

Windows 7/8 are able to correctly configure the correct DNS server (e.g. host Dnsmasq instance) automatically upon boot when using VirtualBox with NAT networking.

#!/bin/bash -e
# build updated run parameters
# strip --no-hosts switch so /etc/hosts is read
DNSMasqParameters=$(echo -n "$DNSMasqParameters" | sed --regexp-extended "s/ --no-hosts( |$)/ /")
# strip --listen-address switch so dnsmasq listens on all network interfaces
DNSMasqParameters=$(echo -n "$DNSMasqParameters" | sed --regexp-extended "s/ --listen-address=[^ ]+( |$)/ /")
# run dnsmasq
exec $DNSMASQ_BIN $DNSMasqParameters
#!/bin/bash -e
# strip --no-hosts switch so /etc/hosts is read
DNSMasqParameters=$(echo -n "$@" | sed --regexp-extended "s/ --no-hosts( |$)/ /")
# fetch local machine IP address from first network adapter
ifconfig "$ETH_INTERFACE" | \
sed --regexp-extended --silent "s/ *?inet addr:(([0-9]{1,3}\.){3}[0-9]{1,3}) .+/\1/p"
# run dnsmasq
exec $DNSMASQ_BIN $DNSMasqParameters --listen-address=$localIPAddress
# update eth0 to suit your Host machine
Copy link

Bozzie4 commented Aug 19, 2014

The simplest way is to just use the dnsmasq config file that comes with Network Manager in Ubuntu 12.10 and up.

See here :

Copy link

Finally I found a solution that, simply add this line 'addn-hosts=/etc/hosts' to dnsmasq configuration file of Newworkmanager package.

echo 'addn-hosts=/etc/hosts' > /etc/NetworkManager/dnsmasq.d/etc-hosts
service network-manager restart

The idea is, we are adding /etc/hosts as a additional host file .


Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment