You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

181 lines
5.2 KiB

  1. #!/bin/sh
  2. ##############################################################################
  3. #
  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.
  7. #
  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.
  12. #
  13. # Copyright (C) 2016 Eric Luehrsen
  14. #
  15. ##############################################################################
  16. #
  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.
  23. #
  24. ##############################################################################
  25. dnsmasq_local_zone() {
  26. local cfg="$1"
  27. local fwd_port fwd_domain wan_fqdn
  28. # dnsmasq domain and interface assignment settings will control config
  29. config_get fwd_domain "$cfg" domain
  30. config_get fwd_port "$cfg" port
  31. config_get wan_fqdn "$cfg" add_wan_fqdn
  32. if [ -n "$wan_fqdn" ] ; then
  33. UNBOUND_D_WAN_FQDN=$wan_fqdn
  34. fi
  35. if [ -n "$fwd_domain" -a -n "$fwd_port" -a ! "${fwd_port:-53}" -eq 53 ] ; then
  36. # dnsmasq localhost listening ports (possible multiple instances)
  37. UNBOUND_N_FWD_PORTS="$UNBOUND_N_FWD_PORTS $fwd_port"
  38. UNBOUND_TXT_FWD_ZONE="$UNBOUND_TXT_FWD_ZONE $fwd_domain"
  39. {
  40. # This creates DOMAIN local privledges
  41. echo " private-domain: \"$fwd_domain\""
  42. echo " local-zone: \"$fwd_domain.\" transparent"
  43. echo " domain-insecure: \"$fwd_domain\""
  44. echo
  45. } >> $UNBOUND_CONFFILE
  46. fi
  47. }
  48. ##############################################################################
  49. dnsmasq_local_arpa() {
  50. local cfg="$1"
  51. local logint dhcpv4 dhcpv6 ignore
  52. local subnets subnets4 subnets6
  53. local forward arpa
  54. local validip4 validip6 privateip
  55. config_get logint "$cfg" interface
  56. config_get dhcpv4 "$cfg" dhcpv4
  57. config_get dhcpv6 "$cfg" dhcpv6
  58. config_get_bool ignore "$cfg" ignore 0
  59. # Find the list of addresses assigned to a logical interface
  60. # Its typical to have a logical gateway split NAME and NAME6
  61. network_get_subnets subnets4 "$logint"
  62. network_get_subnets6 subnets6 "$logint"
  63. subnets="$subnets4 $subnets6"
  64. network_get_subnets subnets4 "${logint}6"
  65. network_get_subnets6 subnets6 "${logint}6"
  66. subnets="$subnets $subnets4 $subnets6"
  67. if [ -z "$subnets" ] ; then
  68. forward=""
  69. elif [ -z "$UNBOUND_N_FWD_PORTS" ] ; then
  70. forward=""
  71. elif [ "$ignore" -gt 0 ] ; then
  72. if [ "$UNBOUND_D_WAN_FQDN" -gt 0 ] ; then
  73. # Only forward the one gateway host.
  74. forward="host"
  75. else
  76. forward=""
  77. fi
  78. else
  79. # Forward the entire private subnet.
  80. forward="domain"
  81. fi
  82. if [ -n "$forward" ] ; then
  83. for subnet in $subnets ; do
  84. validip4=$( valid_subnet4 $subnet )
  85. validip6=$( valid_subnet6 $subnet )
  86. privateip=$( private_subnet $subnet )
  87. if [ "$validip4" = "ok" -a "$dhcpv4" != "disable" ] ; then
  88. if [ "$forward" = "domain" ] ; then
  89. arpa=$( domain_ptr_ip4 "$subnet" )
  90. else
  91. arpa=$( host_ptr_ip4 "$subnet" )
  92. fi
  93. elif [ "$validip6" = "ok" -a "$dhcpv6" != "disable" ] ; then
  94. if [ "$forward" = "domain" ] ; then
  95. arpa=$( domain_ptr_ip6 "$subnet" )
  96. else
  97. arpa=$( host_ptr_ip6 "$subnet" )
  98. fi
  99. else
  100. arpa=""
  101. fi
  102. if [ -n "$arpa" ] ; then
  103. if [ "$privateip" = "ok" ] ; then
  104. {
  105. # This creates ARPA local zone privledges
  106. echo " local-zone: \"$arpa.\" transparent"
  107. echo " domain-insecure: \"$arpa\""
  108. echo
  109. } >> $UNBOUND_CONFFILE
  110. fi
  111. UNBOUND_TXT_FWD_ZONE="$UNBOUND_TXT_FWD_ZONE $arpa"
  112. fi
  113. done
  114. fi
  115. }
  116. ##############################################################################
  117. dnsmasq_forward_zone() {
  118. if [ -n "$UNBOUND_N_FWD_PORTS" -a -n "$UNBOUND_TXT_FWD_ZONE" ] ; then
  119. for fwd_domain in $UNBOUND_TXT_FWD_ZONE ; do
  120. {
  121. # This is derived of dnsmasq_local_zone/arpa
  122. # but forward: clauses need to be seperate
  123. echo "forward-zone:"
  124. echo " name: \"$fwd_domain.\""
  125. for port in $UNBOUND_N_FWD_PORTS ; do
  126. echo " forward-addr: 127.0.0.1@$port"
  127. done
  128. echo
  129. } >> $UNBOUND_CONFFILE
  130. done
  131. fi
  132. }
  133. ##############################################################################
  134. dnsmasq_link() {
  135. # Forward to dnsmasq on same host for DHCP lease hosts
  136. echo " do-not-query-localhost: no" >> $UNBOUND_CONFFILE
  137. # Look at dnsmasq settings
  138. config_load dhcp
  139. # Zone for DHCP / SLAAC-PING DOMAIN
  140. config_foreach dnsmasq_local_zone dnsmasq
  141. # Zone for DHCP / SLAAC-PING ARPA
  142. config_foreach dnsmasq_local_arpa dhcp
  143. # Now create ALL seperate forward: clauses
  144. dnsmasq_forward_zone
  145. }
  146. ##############################################################################