Dnsmasq setup

Installation.

To compile and install dnsmasq, the following command (as root) is enough.
make install
You might want to edit config.h. Dnsmasq has been run on (at least) Linux, uCLinux, AIX 4.1.5, FreeBSD 4.4 OpenBSD and Tru64 4.x Dnsmasq is normally run on a firewall machine (the machine with the modem or other connection to your ISP.) but it can run on any machine with access to the ISPs nameservers. Put the binary in /usr/local/sbin/dnsmasq (running make install will do this) and arrange for it to be started at boot time. Note that dnsmasq needs to run as root, since it binds privileged ports. It will drop root privileges after start-up. Dnsmasq logs problems using the syslog facility as a daemon. It logs debugging information to local0

Configuration.

Configuration for dnsmasq is pretty simple in almost all cases. The program has collected a fair few options as it has developed but most of them are not needed most of the time. A machine which already has a DNS configuration (ie one or more external nameservers in /etc/resolv.conf and any local hosts in /etc/hosts) can be turned into a nameserver simply by running dnsmasq, with no options or configuration at all. Set the IP address of the machine running dnsmasq as the DNS server in all the other machines on your network, and you're done.

With a few option flags, it is possible to make dnsmasq do more clever tricks. Options for dnsmasq can be set either on the command line when starting dnsmasq, or in its configuration file, /etc/dnsmasq.conf.

Making the nameserver machine use dnsmasq.

In the simple configuration described above, processes local to the machine will not use dnsmasq, since they get their information about which nameservers to use from /etc/resolv.conf, which is set to the upstream nameservers. To fix this, simply replace the nameserver in /etc/resolv.conf with the local address 127.0.0.1 and give the address(es) of the upstream nameserver(s) to dnsmasq directly. You can do this using either the server option, or by putting them into another file, and telling dnsmasq about its location with the resolv-file option.

Automatic nameserver configuration.

The two protocols most used for automatic IP network configuration (PPP and DHCP) can determine the IP addresses for nameservers automatically. The daemons can be made to write out a file in the resolv.conf format with the nameservers in which is perfect for dnsmasq to use. When the nameservers change, for instance on dialling into a new ISP using PPP, dnsmasq will automatically re-read this file and begin using the new nameserver(s) completely transparently.

Automatic DNS server configuration with PPP.

Later versions of pppd have an option "usepeerdns" which instructs it to write a file containing the address(es) of the DNS severs in /etc/ppp/resolv.conf. Configure dnsmasq as above with "nameserver 127.0.0.1" in /etc/resolv.conf and run dnsmasq with to option resolv-file=/etc/ppp/resolv.conf.

On Redhat (at least versions 7.1, 7.2 and 7.3) you can set pppd options by adding "PPPOPTIONS=usepeerdns" to /etc/sysconfig/network-scripts/ifcfg-ippp0. In the same file, make sure that "PEERDNS=no" to stop RedHat's network initscripts from copying /etc/ppp/resolv.conf into /etc/resolv.conf.
On SuSE (at least version 8.1, and 8.2) you should use YaST to activate [x] Modify DNS when connected then stop SuSEs network initscripts from copying /etc/ppp/resolv.conf into /etc/resolv.conf by modifying MODIFY_RESOLV_CONF_DYNAMICALLY="no" in /etc/sysconfig/network/config.

Automatic DNS server configuration with DHCP.

You need to get your DHCP client to write the address(es) of the DNS servers to a file other than /etc/resolv.conf. For dhcpcd, the dhcpcd.exe script gets run with the addresses of the nameserver(s) in the shell variable $DNS. The following bit of shell script uses that to write a file suitable for dnsmasq.

echo -n >|/etc/dhcpc/resolv.conf
dnsservers=${DNS//,/ }
for serv in $dnsservers; do
    echo "nameserver $serv" >>/etc/dhcpc/resolv.conf
done

Remember to give dhcpcd the -R flag to stop it overwriting /etc/resolv.conf.

For other DHCP clients it should be possible to achieve the same effect.

DHCP and PPP.

On a laptop which may potentially connect via a modem and PPP or ethernet and DHCP it is possible to combine both of the above configurations. Running dnsmasq with the flags resolv-file=/etc/ppp/resolv.conf resolv-file=/etc/dhcpc/resolv.conf makes it poll both files and use whichever was updated last. The result is automatic switching between DNS servers.

Integration with DHCP.

Dnsmasq reads /etc/hosts so that the names of local machines are available in DNS. This is fine when you give all your local machines static IP addresses which can go in /etc/hosts, but it doesn't work when local machines are configured via DHCP, since the IP address allocated to machine is not fixed. Dnsmasq comes with an integrated DHCP daemon to solve this problem.

The dnsmasq DHCP daemon allocates addresses to hosts on the network and tries to determine their names. If it succeeds it add the name and address pair to the DNS. There are basically two ways to associate a name with a DHCP-configured machine; either the machine knows its name which it gets a DHCP lease, or dnsmasq gives it a name, based on the MAC address of its ethernet card. For the former to work, a machine needs to know its name when it requests a DHCP lease. For dhcpcd, the -h option specifies this. The names may be anything as far as DHCP is concerned, but dnsmasq adds some limitations. By default the names must no have a domain part, ie they must just be alphanumeric names, without any dots. This is a security feature to stop a machine on your network telling DHCP that its name is "www.microsoft.com" and thereby grabbing traffic which shouldn't go to it. A domain part is only allowed by dnsmasq in DHCP machine names if the domain-suffix option is set, the domain part must match the suffix.

As an aside, make sure not to tell DHCP to set the hostname when it obtains a lease (in dhcpcd that's the -H flag.) This is not reliable since the DHCP server get