Networking – DD-WRT: dnsmasq headaches with static hosts

dd-wrtdnsdnsmasqnetworkingrouter

I am using dd-wrt (r23503, for the record) on my new Asus RT-AC56U router. Unfortunately, dnsmasq configuration is giving me nothing but headaches. Here's what I want:

  • DNS queries from the LAN/WLAN for hosts on the LAN/WLAN should be answered for both short names and FQDNs.
  • Since some of the devices are portable (like my phone), I need host.mydyndomain.net to resolve to a LAN IP when connected to the LAN and to the external IP when queried from outside the LAN.

But here is what I currently get:

  • Queries for DHCP leased hosts are being correctly returned (dd-wrt's "Local DNS" option for dnsmasq).
  • Queries to any random non-existant host incorrectly return the external WAN IP address. So, "nslookup foobarbaz" gives a result when it should return an error.

As for my hosts with static IPs, I have not yet found an adequate solution. I read through the dnsmasq manpage and from what I can tell, the correct choice is the "host-record" option.

The dnsmasq related configuration in dd-wrt (under the Services tab) is:
"DHCP Server" section:
Used domain: WAN
LAN domain: [blank]
Additional DHCPd Options: [blank]
One static lease defined.

"DNSMasq" section:
DNSMasq: enabled
Local DNS: enabled
No DNS Rebind: enabled
Additional DNSMasq Options:
host-record=myhost,myhost.mydyndomain.net,192.168.1.1
[several more host-record entries for the other hosts with static LAN IPs]

Unfortunately, putting these host-record lines in the additional options box seems to completely break dnsmasq and then nothing can connect to the LAN/WLAN via DHCP. Once I empty the contents of the box then DHCP starts working again.

My dnsmasq.conf file is as follows:

interface=br0
resolv-file=/tmp/resolv.dnsmasq
all-servers
domain=mydyndomain.net
dhcp-leasefile=/tmp/dnsmasq.leases
dhcp-lease-max=51
dhcp-option=lan,3,192.168.1.1
dhcp-authoritative
dhcp-range=lan,192.168.1.100,192.168.1.149,255.255.255.0,1440m
dhcp-host=88:53:2E:9B:3E:80,Redtail,192.168.1.5,1440m
stop-dns-rebind

The /etc/resolv.conf file is:

search ph.cox.net
nameserver 192.168.1.1

And the /tmp/resolv.dnsmasq file is:

nameserver 208.67.222.222
nameserver 208.67.220.220
nameserver 68.105.28.13

Another smaller, but unrelated, issue: On dd-wrt's "basic setup" page in the DHCP config section I have entered the IPs for OpenDNS's servers (as you can see above). I'd prefer to just use these two nameservers, but the nameserver is automatically tacked on as the third nameserver. Is there a way to tell dd-wrt to ignore DNS info that it receives when acquiring a DHCP lease from the modem/ISP?

So… what am I doing wrong? Clearly, dnsmasq is not happy with the host-record entries, but what is the correct option to use? I'm putting this information in this location rather than /etc/hosts since the latter is a generated file and not easily modified via the web interface. Of course, I can easily edit it by connecting via SSH, but my changes won't be persistent.

Best Answer

I have quite a bit of experience with dnsmasq on dd-wrt and especially close to the date of this comment. I can share with you my working solution to each of the answers to each requirement. I will resist adding more.

Each option in your active /tmp/dnsmasq.conf posted above comes directly from the config options you have selected as described

Except

for your hostname= entry which you should not use imo. You want

Used Domain: [WAN/LAN] not Used Domain [WAN].

This will allow wired (LAN) and wireless (WAN) devices to work on your network.

Also pick a short Lan Domain: [dom ] or any short word besides local. Some use lan some use localdomain . This is required for your requirements and will provide an anchor faux internal only domain that only you and internal users will see/use. The value you choose will be put into each DHCP client's search dom resolver. I will use dom for the remainder but you can make it whatever you like.

I will start with the first two requirements.

  1. DNS queries from the LAN/WLAN for hosts on the LAN/WLAN should be answered for both short names and FQDNs.

  2. Since some of the devices are portable (like my phone), I need host.mydyndomain.net to resolve to a LAN IP when connected to the LAN and to the external IP when queried from outside the LAN.

For hosts having a different internal vs external ip but the same name on both sides of dd-wrt you need to have:

  • Add one line per resolvable host in your Static Leases just below your correctly empty Additional DHCP Options text area. Note the internal name web.dom or just web is for convenience when on the lan.

Note:

 [Static Leases++++++++++++++++++++++++++++++++++++++++++++++++++++++++]    
  [MAC Address]       [Host Name   ][IP Address    ][Client Lease Time]
  [00:19:B9:5B:2B:A5] [web         ][192.168.2.5   ][             1440]

Notes: I thought this was used only for udhcpcd but this is also used by dnsmasq and will write both the actual dnsmasq.conf with correct dhcp-host= lines and puts a `ip host.dom entry for each in /tmp/hosts used by DNSMasq to do all the local name resolution.

I have a script and text file to create these entries as the web interface is a bit cumbersome. Here's what the script does in a nutshell.

macToHostNames.txt:
# comment lines ignored unless embedded set:tag values like set:kids 
# note the ip is just the HOST portion of the subnet, eg: 192.168.1.32 -> 1.32
# host      id       mac address        cnames/aliases for same box
kidhost1    1.32     00:MA:CA:DD:E5     alias1 nabi2 # in-line comment set:kid 
web         1.5      00:AM:AC:AD:ES     www homeweb  # web server with aliases
EOF
generate_Files_Then_Send_Then_Activate_If_Tests_Are_Ok.sh < macToHostNames.txt
# this script file creates 3 files which are sent along with a test script:
dnsmasq_options.new # nvram set dnsmasq_options="$(cat dnsmasq_options.new)"
static_leases.new   # nvram set static_leases="$(cat static_leases.new)"
static_leasenum.new # nvram set static_leasenum="$(cat static_leasnum.new)"
testDnsMasqOpts.sh  # scp -p *.new test*.sh admin@gw:/tmp && ssh admin@gw "/tmp/test*.sh" 
  • add address=/web.dynip.org/<ip> lines in your DNSMasq Options box address=/web.mydyndomain.net/192.168.2.5 # add as many of these as you need

  • finally you need to update your DDNS config to provide the DDNS service mapping your external ISP provided dynamic ip address to resolve as web.mydyndomain.net. I presume you have successfully configured this part.

With this configuration you can ping web or ping web.dom or ping web.mydyndomain.net will return 192.168.2.5 while inside the firewall and access from outside by the name web.mydyndomain.org still works.

The other requirements are met by your other config but you can safely add these lines as I have tested MANY times (to the point of writing a script to execute one dnsmasq line at a time and showing me the offending line since ALL dns logging is left out for space in my latest dnsmasq build and all you can rely on is the return status of the dnsmasq: $?).

For the last requrements I will show you lines of my config with comments (note you can put comments in the DNSMasq Additional Options box).

  1. Queries for DHCP leased hosts are being correctly returned (dd-wrt's "Local DNS" option for dnsmasq).
  2. Queries to any random non-existant host incorrectly return the external WAN IP address. So, "nslookup foobarbaz" gives a result when it should return an error.
  domain-needed    # dont fwd to ext DNS names with no domain
  address=/web.mydnsdomain.org/192.168.2.5 # resolve to this internally!
  expand-hosts     # add .dom to host names without a domain 
  local=/dom/      # map all host.dom request to *this* dns
  bogus-priv       # reject local lookups not in hosts
  localise-queries # for local servers

I will throw in some non-related freebies of questionable value (and for offsite backup).

 no-ping          # some swear by this one to get DNSMasq to work!
 filterwin2k      # junk from MSFT boxen (remove this if ldap SRV used)
 cache-size=3000  # fast local DNS lookups 
 clear-on-reload  # clear ifr.c changes and sig received 

To Limit the number of DNS servers you can do with the dhcp-options=6 as follows:

dhcp-options=lan,6,8.8.8.8 # this will send only one nameserver entry for all hosts