Recently at work, I was setting up a new virtual machine for development. I was working on something which required several domains pointing to the same box (to test with cookie management). I needed multiple subdomains configured - servicea.devbox, serviceb.devbox for example.
Now what I wanted was to be able to set a wildcard DNS entry, but there was no guarantee I would be on a network that could support that. I would be setting up these VMs on my work laptop – and my laptop would be used on a variety of different networks.
Most of the VMs would be using Virtualbox‘s bridged adapter to connect to the Internet, so I couldn’t rely necessarily on the IPs being fixed on an internal network; The network addresses for my VMs would be at the mercy of whatever DHCP server that was handing out IPs at the time.
The majority of interaction that I would have with these servers would be through a web browser directly on my Windows 7 laptop.
My original goal would have been to just define a hosts file using wildcards, and modify that when the IPs of my VMs changed. But since you can’t use wildcards in a hosts file, that wasn’t an option. An alternative approach would have been to just define every single host that I might need in the hosts file (i.e. no wildcards for you, mister!), but that seemed untidy, especially when I might require several different domains for the same VM (for doing tests with sessions) and have several subdomains (one for each service on the machine) all pointing to the same box.
So I tried an approach which appealed to me a lot more – a local VM for serving DNS.
Now why on earth does such a thing merit a blog post? Well, a few reasons.
- If I ever have to do this again, at least I will have a guide.
- If anyone thinks of doing something similar, at least they will have a guide.
- Because this approach muddles between working on real networks and internal virtual ones, and has a sort of quirky elegance about it which makes me feel more like a hacker than simpler solutions would. So I want to share.
So, here’s the general idea of how my approach would work:
- I would create a small VM (small in disk space, small in RAM consumption) to host a DNS server.
- The DNS server would only be authoritative for local domains.
- The vast majority of configuration would be done with wildcards.
- It would only be necessary to change DNS entries for VMs which were using bridged network connections. Any VM’s that use host only network addresses would probably have fixed IPs, regardless of what network the host machine was on.
A typical interaction which would involve the DNS server would be something like this:
- In browser on laptop, go to http://service1.vm1.devbox/
- Primary DNS will not resolve this address, but the DNS server running on my internal network will.
- The DNS entry will be of the form *.vm1.devbox and will point to an IP address which is on the normal (real) network; a virtual machine using a bridged connection.
- The browser connects to this IP address, which will probably hit my reverse proxy of choice, Nginx.
- Nginx is configured to direct all traffic which goes to service1.* to a particular running service.
- Interaction between browser and service takes place.
The point about Nginx handling service1.* is important – if it is configured like that, then I can interact with service1.env1.vm1.devbox and service1.env2.vm1.devbox without needing to add any additional DNS settings or modify Nginx’s settings – env1 and env2 are just used for the sake of the browser to use different cookies to test different sessions.
So, first step was to get a VM running. I went with installing a minimal version of Ubuntu; 10.04 suited me fine. Within Virtualbox, I allocated it a small amount of memory (128 MB) and tried to allocate a small amount of hard disk space – but allocating less than a GB appears to prevent the installer from automatically creating partitions for you. So I went back and defined 2 GB of storage, but used dynamic allocation, so that it would only grow when required.
One important thing to remember to do is to initially give the VM a bridged network connection while you’re setting it up – it relies entirely on grabbing packages from the internet. The installation was quite smooth; I liked the fact that it asked me how I was going to use the OS – I selected “DNS server”, and it automatically installed BIND 9 for me. In retrospect, I should have also told to install SSH as well, but it wasn’t difficult to install it afterwards.
Once complete, I powered down the VM, switched the adapter from “bridged” to “host only”, and fired it back up. Now all the important work we had to do was to modify configuration files. It was slightly disconcerting not to have vim for use, and plain old vi wasn’t for me, so I made do with simple, but friendly Nano.
We have to give the box a static IP – I’m not sure whether Virtualbox allows you to fix the IP address using its own DHCP server, but I couldn’t see a way. So:
- sudo nano /etc/network/interfaces
And insert the following (replacing the existing definition):
# The primary network interface auto eth0 iface eth0 inet static address 192.168.56.10 netmask 255.255.255.0 network 192.168.56.0 broadcast 192.168.56.255
A restart is probably required at this point. Now my VM was ready to be configured for a DNS server, but I’ll leave that for a second post.
September 16, 2010 at 1:08 pm |
[...] the uninformed rants of allanc Just another WordPress.com weblog « Setting up a VM for local DNS (part 1) [...]