2 ##############################################################################
4 # This program is free software; you can redistribute it and/or modify
5 # it under the terms of the GNU General Public License version 2 as
6 # published by the Free Software Foundation.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # Copyright (C) 2016 Eric Luehrsen
15 ##############################################################################
17 # This crosses over to the dnsmasq UCI file "dhcp" and parses it for fields
18 # that will allow Unbound to request local host DNS of dnsmasq. We need to look
19 # at the interfaces in "dhcp" and get their subnets. The Unbound conf syntax
20 # makes this a little difficult. First in "server:" we need to create private
21 # zones for the domain and PTR records. Then we need to create numerous
22 # "forward:" clauses to forward those zones to dnsmasq.
24 ##############################################################################
26 # while useful (sh)ellcheck is pedantic and noisy
27 # shellcheck disable=1091,2002,2004,2034,2039,2086,2094,2140,2154,2155
31 DM_LIST_KNOWN_ZONES
="invalid"
38 ##############################################################################
42 local partial domain found
44 case $DM_LIST_TRN_ZONES in
51 [A-Za-z0-9
]*.
[A-Za-z0-9
]*)
62 if [ $found -eq 0 ] ; then
63 # New Zone! Bundle local-zones: by first two name tiers "abcd.tld."
64 partial
=$
( echo "$target" |
awk -F.
'{ j=NF ; i=j-1; print $i"."$j }' )
65 DM_LIST_TRN_ZONES
="$DM_LIST_TRN_ZONES $partial"
66 DM_LIST_KNOWN_ZONES
="$DM_LIST_KNOWN_ZONES $partial"
70 ##############################################################################
72 create_host_record_from_domain
() {
74 local ip name debug_ip
76 # basefiles dhcp "domain" clause which means host A, AAAA, and PRT record
77 config_get ip
"$cfg" ip
78 config_get name
"$cfg" name
81 if [ -n "$name" ] && [ -n "$ip" ] ; then
82 create_local_zone
"$name"
86 fe
[89ab
][0-9a-f]:*|
169.254.
*)
91 DM_LIST_LOCAL_DATA
="$DM_LIST_LOCAL_DATA $name.@@300@@IN@@AAAA@@$ip"
92 DM_LIST_LOCAL_PTR
="$DM_LIST_LOCAL_PTR $ip@@300@@$name"
96 DM_LIST_LOCAL_DATA
="$DM_LIST_LOCAL_DATA $name.@@300@@IN@@A@@$ip"
97 DM_LIST_LOCAL_PTR
="$DM_LIST_LOCAL_PTR $ip@@300@@$name"
103 ##############################################################################
105 create_host_record_from_host
() {
109 # basefiles dhcp "host" clause which means host A and PTR records
110 config_get dns
"$cfg" dns
0
111 config_get ip
"$cfg" ip
112 config_get name
"$cfg" name
115 if [ -n "$name" ] && [ -n "$ip" ] && [ $dns -eq 1 ] ; then
118 # domain present, do nothing
121 name
="$name.$UB_TXT_DOMAIN"
126 create_local_zone
"$name"
127 DM_LIST_LOCAL_DATA
="$DM_LIST_LOCAL_DATA $name.@@300@@IN@@A@@$ip"
128 DM_LIST_LOCAL_PTR
="$DM_LIST_LOCAL_PTR $ip@@300@@$name"
132 ##############################################################################
136 local domain relay pref record
138 # Insert a static MX record
139 config_get domain
"$cfg" domain
140 config_get relay
"$cfg" relay
141 config_get pref
"$cfg" pref
10
144 if [ -n "$domain" ] && [ -n "$relay" ] ; then
145 create_local_zone
"$domain"
146 record
="$domain.@@300@@IN@@MX@@$pref@@$relay."
147 DM_LIST_LOCAL_DATA
="$DM_LIST_LOCAL_DATA $record"
151 ##############################################################################
153 create_srv_record
() {
155 local srv target port class weight record
157 # Insert a static SRV record such as SIP server
158 config_get srv
"$cfg" srv
159 config_get target
"$cfg" target
160 config_get port
"$cfg" port
161 config_get class
"$cfg" class
10
162 config_get weight
"$cfg" weight
10
165 if [ -n "$srv" ] && [ -n "$target" ] && [ -n "$port" ] ; then
166 create_local_zone
"$srv"
167 record
="$srv.@@300@@IN@@SRV@@$class@@$weight@@$port@@$target."
168 DM_LIST_LOCAL_DATA
="$DM_LIST_LOCAL_DATA $record"
172 ##############################################################################
174 create_cname_record
() {
176 local cname target record
178 # Insert static CNAME record
179 config_get cname
"$cfg" cname
180 config_get target
"$cfg" target
183 if [ -n "$cname" ] && [ -n "$target" ] ; then
184 create_local_zone
"$cname"
185 record
="$cname.@@300@@IN@@CNAME@@$target."
186 DM_LIST_LOCAL_DATA
="$DM_LIST_LOCAL_DATA $record"
190 ##############################################################################
192 dnsmasq_local_zone
() {
194 local fwd_port fwd_domain wan_fqdn
196 # dnsmasq domain and interface assignment settings will control config
197 config_get fwd_domain
"$cfg" domain
198 config_get fwd_port
"$cfg" port
199 config_get wan_fqdn
"$cfg" add_wan_fqdn
202 if [ -n "$wan_fqdn" ] ; then
203 DM_D_WAN_FQDN
=$wan_fqdn
207 if [ -n "$fwd_domain" ] && [ -n "$fwd_port" ] \
208 && [ ! ${fwd_port:-53} -eq 53 ] ; then
209 # dnsmasq localhost listening ports (possible multiple instances)
210 DM_LIST_FWD_PORTS
="$DM_LIST_FWD_PORTS $fwd_port"
211 DM_LIST_FWD_ZONES
="$DM_LIST_FWD_ZONES $fwd_domain"
215 ##############################################################################
217 dnsmasq_local_arpa
() {
218 local ifarpa ifsubnet
221 if [ -n "$UB_LIST_NETW_LAN" ] ; then
222 for ifsubnet
in $UB_LIST_NETW_LAN ; do
223 ifarpa
=$
( domain_ptr_any
"${ifsubnet#*@}" )
224 DM_LIST_FWD_ZONES
="$DM_LIST_FWD_ZONES $ifarpa"
229 if [ -n "$UB_LIST_NETW_WAN" ] && [ $DM_D_WAN_FQDN -gt 0 ] ; then
230 for ifsubnet
in $UB_LIST_NETW_WAN ; do
231 ifarpa
=$
( domain_ptr_any
"${ifsubnet#*@}" )
232 DM_LIST_FWD_ZONES
="$DM_LIST_FWD_ZONES $ifarpa"
237 ##############################################################################
243 if [ $UB_D_EXTRA_DNS -gt 0 ] ; then
244 # Parasite from the uci.dhcp.domain clauses
245 DM_LIST_KNOWN_ZONES
="$DM_LIST_KNOWN_ZONES $UB_TXT_DOMAIN"
247 config_foreach create_host_record_from_domain domain
248 config_foreach create_host_record_from_host
host
251 if [ $UB_D_EXTRA_DNS -gt 1 ] ; then
252 config_foreach create_srv_record srvhost
253 config_foreach create_mx_record mxhost
257 if [ $UB_D_EXTRA_DNS -gt 2 ] ; then
258 config_foreach create_cname_record cname
263 echo "# $UB_SRVMASQ_CONF generated by UCI"
264 if [ -n "$DM_LIST_TRN_ZONES" ] ; then
265 for record
in $DM_LIST_TRN_ZONES ; do
266 echo " local-zone: $record transparent"
270 if [ -n "$DM_LIST_LOCAL_DATA" ] ; then
271 for record
in $DM_LIST_LOCAL_DATA ; do
272 echo " local-data: \"${record//@@/ }\""
276 if [ -n "$DM_LIST_LOCAL_PTR" ] ; then
277 for record
in $DM_LIST_LOCAL_PTR ; do
278 echo " local-data-ptr: \"${record//@@/ }\""
286 ##############################################################################
289 # Look at dnsmasq settings
291 # Zone for DHCP / SLAAC-PING DOMAIN
292 config_foreach dnsmasq_local_zone dnsmasq
293 # Zone for DHCP / SLAAC-PING ARPA
297 if [ -n "$DM_LIST_FWD_PORTS" ] && [ -n "$DM_LIST_FWD_ZONES" ] ; then
298 if [ $UB_B_DNS_ASSIST -lt 1 ] ; then
300 # Forward to dnsmasq on same host for DHCP lease hosts
301 echo "# $UB_SRVMASQ_CONF generated by UCI"
302 echo " do-not-query-localhost: no"
307 echo > $UB_SRVMASQ_CONF
310 echo "# $UB_EXTMASQ_CONF generated by UCI" > $UB_EXTMASQ_CONF
313 for fwd_domain
in $DM_LIST_FWD_ZONES ; do
315 # This creates a domain with local privledges
316 echo " domain-insecure: $fwd_domain"
317 echo " private-domain: $fwd_domain"
318 echo " local-zone: $fwd_domain transparent"
320 } >> $UB_SRVMASQ_CONF
323 # This is derived from dnsmasq local domain and dhcp service subnets
325 echo " name: $fwd_domain"
326 echo " forward-first: no"
327 for port
in $DM_LIST_FWD_PORTS ; do
328 echo " forward-addr: 127.0.0.1@$port"
331 } >> $UB_EXTMASQ_CONF
336 ##############################################################################
339 if [ "$UB_D_DHCP_LINK" = "dnsmasq" ] ; then
347 ##############################################################################