luci-app-dnscrypt-proxy: small fixes & additions
[project/luci.git] / applications / luci-app-dnscrypt-proxy / luasrc / model / cbi / dnscrypt-proxy / overview_tab.lua
1 -- Copyright 2017 Dirk Brenken (dev@brenken.org)
2 -- This is free software, licensed under the Apache License, Version 2.0
3
4 local fs        = require("nixio.fs")
5 local uci       = require("luci.model.uci").cursor()
6 local util      = require("luci.util")
7 local date      = require("luci.http.protocol.date")
8 local res_input = "/usr/share/dnscrypt-proxy/dnscrypt-resolvers.csv"
9 local dump      = util.ubus("network.interface", "dump", {})
10 local plug_cnt  = tonumber(luci.sys.exec("env -i /usr/sbin/dnscrypt-proxy --version | grep 'Support for plugins: present' | wc -l"))
11 local res_list  = {}
12 local url       = "https://download.dnscrypt.org/dnscrypt-proxy/dnscrypt-resolvers.csv"
13
14 if not fs.access("/lib/libustream-ssl.so") then
15         m = SimpleForm("error", nil, translate("SSL support not available, please install an libustream-ssl variant to use this package."))
16         m.submit = false
17         m.reset = false
18         return m
19 end
20
21 if not fs.access(res_input) then
22         luci.sys.call("env -i /bin/uclient-fetch --no-check-certificate -O " .. res_input .. " " .. url .. " >/dev/null 2>&1")
23 end
24
25 if not uci:get_first("dnscrypt-proxy", "global") then
26         uci:add("dnscrypt-proxy", "global")
27         uci:save("dnscrypt-proxy")
28         uci:commit("dnscrypt-proxy")
29 end
30
31 for line in io.lines(res_input) do
32         local name = line:match("^[%w_.-]*")
33         res_list[#res_list + 1] = { name = name }
34 end
35
36 m = Map("dnscrypt-proxy", translate("DNSCrypt-Proxy"),
37         translate("Configuration of the DNSCrypt-Proxy package. ")
38         .. translate("Keep in mind to configure Dnsmasq as well. ")
39         .. translatef("For further information "
40         .. "<a href=\"%s\" target=\"_blank\">"
41         .. "see the wiki online</a>", "https://wiki.openwrt.org/inbox/dnscrypt"))
42
43 function m.on_after_commit(self)
44         luci.sys.call("env -i /etc/init.d/dnsmasq restart >/dev/null 2>&1")
45         luci.sys.call("env -i /etc/init.d/dnscrypt-proxy restart >/dev/null 2>&1")
46 end
47
48 s = m:section(TypedSection, "global", translate("General options"))
49 s.anonymous = true
50
51 -- Main dnscrypt-proxy resource list
52
53 o1 = s:option(DummyValue, "", translate("Default Resolver List"))
54 o1.template = "dnscrypt-proxy/res_options"
55 o1.value = res_input
56
57 o2 = s:option(DummyValue, "", translate("File Date"))
58 o2.template = "dnscrypt-proxy/res_options"
59 o2.value = date.to_http(nixio.fs.stat(res_input).mtime)
60
61 o3 = s:option(DummyValue, "", translate("File Checksum"))
62 o3.template = "dnscrypt-proxy/res_options"
63 o3.value = luci.sys.exec("sha256sum " .. res_input .. " | awk '{print $1}'")
64
65 btn = s:option(Button, "", translate("Refresh Resolver List"))
66 btn.inputtitle = translate("Refresh List")
67 btn.inputstyle = "apply"
68 btn.disabled = false
69 function btn.write(self, section, value)
70         luci.sys.call("env -i /bin/uclient-fetch --no-check-certificate -O " .. res_input .. " " .. url .. " >/dev/null 2>&1")
71         luci.http.redirect(luci.dispatcher.build_url("admin", "services", "dnscrypt-proxy"))
72 end
73
74 -- Trigger settings
75
76 t = s:option(DynamicList, "procd_trigger", translate("Startup Trigger"),
77         translate("By default the DNSCrypt-Proxy startup will be triggered by ifup events of multiple network interfaces. ")
78         .. translate("To restrict the trigger, add only the relevant network interface(s). ")
79         .. translate("Usually the 'wan' interface should work for most users."))
80 if dump then
81         local i, v
82         for i, v in ipairs(dump.interface) do
83                 if v.interface ~= "loopback" then
84                         t:value(v.interface)
85                 end
86         end
87 end
88 t.rmempty = true
89
90 -- Extra options
91
92 ds = s:option(DummyValue, "_dummy", translate("Extra options"),
93         translate("Options for further tweaking in case the defaults are not suitable for you."))
94 ds.template = "cbi/nullsection"
95
96 btn = s:option(Button, "", translate("Create custom config file"),
97         translate("Create '/etc/resolv-crypt.conf' with 'options timeout:1' to reduce DNS upstream timeouts with multiple DNSCrypt instances. ")
98         .. translatef("For further information "
99         .. "<a href=\"%s\" target=\"_blank\">"
100         .. "see the wiki online</a>", "https://wiki.openwrt.org/inbox/dnscrypt"))
101 btn.inputtitle = translate("Create Config File")
102 btn.inputstyle = "apply"
103 btn.disabled = false
104 function btn.write(self, section, value)
105         if not fs.access("/etc/resolv-crypt.conf") then
106                 luci.sys.call("env -i echo 'options timeout:1' > '/etc/resolv-crypt.conf'")
107         end
108 end
109
110 -- Mandatory options per instance
111
112 s = m:section(TypedSection, "dnscrypt-proxy", translate("Instance options"))
113 s.anonymous = true
114 s.addremove = true
115
116 o1 = s:option(Value, "address", translate("IP Address"),
117         translate("The local IPv4 or IPv6 address. The latter one should be specified within brackets, e.g. '[::1]'."))
118 o1.default = address or "127.0.0.1"
119 o1.rmempty = false
120
121 o2 = s:option(Value, "port", translate("Port"),
122         translate("The listening port for DNS queries."))
123 o2.datatype = "port"
124 o2.default = port
125 o2.rmempty = false
126
127 o3 = s:option(ListValue, "resolver", translate("Resolver"),
128         translate("Name of the remote DNS service for resolving queries."))
129 o3.datatype = "hostname"
130 o3.widget = "select"
131 local i, v
132 for i, v in ipairs(res_list) do
133         if v.name ~= "Name" then
134                 o3:value(v.name)
135         end
136 end
137 o3.default = resolver
138 o3.rmempty = false
139
140 -- Extra options per instance
141
142 e1 = s:option(Value, "resolvers_list", translate("Alternate Resolver List"),
143         translate("Specify a non-default Resolver List."))
144 e1.datatype = "file"
145 e1.optional = true
146
147 e2 = s:option(Value, "ephemeral_keys", translate("Ephemeral Keys"),
148         translate("Improve privacy by using an ephemeral public key for each query. ")
149         .. translate("This option requires extra CPU cycles and is useless with most DNSCrypt server."))
150 e2.datatype = "bool"
151 e2.value = 1
152 e2.optional = true
153
154 if plug_cnt > 0 then
155         e3 = s:option(DynamicList, "blacklist", translate("Blacklist"),
156                 translate("Local blacklists allow you to block abuse sites by domains or ip addresses. ")
157                 .. 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'."))
158         e3.optional = true
159
160         e4 = s:option(Value, "block_ipv6", translate("Block IPv6"),
161                 translate("Disable IPv6 to speed up DNSCrypt-Proxy."))
162         e4.datatype = "bool"
163         e4.value = 1
164         e4.optional = true
165
166         e5 = s:option(Value, "local_cache", translate("Local Cache"),
167                 translate("Enable Caching to speed up DNSCcrypt-Proxy."))
168         e5.datatype = "bool"
169         e5.value = 1
170         e5.optional = true
171         
172         e6 = s:option(Value, "query_log_file", translate("DNS Query Logfile"),
173         translate("Log the received DNS queries to a file, so you can watch in real-time what is happening on the network."))
174         e6.optional = true
175 end
176
177 return m