overview_tab.lua 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. -- Copyright 2017 Dirk Brenken (dev@brenken.org)
  2. -- This is free software, licensed under the Apache License, Version 2.0
  3. local fs = require("nixio.fs")
  4. local uci = require("luci.model.uci").cursor()
  5. local util = require("luci.util")
  6. local date = require("luci.http.protocol.date")
  7. local res_input = "/usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv"
  8. local dump = util.ubus("network.interface", "dump", {})
  9. local plug_cnt = tonumber(luci.sys.exec("env -i /usr/sbin/dnscrypt-proxy --version | grep 'Support for plugins: present' | wc -l"))
  10. local res_list = {}
  11. local url = "https://download.dnscrypt.org/dnscrypt-proxy/dnscrypt-resolvers.csv"
  12. if not fs.access(res_input) then
  13. if not fs.access("/lib/libustream-ssl.so") then
  14. m = SimpleForm("error", nil, translate("No default resolver list and no SSL support available.<br />")
  15. .. translate("Please install a resolver list to '/usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv' to use this package."))
  16. m.submit = false
  17. m.reset = false
  18. return m
  19. else
  20. luci.sys.call("env -i /bin/uclient-fetch --no-check-certificate -O " .. res_input .. " " .. url .. " >/dev/null 2>&1")
  21. end
  22. end
  23. if not uci:get_first("dnscrypt-proxy", "global") then
  24. uci:add("dnscrypt-proxy", "global")
  25. uci:save("dnscrypt-proxy")
  26. uci:commit("dnscrypt-proxy")
  27. end
  28. for line in io.lines(res_input) do
  29. local name,
  30. location,
  31. dnssec,
  32. nolog = line:match("^([^,]+),.-,\".-\",\"*(.-)\"*,.-,[0-9],\"*([yesno]+)\"*,\"*([yesno]+)\"*,.*")
  33. if name ~= "" and name ~= "Name" then
  34. if location == "" then
  35. location = "-"
  36. end
  37. if dnssec == "" then
  38. dnssec = "-"
  39. end
  40. if nolog == "" then
  41. nolog = "-"
  42. end
  43. res_list[#res_list + 1] = { name = name, location = location, dnssec = dnssec, nolog = nolog }
  44. end
  45. end
  46. m = Map("dnscrypt-proxy", translate("DNSCrypt-Proxy"),
  47. translate("Configuration of the DNSCrypt-Proxy package. ")
  48. .. translatef("For further information "
  49. .. "<a href=\"%s\" target=\"_blank\">"
  50. .. "see the wiki online</a>", "https://wiki.openwrt.org/inbox/dnscrypt"))
  51. m:chain("dhcp")
  52. function m.on_after_commit(self)
  53. function d1.validate(self, value, s1)
  54. if value == "1" then
  55. uci:commit("dnscrypt-proxy")
  56. uci:set("dhcp", s1, "noresolv", 1)
  57. if not fs.access("/etc/resolv-crypt.conf") or nixio.fs.stat("/etc/resolv-crypt.conf").size == 0 then
  58. uci:set("dhcp", s1, "resolvfile", "/tmp/resolv.conf.auto")
  59. else
  60. uci:set("dhcp", s1, "resolvfile", "/etc/resolv-crypt.conf")
  61. end
  62. local server_list = {}
  63. local cnt = 1
  64. uci:foreach("dnscrypt-proxy", "dnscrypt-proxy", function(s)
  65. server_list[cnt] = s['address'] .. "#" .. s['port']
  66. cnt = cnt + 1
  67. end)
  68. server_list[cnt] = "/pool.ntp.org/8.8.8.8"
  69. uci:set_list("dhcp", s1, "server", server_list)
  70. if cnt > 2 then
  71. uci:set("dhcp", s1, "allservers", 1)
  72. else
  73. uci:set("dhcp", s1, "allservers", 0)
  74. end
  75. uci:save("dhcp")
  76. uci:commit("dhcp")
  77. end
  78. return value
  79. end
  80. luci.sys.call("env -i /etc/init.d/dnscrypt-proxy restart >/dev/null 2>&1")
  81. luci.sys.call("env -i /etc/init.d/dnsmasq restart >/dev/null 2>&1")
  82. end
  83. s = m:section(TypedSection, "global", translate("General Options"))
  84. s.anonymous = true
  85. -- Main dnscrypt-proxy resource list
  86. o1 = s:option(DummyValue, "", translate("Default Resolver List"))
  87. o1.template = "dnscrypt-proxy/res_options"
  88. o1.value = res_input
  89. o2 = s:option(DummyValue, "", translate("File Date"))
  90. o2.template = "dnscrypt-proxy/res_options"
  91. o2.value = date.to_http(nixio.fs.stat(res_input).mtime)
  92. o3 = s:option(DummyValue, "", translate("File Checksum"))
  93. o3.template = "dnscrypt-proxy/res_options"
  94. o3.value = luci.sys.exec("sha256sum " .. res_input .. " | awk '{print $1}'")
  95. if fs.access("/lib/libustream-ssl.so") then
  96. btn1 = s:option(Button, "", translate("Refresh Resolver List"),
  97. translate("Download the current resolver list from 'download.dnscrypt.org'."))
  98. btn1.inputtitle = translate("Refresh List")
  99. btn1.inputstyle = "apply"
  100. btn1.disabled = false
  101. function btn1.write()
  102. luci.sys.call("env -i /bin/uclient-fetch --no-check-certificate -O " .. res_input .. " " .. url .. " >/dev/null 2>&1")
  103. luci.http.redirect(luci.dispatcher.build_url("admin", "services", "dnscrypt-proxy"))
  104. end
  105. else
  106. btn1 = s:option(Button, "", translate("Refresh Resolver List"),
  107. translate("No SSL support available.<br />")
  108. .. translate("Please install a 'libustream-ssl' library to download the current resolver list from 'download.dnscrypt.org'."))
  109. btn1.inputtitle = translate("-------")
  110. btn1.inputstyle = "button"
  111. btn1.disabled = true
  112. end
  113. if not fs.access("/etc/resolv-crypt.conf") or nixio.fs.stat("/etc/resolv-crypt.conf").size == 0 then
  114. btn2 = s:option(Button, "", translate("Create Custom Config File"),
  115. translate("Create '/etc/resolv-crypt.conf' with 'options timeout:1' to reduce DNS upstream timeouts with multiple DNSCrypt instances.<br />")
  116. .. translatef("For further information "
  117. .. "<a href=\"%s\" target=\"_blank\">"
  118. .. "see the wiki online</a>", "https://wiki.openwrt.org/inbox/dnscrypt"))
  119. btn2.inputtitle = translate("Create Config File")
  120. btn2.inputstyle = "apply"
  121. btn2.disabled = false
  122. function btn2.write()
  123. luci.sys.call("env -i echo 'options timeout:1' > '/etc/resolv-crypt.conf'")
  124. luci.http.redirect(luci.dispatcher.build_url("admin", "services", "dnscrypt-proxy"))
  125. end
  126. else
  127. btn2 = s:option(Button, "", translate("Create Custom Config File"),
  128. translate("The config file '/etc/resolv-crypt.conf' already exist.<br />")
  129. .. translate("Please edit the file manually in the 'Advanced' section."))
  130. btn2.inputtitle = translate("-------")
  131. btn2.inputstyle = "button"
  132. btn2.disabled = true
  133. end
  134. -- Trigger settings
  135. t = s:option(ListValue, "procd_trigger", translate("Startup Trigger"),
  136. translate("By default the DNSCrypt-Proxy startup will be triggered by ifup events of 'All' available network interfaces.<br />")
  137. .. translate("To restrict the trigger, select only the relevant network interface. Usually the 'wan' interface should work for most users."))
  138. t:value("", "All")
  139. if dump then
  140. local i, v
  141. for i, v in ipairs(dump.interface) do
  142. if v.interface ~= "loopback" then
  143. t:value(v.interface)
  144. end
  145. end
  146. end
  147. t.default = procd_trigger or "All"
  148. t.rmempty = true
  149. -- Mandatory options per instance
  150. s = m:section(TypedSection, "dnscrypt-proxy", translate("Instance Options"))
  151. s.anonymous = true
  152. s.addremove = true
  153. i1 = s:option(Value, "address", translate("IP Address"),
  154. translate("The local IPv4 or IPv6 address. The latter one should be specified within brackets, e.g. '[::1]'."))
  155. i1.default = address or "127.0.0.1"
  156. i1.rmempty = false
  157. i2 = s:option(Value, "port", translate("Port"),
  158. translate("The listening port for DNS queries."))
  159. i2.datatype = "port"
  160. i2.default = port
  161. i2.rmempty = false
  162. i3 = s:option(ListValue, "resolver", translate("Resolver (LOC/SEC/NOLOG)"),
  163. translate("Name of the remote DNS service for resolving queries incl. Location, DNSSEC- and NOLOG-Flag."))
  164. i3.datatype = "hostname"
  165. i3.widget = "select"
  166. local i, v
  167. for i, v in ipairs(res_list) do
  168. if v.name then
  169. i3:value(v.name, v.name .. " (" .. v.location .. "/" .. v.dnssec .. "/" .. v.nolog .. ")")
  170. end
  171. end
  172. i3.default = resolver
  173. i3.rmempty = false
  174. -- Extra options per instance
  175. e1 = s:option(Value, "resolvers_list", translate("Alternate Resolver List"),
  176. translate("Specify a non-default Resolver List."))
  177. e1.datatype = "file"
  178. e1.optional = true
  179. e2 = s:option(Value, "ephemeral_keys", translate("Ephemeral Keys"),
  180. translate("Improve privacy by using an ephemeral public key for each query. ")
  181. .. translate("This option requires extra CPU cycles and is useless with most DNSCrypt server."))
  182. e2.datatype = "bool"
  183. e2.value = 1
  184. e2.optional = true
  185. if plug_cnt > 0 then
  186. e3 = s:option(DynamicList, "blacklist", translate("Blacklist"),
  187. translate("Local blacklists allow you to block abuse sites by domains or ip addresses. ")
  188. .. translate("The value for this property is the blocklist type and path to the file, e.g.'domains:/path/to/dbl.txt' or 'ips:/path/to/ipbl.txt'."))
  189. e3.optional = true
  190. e4 = s:option(Value, "block_ipv6", translate("Block IPv6"),
  191. translate("Disable IPv6 to speed up DNSCrypt-Proxy."))
  192. e4.datatype = "bool"
  193. e4.value = 1
  194. e4.optional = true
  195. e5 = s:option(Value, "local_cache", translate("Local Cache"),
  196. translate("Enable Caching to speed up DNSCcrypt-Proxy."))
  197. e5.datatype = "bool"
  198. e5.value = 1
  199. e5.optional = true
  200. e6 = s:option(Value, "query_log_file", translate("DNS Query Logfile"),
  201. translate("Log the received DNS queries to a file, so you can watch in real-time what is happening on the network."))
  202. e6.optional = true
  203. end
  204. -- Dnsmasq options
  205. m1 = Map("dhcp")
  206. s1 = m1:section(TypedSection, "dnsmasq", translate("Dnsmasq Options"))
  207. s1.anonymous = true
  208. d1 = s1:option(Flag, "", translate("Transfer Options To Dnsmasq"),
  209. translate("Apply DNSCrypt-Proxy specific settings to the Dnsmasq configuration.<br />")
  210. .. translate("Please note: This may change the values for 'noresolv', 'resolvfile', 'allservers' and the list 'server' settings."))
  211. d1.default = d1.enabled
  212. d1.rmempty = false
  213. return m, m1