Simple Staging LAN with OpenWRT and dnsmasq

This isn’t PHP-specific, but it’s a simple recipe for a small LAN for testing websites (or any client-server software). With it, you can easily manage a small network with minimal effort. Conceptually, it expands on the idea outlined in “A Simple Staging Server”, where you use the /etc/hosts file and apache virtual hosts to stage your sites.

The staging environment that’s created isn’t as complete as switching /etc/hosts, but it’s a reasonable approximation. Here are the parts:

  • OpenWRT and a compatible router (like the LinksysWRT54G, before version 5, which is not compatible)
  • Apache 2
  • /etc/hosts

OpenWRT uses the dnsmasq daemon to offer DHCP and DNS proxying. dnsmasq does three things. First, it’s a DHCP server, handing out IP addresses to machines on your LAN. Second, it takes DNS requests, and relays the requests to the ISP’s DNS servers, caching some results. Third, it will also serve up domain names in /etc/hosts, letting you share your hosts file.

The third feature is what we’ll use. But first, you have to get OpenWRT installed on the router. See openwrt.org for that info.

Log in to the router.

Your goal is to freeze the IP addresses of your staging servers. You do this by forcing dnsmasq to assign specific IP addresses to specific MAC addresses. Turn on all the computers on your LAN. This will cause the file /tmp/dhcp.leases to be filled with the MAC addresses, IP addresses, and host names of all the computers. Copy this info somewhere and then use it to
create the file /etc/ethers, which is a list of MAC addresses mapped to IP addresses. Mine looks something like this:

# /etc/ethers
# sad
00:11:aa:88:b9:27 192.168.1.142
# stage
00:15:2a:11:aa:9f 192.168.1.106
# sandwich
00:41:aa:8c:ba:aa 192.168.1.124

The numbers could have been manually sequenced, but I’m not picky about that.

Now execute these commands in the shell:

cd /etc
rm hosts
cp /rom/etc/hosts .
rm dnsmasq.conf
cp /rom/etc/dnsmasq.conf .

You do that to get around OpenWRT’s effort to save some space by symlinking files in /etc to the uncompressed, read-only boot image. To modify the files, delete the symlink, and copy the original over.

Then you have to add lines /etc/hosts to include your staging server. In the example below, the staging server is on 192.168.1.106.

#added to /etc/hosts
192.168.1.106 conc.lo
192.168.1.106 go.lo
192.168.1.106 iper.lo

go.lo is a staging server. On that server, in the apache configuration, we have the following. This isn’t on the router; it’s on the staging PC.

<VirtualHost 192.168.1.106:80>
        ServerName go.lo
        ServerAdmin nospam@riceball.com
        DocumentRoot /home/johnk/Sites/go/
</VirtualHost>

That sets up a staging server on the external IP address. (Note that in the article about simple staging servers, we used 127.0.0.1 as the host. In this situation, we want to offer the server to the LAN.)

Then the final edit is to modify dnsmasq.conf to include the following:

local=/lo/

local=/lo/ tells dnsmasq to try and resolve domains that end in .lo with data from /etc/hosts. .lo is a fake top-level domain, short for “local” (if it’s real, we just prevented ourselves from accessing anything in .lo)

Once done, you can reload the configs for dnsmasq:

killall -HUP dnsmasq

The name “go.lo” should now resolve, and is usable as a staging server.