« Chaining Wireless Access Points for Compartmentalized Security | Main | Disaster Preparedness in the San Francisco Bay Area »

Running Multiple 'dnsmasq' Processes

I recently added a second Linksys WRT54G(L) to my home network with the purpose of creating an isolated wireless network using WEP encryption. I wanted to issue hosts in the secure network (lan1) Internet Protocol (IP) address in a different range than hosts in WEP network (lan2). This just helps to emphasize the isolation since the networks are actually kept separate by the hardware.

The OpenWRT firmware uses the dnsmasq program as a caching name-server and DHCP server. It's has a small memory and filesystem footprint, and contains a feature-set perfect for most residential networks. I wanted to continue using dnsmasq as DHCP server for both networks. This meant configuring dnsmasq to issue IPs on two networks, or run two separate dnsmasq processes configured to issue IPs on a specific network.

First, I consulted the web-site for dnsmasq. The Man page indicated some options of interest:

-a, --listen-address=

    "Listen on the given IP address(es)."
-z
    "Setting this option also enables multiple instances of dnsmasq which provide DHCP service to run in the same machine."
-l, --dhcp-leasefile=
    "Use the specified file to store DHCP lease information."
I decided to go the route of running two separate dnsmasq processes. Here are the steps I took:
  • Copy the initialization script (S50dnsmasq) for dnsmasq so that two processes at boot. I created two scripts (S50dnsmasq-lan1, S50dnsmasq-lan2).

    root@OpenWrt:/etc/init.d# ls   
    S05nvram         S50dnsmasq-lan1  S50inadyn        rcS
    S10boot          S50dnsmasq-lan2  S50telnet
    S40network       S50dropbear      S60cron
    S45firewall      S50httpd         S99done
  • I then modified the scripts to cause each dnsmasq process to listen on a different network interface (customize "iface" variable). I also added options to the "args" variable to allow multiple dnsmasq processes and listen on a specific interface.

    root@OpenWrt:/etc/init.d# more S50dnsmasq-lan1
    #!/bin/sh
    
    # The following is to automatically configure the DHCP settings
    # based on nvram settings. Feel free to replace all this crap
    # with a simple "dnsmasq" and manage everything via the
    # /etc/dnsmasq.conf config file
    
    # DHCP interface (lan, wan, wifi -- any ifup *)
    iface=lan1
    ifname=$(nvram get ${iface}_ifname)
    
    udhcpc -n -q -R -s /bin/true -i $ifname >&- || {
      # no existing DHCP server?
    
      # calculate settings
      ipaddr=$(nvram get ${iface}_ipaddr)
      netmask=$(nvram get ${iface}_netmask)
      start=$(nvram get dhcp_start)
      start=$((network+${start:-100}))
      num=$(nvram get dhcp_num)
      num=$((start+${num:-150}))
      eval $(ipcalc $ipaddr $netmask $start $num)
      leases=/tmp/leases-${iface}
      
      # and pass the args via the commandline
      # (because trying to edit the config from here is crazy)
      args="--listen-address=$ipaddr --bind-interfaces --dhcp-leasefile=$leases -F $START,$END,$NETMASK,12h"
    }
    
    # ignore requests from wan interface
    wanproto=$(nvram get wan_proto)
    [ -z "$wanproto" -o "$wanproto" = "none" ] || args="${args} -I $(nvram get wan_ifname)"
  • Make sure that the scripts are executable (chmod +x S50dnsmasq-lan1).
  • Restart the router and check the processes:

    root@OpenWrt:/etc/init.d# ps -eax | grep dnsmasq
      444 nobody      416 S   dnsmasq --listen-address=192.168.1.1 --bind-interface
      460 nobody      396 S   dnsmasq --listen-address=192.168.2.1 --bind-interface

That's it! You should now have two DHCP & DNS servers running on separate network interfaces.