| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574 |
- --
- -- Copyright (C) 2018-2020 Ruilin Peng (Nick) <[email protected]>.
- --
- -- smartdns is free software: you can redistribute it and/or modify
- -- it under the terms of the GNU General Public License as published by
- -- the Free Software Foundation, either version 3 of the License, or
- -- (at your option) any later version.
- --
- -- smartdns is distributed in the hope that it will be useful,
- -- but WITHOUT ANY WARRANTY; without even the implied warranty of
- -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- -- GNU General Public License for more details.
- --
- -- You should have received a copy of the GNU General Public License
- -- along with this program. If not, see <http://www.gnu.org/licenses/>.
- require ("nixio.fs")
- require ("luci.http")
- require ("luci.dispatcher")
- require ("nixio.fs")
- local uci = require "luci.model.uci".cursor()
- m = Map("smartdns")
- m.title = translate("SmartDNS Server")
- m.description = translate("SmartDNS is a local high-performance DNS server, supports finding fastest IP, supports ad filtering, and supports avoiding DNS poisoning.")
- m:section(SimpleSection).template = "smartdns/smartdns_status"
- -- Basic
- s = m:section(TypedSection, "smartdns", translate("Settings"), translate("General Settings"))
- s.anonymous = true
- s:tab("settings", translate("General Settings"))
- s:tab("advanced", translate('Advanced Settings'))
- s:tab("seconddns", translate("Second Server Settings"))
- s:tab("custom", translate("Custom Settings"))
- ---- Eanble
- o = s:taboption("settings", Flag, "enabled", translate("Enable"), translate("Enable or disable smartdns server"))
- o.default = o.disabled
- o.rempty = false
- ---- server name
- o = s:taboption("settings", Value, "server_name", translate("Server Name"), translate("Smartdns server name"))
- o.default = "smartdns"
- o.datatype = "hostname"
- o.rempty = false
- ---- Port
- o = s:taboption("settings", Value, "port", translate("Local Port"),
- translate("Smartdns local server port, smartdns will be automatically set as main dns when the port is 53."))
- o.placeholder = 53
- o.default = 53
- o.datatype = "port"
- o.rempty = false
- ---- Enable TCP server
- o = s:taboption("settings", Flag, "tcp_server", translate("TCP Server"), translate("Enable TCP DNS Server"))
- o.rmempty = false
- o.default = o.enabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "1"
- end
- ---- Support IPV6
- o = s:taboption("settings", Flag, "ipv6_server", translate("IPV6 Server"), translate("Enable IPV6 DNS Server"))
- o.rmempty = false
- o.default = o.enabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "1"
- end
- ---- Support DualStack ip selection
- o = s:taboption("advanced", Flag, "dualstack_ip_selection", translate("Dual-stack IP Selection"), translate("Enable IP selection between IPV4 and IPV6"))
- o.rmempty = false
- o.default = o.enabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "0"
- end
- ---- Domain prefetch load
- o = s:taboption("advanced", Flag, "prefetch_domain", translate("Domain prefetch"), translate("Enable domain prefetch, accelerate domain response speed."))
- o.rmempty = false
- o.default = o.disabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "0"
- end
- ---- Domain Serve expired
- o = s:taboption("advanced", Flag, "serve_expired", translate("Serve expired"),
- translate("Attempts to serve old responses from cache with a TTL of 0 in the response without waiting for the actual resolution to finish."))
- o.rmempty = false
- o.default = o.enabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "0"
- end
- ---- cache-size
- o = s:taboption("advanced", Value, "cache_size", translate("Cache Size"), translate("DNS domain result cache size"))
- o.rempty = true
- -- cache-size
- o = s:taboption("advanced", Flag, "resolve_local_hostnames", translate("Resolve Local Hostnames"), translate("Resolve local hostnames by reading Dnsmasq lease file."))
- o.rmempty = false
- o.default = o.enabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "1"
- end
- -- Automatically Set Dnsmasq
- o = s:taboption("advanced", Flag, "auto_set_dnsmasq", translate("Automatically Set Dnsmasq"), translate("Automatically set as upstream of dnsmasq when port changes."))
- o.rmempty = false
- o.default = o.enabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "0"
- end
- -- Force AAAA SOA
- o = s:taboption("advanced", Flag, "force_aaaa_soa", translate("Force AAAA SOA"), translate("Force AAAA SOA."))
- o.rmempty = false
- o.default = o.enabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "0"
- end
- -- Force HTTPS SOA
- o = s:taboption("advanced", Flag, "force_https_soa", translate("Force HTTPS SOA"), translate("Force HTTPS SOA."))
- o.rmempty = false
- o.default = o.enabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "1"
- end
- ---- rr-ttl
- o = s:taboption("advanced", Value, "rr_ttl", translate("Domain TTL"), translate("TTL for all domain result."))
- o.rempty = true
- ---- rr-ttl-min
- o = s:taboption("advanced", Value, "rr_ttl_min", translate("Domain TTL Min"), translate("Minimum TTL for all domain result."))
- o.rempty = true
- o.placeholder = "600"
- o.default = 600
- o.optional = true
- ---- rr-ttl-max
- o = s:taboption("advanced", Value, "rr_ttl_max", translate("Domain TTL Max"), translate("Maximum TTL for all domain result."))
- o.rempty = true
- ---- rr-ttl-reply-max
- o = s:taboption("advanced", Value, "rr_ttl_reply_max", translate("Reply Domain TTL Max"), translate("Reply maximum TTL for all domain result."))
- o.rempty = true
- o = s:taboption("advanced", DynamicList, "conf_files", translate("Include Config Files<br>/etc/smartdns/conf.d"),
- translate("Include other config files from /etc/smartdns/conf.d or custom path, can be downloaded from the download page."));
- uci:foreach("smartdns", "download-file", function(section)
- local filetype = section.type
- if (filetype ~= 'config') then
- return
- end
- o:value(section.name);
- end)
- ---- second dns server
- ---- Eanble
- o = s:taboption("seconddns", Flag, "seconddns_enabled", translate("Enable"), translate("Enable or disable second DNS server."))
- o.default = o.disabled
- o.rempty = false
- ---- Port
- o = s:taboption("seconddns", Value, "seconddns_port", translate("Local Port"), translate("Smartdns local server port"))
- o.placeholder = 6553
- o.default = 6553
- o.datatype = "port"
- o.rempty = false
- ---- Enable TCP server
- o = s:taboption("seconddns", Flag, "seconddns_tcp_server", translate("TCP Server"), translate("Enable TCP DNS Server"))
- o.rmempty = false
- o.default = o.enabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "1"
- end
- ---- dns server group
- o = s:taboption("seconddns", Value, "seconddns_server_group", translate("Server Group"), translate("Query DNS through specific dns server group, such as office, home."))
- o.rmempty = true
- o.placeholder = "default"
- o.datatype = "hostname"
- o.rempty = true
- o = s:taboption("seconddns", Flag, "seconddns_no_speed_check", translate("Skip Speed Check"), translate("Do not check speed."))
- o.rmempty = false
- o.default = o.disabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "0"
- end
- ---- skip address rules
- o = s:taboption("seconddns", Flag, "seconddns_no_rule_addr", translate("Skip Address Rules"), translate("Skip address rules."))
- o.rmempty = false
- o.default = o.disabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "0"
- end
- ---- skip name server rules
- o = s:taboption("seconddns", Flag, "seconddns_no_rule_nameserver", translate("Skip Nameserver Rule"), translate("Skip nameserver rules."))
- o.rmempty = false
- o.default = o.disabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "0"
- end
- ---- skip ipset rules
- o = s:taboption("seconddns", Flag, "seconddns_no_rule_ipset", translate("Skip Ipset Rule"), translate("Skip ipset rules."))
- o.rmempty = false
- o.default = o.disabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "0"
- end
- ---- skip soa address rule
- o = s:taboption("seconddns", Flag, "seconddns_no_rule_soa", translate("Skip SOA Address Rule"), translate("Skip SOA address rules."))
- o.rmempty = false
- o.default = o.disabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "0"
- end
- o = s:taboption("seconddns", Flag, "seconddns_no_dualstack_selection", translate("Skip Dualstack Selection"), translate("Skip Dualstack Selection."))
- o.rmempty = false
- o.default = o.disabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "0"
- end
- ---- skip cache
- o = s:taboption("seconddns", Flag, "seconddns_no_cache", translate("Skip Cache"), translate("Skip Cache."))
- o.rmempty = false
- o.default = o.disabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "0"
- end
- ---- Force AAAA SOA
- o = s:taboption("seconddns", Flag, "seconddns_force_aaaa_soa", translate("Force AAAA SOA"), translate("Force AAAA SOA."))
- o.rmempty = false
- o.default = o.disabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "0"
- end
- ----- custom settings
- custom = s:taboption("custom", Value, "Custom Settings",
- translate(""),
- translate("smartdns custom settings"))
- custom.template = "cbi/tvalue"
- custom.rows = 20
- function custom.cfgvalue(self, section)
- return nixio.fs.readfile("/etc/smartdns/custom.conf")
- end
- function custom.write(self, section, value)
- value = value:gsub("\r\n?", "\n")
- nixio.fs.writefile("/etc/smartdns/custom.conf", value)
- end
- o = s:taboption("custom", Flag, "coredump", translate("Generate Coredump"), translate("Generate Coredump file when smartdns crash, coredump file is located at /tmp/smartdns.xxx.core."))
- o.rmempty = false
- o.default = o.disabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "0"
- end
- -- Upstream servers
- s = m:section(TypedSection, "server", translate("Upstream Servers"), translate("Upstream Servers, support UDP, TCP protocol. " ..
- "Please configure multiple DNS servers, including multiple foreign DNS servers."))
-
- s.anonymous = true
- s.addremove = true
- s.template = "cbi/tblsection"
- s.extedit = luci.dispatcher.build_url("admin/services/smartdns/upstream/%s")
- ---- enable flag
- o = s:option(Flag, "enabled", translate("Enable"), translate("Enable"))
- o.rmempty = false
- o.default = o.enabled
- o.cfgvalue = function(...)
- return Flag.cfgvalue(...) or "1"
- end
- ---- name
- s:option(Value, "name", translate("DNS Server Name"), translate("DNS Server Name"))
- ---- IP address
- o = s:option(Value, "ip", translate("ip"), translate("DNS Server ip"))
- o.datatype = "or(ipaddr, string)"
- o.rmempty = false
- ---- port
- o = s:option(Value, "port", translate("port"), translate("DNS Server port"))
- o.placeholder = "default"
- o.datatype = "port"
- o.rempty = true
- o:depends("type", "udp")
- o:depends("type", "tcp")
- o:depends("type", "tls")
- ---- type
- o = s:option(ListValue, "type", translate("type"), translate("DNS Server type"))
- o.placeholder = "udp"
- o:value("udp", translate("udp"))
- o:value("tcp", translate("tcp"))
- o:value("tls", translate("tls"))
- o:value("https", translate("https"))
- o.default = "udp"
- o.rempty = false
- ---- domain rules;
- s = m:section(TypedSection, "domain-rule", translate("Domain Rules"), translate("Domain Rules Settings"))
- s.anonymous = true
- s.nodescriptions = true
- s:tab("forwarding", translate('DNS Forwarding Setting'))
- s:tab("block", translate("DNS Block Setting"))
- s:tab("domain-address", translate("Domain Address"), translate("Set Specific domain ip address."))
- s:tab("blackip-list", translate("IP Blacklist"), translate("Set Specific ip blacklist."))
- ---- domain forwarding;
- o = s:taboption("forwarding", Value, "server_group", translate("Server Group"), translate("DNS Server group belongs to, such as office, home."))
- o.rmempty = true
- o.placeholder = "default"
- o.datatype = "hostname"
- o.rempty = true
- uci:foreach("smartdns", "server", function(section)
- local server_group = section.server_group
- o:value(server_group);
- end)
- function o.validate (section_id, value)
- if (value == "") then
- return value
- end
- local exists = false
- uci:foreach("smartdns", "server", function(section)
- local server_group = section.server_group
- if (exists == true) then
- return
- end
- if (value == server_group) then
- exists = true
- end
- end)
- if (exists == false) then
- return nil, translate('Server Group not exists')
- end
- return value;
- end
- o = s:taboption("forwarding", Flag, "no_speed_check", translate("Skip Speed Check"),
- translate("Do not check speed."))
- o.rmempty = false
- o.default = o.disabled
- o = s:taboption("forwarding", Flag, "force_aaaa_soa", translate("Force AAAA SOA"), translate("Force AAAA SOA."))
- o.rmempty = false
- o.default = o.disabled
- o = s:taboption("forwarding", Value, "ipset_name", translate("IPset Name"), translate("IPset name."))
- o.rmempty = true
- o.datatype = "hostname"
- o.rempty = true
- o = s:taboption("forwarding", Value, "nftset_name", translate("NFTset Name"), translate("NFTset name, format: [#[4|6]:[family#table#set]]"))
- o.rmempty = true
- o.datatype = "string"
- o.rempty = true
- function o.validate(self, value)
- if (value == "") then
- return value
- end
- if (value:match("#[4|6]:[a-zA-Z0-9%-_]+#[a-zA-Z0-9%-_]+#[a-zA-Z0-9%-_]+$")) then
- return value
- end
- return nil, translate("NFTset name format error, format: [#[4|6]:[family#table#set]]")
- end
- o = s:taboption("forwarding", FileUpload, "forwarding_domain_set_file", translate("Domain List File"),
- translate("Upload domain list file, or configure auto download from Download File Setting page."))
- o.rmempty = true
- o.datatype = "file"
- o.rempty = true
- o.editable = true
- o.root_directory = "/etc/smartdns/domain-set"
- o = s:taboption("forwarding", TextValue, "domain_forwarding_list",
- translate("Domain List"), translate("Configure forwarding domain name list."))
- o.rows = 10
- o.cols = 64
- o.monospace = true
- function o.cfgvalue(self, section)
- return nixio.fs.readfile("/etc/smartdns/domain-forwarding.list")
- end
- function o.write(self, section, value)
- value = value:gsub("\r\n?", "\n")
- nixio.fs.writefile("/etc/smartdns/domain-forwarding.list", value)
- end
- ---- domain block;
- o = s:taboption("block", FileUpload, "block_domain_set_file", translate("Domain List File"), translate("Upload domain list file."))
- o.rmempty = true
- o.datatype = "file"
- o.rempty = true
- o.editable = true
- o.root_directory = "/etc/smartdns/domain-set"
- o = s:taboption("block", TextValue, "domain_block_list",
- translate("Domain List"), translate("Configure block domain list."))
- o.rows = 10
- o.cols = 64
- function o.cfgvalue(self, section)
- return nixio.fs.readfile("/etc/smartdns/domain-block.list")
- end
- function o.write(self, section, value)
- value = value:gsub("\r\n?", "\n")
- nixio.fs.writefile("/etc/smartdns/domain-block.list", value)
- end
- -- Doman addresss
- addr = s:taboption("domain-address", Value, "address",
- translate(""),
- translate("Specify an IP address to return for any host in the given domains, Queries in the domains are never forwarded and always replied to with the specified IP address which may be IPv4 or IPv6."))
- addr.template = "cbi/tvalue"
- addr.rows = 20
- function addr.cfgvalue(self, section)
- return nixio.fs.readfile("/etc/smartdns/address.conf")
- end
- function addr.write(self, section, value)
- value = value:gsub("\r\n?", "\n")
- nixio.fs.writefile("/etc/smartdns/address.conf", value)
- end
- -- IP Blacklist
- addr = s:taboption("blackip-list", Value, "blacklist_ip",
- translate(""),
- translate("Configure IP blacklists that will be filtered from the results of specific DNS server."))
- addr.template = "cbi/tvalue"
- addr.rows = 20
- function addr.cfgvalue(self, section)
- return nixio.fs.readfile("/etc/smartdns/blacklist-ip.conf")
- end
- function addr.write(self, section, value)
- value = value:gsub("\r\n?", "\n")
- nixio.fs.writefile("/etc/smartdns/blacklist-ip.conf", value)
- end
- s = m:section(TypedSection, "smartdns", translate("Download Files Setting"), translate("Download domain list files for domain-rule and include config files, please refresh the page after download to take effect."))
- s.anonymous = true
- ---- download Files Settings
- o = s:option(Flag, "enable_auto_update", translate("Enable Auto Update"), translate("Enable daily auto update."))
- o.rmempty = false
- o.default = o.disabled
- o.rempty = true
- o = s:option(FileUpload, "upload_conf_file", translate("Upload Config File"),
- translate("Upload smartdns config file to /etc/smartdns/conf.d"))
- o.rmempty = true
- o.datatype = "file"
- o.rempty = true
- o.editable = true
- o.root_directory = "/etc/smartdns/conf.d"
- o = s:option(FileUpload, "upload_list_file", translate("Upload Domain List File"),
- translate("Upload domain list file to /etc/smartdns/domain-set"))
- o.rmempty = true
- o.datatype = "file"
- o.rempty = true
- o.editable = true
- o.root_directory = "/etc/smartdns/domain-set"
- o = s:option(Button, "_updateate")
- o.title = translate("Update Files")
- o.inputtitle = translate("update domain list files")
- o.inputstyle = "apply"
- o.write = function()
- luci.sys.call("/etc/init.d/smartdns updatefiles >/dev/null 2>&1")
- end
- s = m:section(TypedSection, "download-file", translate("Download Files"), translate("List of files to download."))
- s.anonymous = true
- s.addremove = true
- s.template = "cbi/tblsection"
- o = s:option(Value, 'name', translate('File Name'), translate('File Name'))
- o.rmempty = false
- o.datatype = 'string'
- o = s:option(Value, 'url', translate('URL'), translate('URL'))
- o.rmempty = false
- o.datatype = 'string'
- function o.validate(self, value, section)
- if value == "" then
- return nil
- end
- if value.find(value, "http://") then
- return value
- end
- if value.find(value, "https://") then
- return value
- end
- return nil, translate("URL format error, format: http:// or https://")
- end
- o = s:option(ListValue, "type", translate("type"), translate("File Type"))
- o:value("list", translate("domain list (/etc/smartdns/domain-set)"))
- o:value("config", translate("smartdns config (/etc/smartdns/conf.d)"))
- o.default = "list"
- o.rempty = false
- o = s:option(Value, 'desc', translate('Description'), translate('Description'))
- o.rmempty = true
- o.datatype = 'string'
- -- Technical Support
- s = m:section(TypedSection, "smartdns", translate("Technical Support"),
- translate("If you like this software, please buy me a cup of coffee."))
- s.anonymous = true
- o = s:option(Button, "web")
- o.title = translate("SmartDNS official website")
- o.inputtitle = translate("open website")
- o.inputstyle = "apply"
- o.write = function()
- luci.http.redirect("https://pymumu.github.io/smartdns")
- end
- o = s:option(Button, "Donate")
- o.title = translate("Donate to smartdns")
- o.inputtitle = translate("Donate")
- o.inputstyle = "apply"
- o.write = function()
- luci.http.redirect("https://pymumu.github.io/smartdns/#donate")
- end
- o = s:option(Button, "Restart")
- o.title = translate("Restart smartdns")
- o.inputtitle = translate("Restart")
- o.inputstyle = "apply"
- o.write = function()
- luci.sys.call("/etc/init.d/smartdns restart >/dev/null 2>&1")
- end
- return m
|