Faking DNS entries for the Android emulator using Unbound

Previously I ranted about JQuery Mobile and the immature state of mobile development tools. While I was on that project I reckoned it might be a good idea to use an emulator so I could test what my mobile Web site might look like in real life.

A nice idea, but in practice it seems the mobile toolchain is… rather more full of good intentions than actual capability.

A quick check with my product owner confirmed that based on anecdotal research on the use of mobile devices by doctors in the NHS, iOS was the primary target, with Android a distant second.

Unfortunately another quick check confirmed that the budget wouldn’t stretch to anything capable of running an iPhone development kit. I was so tempted to nip down to the local Apple Store and get a Mac Mini, but, given that once this job had finished it’d really just be a toy… I vetoed that one.

So. I’ve had my fingers burned (a bit) with previous Windows Mobile devices, but lots of people I know and respect reckon that Windows Phone 7 is really pretty good. So it’s off to the Microsoft site to download their emulator… which promptly told me that my video drivers were Just Not Up To Scratch. Which is fairly reasonable given that I’m using athree-year-old laptop.

So. Android. My wife has an HTC Desire HD which is really rather cool, so off to Google we go to get the Android emulator. Only to find that – well, it’s really not that brilliant on Windows. Don’t get me wrong, it works, but it’s just … not quite right.

Oh, and it’s slower than molasses on a January day in Gloucestershire. Slower than a real device, which is quite remarkable, and probably explains why Android apps are quite fast: developers get used to the poor performance of the emulator.

Whatever. I can (eventually) get to the mobile browser and enter some sites, which work fine — at least, they work as well as they ever do on a mobile browser.

But there’s a snag: hacking the local hosts file.

This project uses host headers to allow multiple ASP.NET sites to run on a single IIS server. The same goes for local development boxes, so to allow local IIS to work as it should we have a dozen or so entries in our local hosts file. Locally, the Windows DNS system checks this file for the “development” versions of the hosts first, and so all is well.

However, the emulator is its own host, which (from what I can tell) doesn’t use the DNS name resolver on the PC. Rather, it uses the DNS subsystem on the phone itself.

At its heart Android is really a Linux distro under the hood, so in theory we should find something useful in or around/etc/hosts; and, yes, sure enough there is.

A quick Google brought up a couple of sites that suggested that hacking that hosts file is quite feasible and should work. But other sites suggested that the Android hosts file is really very sensitive to line endings, tabs, the current phase of the moon and other random variables.

Whatever it was I did, I clearly didn’t invoke the right deity, as no matter what I tried the darned thing wouldn’t resolve my host. OK, I grant you that given that each boot-up cycle took ten minutes (!) I didn’t try too hard, but it was still frustrating.

So I gave up and carried on using Chrome on the PC to test the site, which was reasonably close.

A few weeks later and I’m further on the project but don’t yet have a real device to test the JQuery Mobile modifications I’ve made. So I take the plunge and give myself a free morning to sort the situation out.

This time, one thing I do that’s different is to install the emulator on an Ubuntu virtual machine. In hindsight this seems crazy — why run an emulator on an emulator? — but the Android ecosystem is much better supported on Linux than Windows and the tooling felt, well, right when run on a Linux host.

Better, I now had a degree of redirection that I could use to crack the DNS issue. The VMware Workstation virtual machine can be configured to use a virtual network shared with the host, so I had a scout around to see if I could configure a DNS server on the PC that would supply the missing network names. My theory was that I could then point the DNS client on the Ubuntu box to point to my Windows host.

One option was to install a Windows Server virtual machine and configure a DNS server through Active Directory… er, no, thanks.

Another option was to install a natty bit of open source software I found called Unbound. This is a full DNS server that appears to do … everything .. and that runs as a Windows service.

And, it works a treat, even though configuring it is a little bit of a challenge. In particular there’s all kinds of options for DNSSEC that I just didn’t need as this was going to run on a virtual network locally to my PC.

Here’s my configuration file:

# Unbound configuration file on windows.
server:
 verbosity: 2
 logfile: "C:\temp\unbound.log"

use-syslog: yes
# the IP address of the
interface: 192.168.121.1
access-control: 0.0.0.0/0 allow
access-control: ::0/0 allow
domain-insecure: "."
local-data: "devauth.doccom.me IN A 192.168.121.1"
local-data: "devs.doccom.me IN A 192.168.121.1"
local-data: "devapi.doccom.me IN A 192.168.121.1"
local-data: "devm.doccom.me IN A 192.168.121.1"
forward-zone:
 name: "."
 forward-addr: 10.0.124.3

Or, put another way, this

  • logs reasonably verbosely to a file
  • listens only on IP address 192.168.121.1, which is the IP address of the Windows host on the virtual network
  • allows access from anywhere – not an issue as the resolver is only listening on a private internal virtual network
  • adds four hostnames, each of which resolves to the local Windows host
  • forwards anything else through to 10.0.124.3, which is the address of the local DNS server.

I saved this as service.conf in the Unbound folder and verified that all was well by running Unbound at the command line. I then reconfigured VMware to use this as the default DNS server for DHCP requests for that private network – and, hurrah, after a reboot the Linux host could resolve my custom hostnames!

Better, the Android emulator – which is also dispensed a network address through DHCP – worked just fine, too. At which point I ran into all sorts of issues about cross-domain AJAX calls, but that’s a post for another day.

Author: Jeremy McGee

I write software, and try to help others do the same.