Skip to content

Instantly share code, notes, and snippets.

@boostrack
Forked from magnetikonline/README.md
Last active August 29, 2015 14:19
Show Gist options
  • Save boostrack/5b3a212e1e82d6a98bcc to your computer and use it in GitHub Desktop.
Save boostrack/5b3a212e1e82d6a98bcc to your computer and use it in GitHub Desktop.

Using Dnsmasq with Ubuntu for VM web application testing

When using virtual machines for testing web apps in various browsers (e.g. Internet Explorer), I have found it rather tedious having to continually tweak the hosts file within each new 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 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 your host's /etc/hosts file where we will keep a single set of DNS entires to our test web applications.

Method 1

Ubuntu 12.04LTS and above by default runs it's own instance of Dnsmasq via the NetworkManager service for all DNS queries, but sadly it's configured to ignore /etc/hosts and to only listen on the loopback interface 127.0.0.1. 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 14.04/12.04.

Ubuntu 14.04LTS

$ sudo mv /usr/sbin/dnsmasq /usr/sbin/dnsmasq.bin
$ sudo wget \
	https://gist.github.com/magnetikonline/6236150/raw/dnsmasq.1404.sh \
	-O /usr/sbin/dnsmasq
$ sudo chmod a+x /usr/sbin/dnsmasq
$ sudo restart network-manager

Ubuntu 12.04LTS

$ sudo mv /usr/sbin/dnsmasq /usr/sbin/dnsmasq.bin
$ sudo wget \
	https://gist.github.com/magnetikonline/6236150/raw/dnsmasq.1204.sh \
	-O /usr/sbin/dnsmasq
$ sudo chmod a+x /usr/sbin/dnsmasq
$ sudo restart network-manager

Method 2 (alternative)

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 as the better option.

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 -e 's/dns=dnsmasq/#dns=dnsmasq/' \
	> /etc/NetworkManager/NetworkManager.conf
$ sudo restart network-manager

Install Dnsmasq and config

$ sudo apt-get install dnsmasq
$ sudo cp /etc/dnsmasq.conf /etc/dnsmasq.conf.pkg
$ sudo wget \
	https://gist.github.com/magnetikonline/6236150/raw/dnsmasq.conf \
	-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

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 determine the correct DNS server automatically on boot. I'm not sure if this is related to the OS, or how VirtulBox guest additions manage the network stack - but it works!

#!/bin/bash
DNSMASQ_BIN=/usr/sbin/dnsmasq.bin
# build updated run parameters
DNSMASQ_PARAMETERS=$@
# remove --no-hosts switch so /etc/hosts is read
DNSMASQ_PARAMETERS=`echo $DNSMASQ_PARAMETERS | sed -e 's/--no-hosts//'`
# remove --listen-address switch so dnsmasq listens on all network interfaces
DNSMASQ_PARAMETERS=`echo $DNSMASQ_PARAMETERS | sed -r 's/--listen-address=[^ ]+//'`
# run dnsmasq
exec $DNSMASQ_BIN $DNSMASQ_PARAMETERS
#!/bin/bash
DNSMASQ_BIN=/usr/sbin/dnsmasq.bin
# build updated run parameters
DNSMASQ_PARAMETERS=$@
# remove --no-hosts switch so /etc/hosts is read
DNSMASQ_PARAMETERS=`echo $DNSMASQ_PARAMETERS | sed -e 's/--no-hosts//'`
# fetch local machine IP address
LOCAL_IP_ADDRESS=`ifconfig | sed -En 's/127.0.0.[0-9]{1,3}//;s/.*?inet addr:(([0-9]{1,3}\.){3}[0-9]{1,3}).*/\1/p'`
# run dnsmasq
exec $DNSMASQ_BIN $DNSMASQ_PARAMETERS --listen-address=$LOCAL_IP_ADDRESS
# update eth0 to suit your Host machine
interface=eth0
cache-size=1000
no-poll
@boostrack
Copy link
Author

REC:

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

See here : http://www.gwbasics.be/blog.nsf/dx/setup-dnsmasq-for-proof-of-concept-development-test-environments.htm

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