Hi all,

TL;DR - using "--address" for individual host A records is broken, use 
"--host-record" instead.

The following patch changes dnsmasq.init to build individual host records using 
"--host-record" instead of "--address". Using "--address" in this context is 
incorrect. For example, the current init script will create the following two 
entries in /var/etc/dnsmasq.conf:

address=/OpenWrt.lan/192.168.1.1
ptr-record=1.1.168.192.in-addr.arpa,OpenWrt.lan

At first glance this has the desired effect, "OpenWrt.lan" resolves to 
192.168.1.1. However, what it really says is "for anything that ends with 
"OpenWrt.lan," that I don't have a record for, return 192.168.1.1". For example:

fakeaddress.OpenWrt.lan would return 192.168.1.1.
adsfasdfsdfsd.OpenWrt.lan would return 192.168.1.1.

That's wrong and it causes problems when using a real domain name, such as 
domain.com. Often it's desirable to have "domain.com" resolve to an address so 
users can hit the http service at http://domain.com. By using the existing 
"config domain" option, you would configure this as follows:

config domain
        option name 'domain.com'
        option ip '192.168.1.100'

This would create these config items:

address=/domain.com/192.168.1.100
ptr-record=100.1.168.192.in-addr.arpa,domain.com

Now, as a result, anything that doesn't have its own, preexisting record, will 
also resolve to 192.168.1.100. That's no good because things like Windows do 
proxy requests by default for wpad.domain.com and instead of getting back an 
NXDOMAIN, it gets 192.168.1.100 and goes hunting for a pac file that doesn't 
exist.

The solution for this is to use "--host-record". This is actually a lot easier 
to configure because dnsmasq will create the PTR records automatically, so 
there's no need to manual calculate it like is done today. This means that IPv6 
addresses can be supported as well. The attached patch makes this adjustment 
and accomplishes the following:

1. By default, the router's hostname is now added to the configuration using 
"--host-record" instead of "--address". If there's a domain configured, the 
default host-record entry looks like this:

host-record=OpenWrt.lan,OpenWrt,192.168.1.1

With this, now both "OpenWrt.lan" and "OpenWrt" will both resolve to 
192.168.1.1. In the reverse, 192.168.1.1 will resolve to only "OpenWrt.lan".

2. It introduces a new configuration structure to define additional host 
records. For example:

config hostrecord
        list name 'mail.domain.com'
        list name 'www.domain.com'
        list name 'domain.com'
        list ip '192.168.1.100'

It uses lists here because dnsmasq can accept multiple hostnames and IP 
addresses in a single host-record. This generates the following config:

host-record=mail.domain.com,www.domain.com,domain.com,192.168.1.100

All of those hostnames will resolve to 192.168.1.100 in the forward direction. 
192.168.1.100 will resolve to "mail.domain.com" in the reverse.

3. It restructures "dhcp_domain_add()" to remove the manual PTR record 
calculation and configuration. This only supported IPv4 and isn't the proper 
use of the "--address" option. Now it will build a proper "--address" config 
that can support multiple domain names to a single IP address as per the 
dnsmasq MAN page.

Note, the domain name is no longer automatically appended to the end of either 
"config hostrecord" or "config domain" entries as was previously the case. To 
define a specific fqdn, one needs to manually configure it as such. This makes 
the configuration more consistent; only what's configured is what is generated 
for dnsmasq.

Sorry for the long email. I hope it all made sense. If not, please let me know.

Thanks,
Adam


Signed-off-by: Adam Gensler <openwrt at gnslr.us>
---

Index: network/services/dnsmasq/files/dnsmasq.init
===================================================================
--- network/services/dnsmasq/files/dnsmasq.init (revision 36849)
+++ network/services/dnsmasq/files/dnsmasq.init (working copy)
@@ -393,7 +393,7 @@
 
 dhcp_domain_add() {
        local cfg="$1"
-       local ip name names
+       local ip name names record
 
        config_get names "$cfg" name "$2"
        [ -n "$names" ] || return 0
@@ -401,22 +401,15 @@
        config_get ip "$cfg" ip "$3"
        [ -n "$ip" ] || return 0
 
-       local oIFS="$IFS"; IFS="."; set -- $ip; IFS="$oIFS"
-       local raddr="${4:+$4.$3.$2.$1.in-addr.arpa}"
-
        for name in $names; do
-               local fqdn="$name"
+               if [ -z "$record" ]; then
+                       record="$name"
+               else
+                       record="$record/$name"
+               fi
+       done
 
-               [ "${fqdn%.*}" == "$fqdn" ] && \
-                       fqdn="$fqdn${DOMAIN:+.$DOMAIN}"
-
-               xappend "--address=/$fqdn/$ip"
-
-               [ -n "$raddr" ] && {
-                       xappend "--ptr-record=$raddr,$fqdn"
-                       raddr=""
-               }
-       done
+       xappend "--address=/$record/$ip"
 }
 
 dhcp_srv_add() {
@@ -469,6 +462,36 @@
        xappend "--cname=${cname},${target}"
 }
 
+dhcp_hostrecord_add() {
+       local cfg="$1"
+       local names addresses record
+
+       config_get names "$cfg" name "$2"
+       if [ -z "$names" ]; then
+               return 0
+       fi
+
+       config_get addresses "$cfg" ip "$3"
+       if [ -z "$addresses" ]; then
+               return 0
+       fi
+
+       build_list() {
+               for i in $1; do
+                       if [ -z "$record" ]; then
+                               record="$i"
+                       else
+                               record="$record,$i"
+                       fi
+               done
+       }
+
+       build_list "$names"
+       build_list "$addresses"
+
+       xappend "--host-record=$record"
+}
+
 start() {
        include /lib/network
        scan_interfaces
@@ -501,6 +524,19 @@
        config_foreach dhcp_remoteid_add remoteid
        config_foreach dhcp_subscrid_add subscrid
        config_foreach dhcp_domain_add domain
+       config_foreach dhcp_hostrecord_add hostrecord
+
+       # add own hostname
+       [ $ADD_LOCAL_HOSTNAME -eq 1 ] && [ -n "$lanaddr" ] && {
+               local hostname="$(uci_get system.@system[0].hostname)"
+
+               if [ -n "$DOMAIN" ]; then
+                       dhcp_hostrecord_add "" "${hostname:-OpenWrt}.$DOMAIN 
${hostname:-OpenWrt}" "$lanaddr"
+               else
+                       dhcp_hostrecord_add "" "${hostname:-OpenWrt}" "$lanaddr"
+               fi
+       }
+
        echo >> $CONFIGFILE
        config_foreach dhcp_srv_add srvhost
        config_foreach dhcp_mx_add mxhost
@@ -510,12 +546,6 @@
        config_foreach dhcp_cname_add cname
        echo >> $CONFIGFILE
 
-       # add own hostname
-       [ $ADD_LOCAL_HOSTNAME -eq 1 ] && [ -n "$lanaddr" ] && {
-               local hostname="$(uci_get system.@system[0].hostname)"
-               dhcp_domain_add "" "${hostname:-OpenWrt}" "$lanaddr"
-       }
-
        service_start /usr/sbin/dnsmasq -C $CONFIGFILE && {
                rm -f /tmp/resolv.conf
                [ $ADD_LOCAL_DOMAIN -eq 1 ] && [ -n "$DOMAIN" ] && {

_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/mailman/listinfo/openwrt-devel

Reply via email to