diff --git a/Makefile b/Makefile index 60924fd..878fbf7 100644 --- a/Makefile +++ b/Makefile @@ -6,12 +6,12 @@ include $(TOPDIR)/rules.mk PKG_LICENSE:=GPL-3.0-or-later PKG_MAINTAINER:=Nick Peng -PKG_VERSION:=1.2019.28 +PKG_VERSION:=1.2020.30 PKG_RELEASE:=1 LUCI_TITLE:=LuCI for smartdns LUCI_DESCRIPTION:=Provides Luci for smartdns -LUCI_DEPENDS:=+luci-compat +smartdns +LUCI_DEPENDS:=+smartdns LUCI_PKGARCH:=all define Package/$(PKG_NAME)/config diff --git a/ReadMe.md b/ReadMe.md new file mode 100644 index 0000000..b94a900 --- /dev/null +++ b/ReadMe.md @@ -0,0 +1,97 @@ +# luci-app-smartdns + +此仓库为smartdns独立仓库,为单独编译使用, 在安装此界面前,需要先安装smartdns进程编译脚本。 +请先安装[openwrt-smartdns](https://github.com/pymumu/openwrt-smartdns) + +仓库分为两个分支 + +1. master分支为openwrt 19.07之后版本使用,此版本基于javascript。 +2. lede分支为lede分支使用, 此版本基于lua。 + +使用时,请使用配套的版本。 + +## 使用方式 + +如下命令操作路径为openwrt源代码所在目录。 + +### 复制仓库中的文件到如下目录,并执行安装 + +```shell +feeds/luci/applications/luci-app-smartdns/ +./scripts/feeds install luci -a +``` + +> lede请下载lede分支 + +### 执行openwrt配置, 选中luci-app-smartdns + +* 选择路径: + +LuCI > 3. Applications > luci-app-smartdns + +```shell +make menuconfig +``` + +* 编译模式: + +1. 若编译独立软件包,选择编译模式为`M` +1. 若编译到固件中,选择编译模式为`*` + +### 执行openwrt编译 + +仅编译软件包: + +```shell +make package/feeds/luci/applications/luci-app-smartdns/compile +``` + +编译固件以及软件包。 + +```shell +make -j8 +``` + +## 懒人脚本 + +可执行如下命令,一次性下载smartdns以及luci-app-smartdns。 +下列命令可采用复制粘贴的方式执行。 + +注意事项: + +1. 执行下列命令时,需要确保当前路径为openwrt代码路径。 +1. 确保执行过./scripts/feeds进行更新。 +1. 若是LEDE,请更换`LUCIBRANCH`变量为 + +```shell +LUCIBRANCH="lede" +``` + +批量命令: + +```shell +LUCIBRANCH="master" +WORKINGDIR="`pwd`/feeds/packages/net/smartdns" +mkdir $WORKINGDIR -p +rm $WORKINGDIR/* -fr +wget https://github.com/pymumu/openwrt-smartdns/archive/master.zip -O $WORKINGDIR/master.zip +unzip $WORKINGDIR/master.zip -d $WORKINGDIR +mv $WORKINGDIR/openwrt-smartdns-master/* $WORKINGDIR/ +rmdir $WORKINGDIR/openwrt-smartdns-master +rm $WORKINGDIR/master.zip + +WORKINGDIR="`pwd`/feeds/luci/applications/luci-app-smartdns" +mkdir $WORKINGDIR -p +rm $WORKINGDIR/* -fr +wget https://github.com/pymumu/luci-app-smartdns/archive/${LUCIBRANCH}.zip -O $WORKINGDIR/${LUCIBRANCH}.zip +unzip $WORKINGDIR/${LUCIBRANCH}.zip -d $WORKINGDIR +mv $WORKINGDIR/luci-app-smartdns-${LUCIBRANCH}/* $WORKINGDIR/ +rmdir $WORKINGDIR/luci-app-smartdns-${LUCIBRANCH} +rm $WORKINGDIR/${LUCIBRANCH}.zip + +./scripts/feeds install -a +make menuconfig + +``` + +下载完成后,执行配置编译。 diff --git a/htdocs/luci-static/resources/view/smartdns/smartdns.js b/htdocs/luci-static/resources/view/smartdns/smartdns.js new file mode 100644 index 0000000..549482b --- /dev/null +++ b/htdocs/luci-static/resources/view/smartdns/smartdns.js @@ -0,0 +1,483 @@ +/************************************************************************* + * + * Copyright (C) 2018-2020 Ruilin Peng (Nick) . + * + * 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 . + */ + + +'use strict'; +'require fs'; +'require uci'; +'require form'; +'require rpc'; + +var conf = 'smartdns'; +var callServiceList = rpc.declare({ + object: 'service', + method: 'list', + params: ['name'], + expect: { '': {} } +}); + +function getPidOfSmartdns() { + return L.resolveDefault(callServiceList(conf), {}) + .then(function (res) { + var isrunning = false; + try { + isrunning = res[conf]['instances']['smartdns']['running']; + } catch (e) { } + return isrunning; + }); +} + +function getIPTablesRedirect() { + return fs.exec('/usr/sbin/iptables', ['-t', 'nat', '-nL', 'PREROUTING']).then(function (res) { + if (res.code === 0) { + return res.stdout.trim(); + } else { + return ""; + } + }); +} + +function getIP6TablesRedirect() { + return fs.exec('/usr/sbin/ip6tables', ['-t', 'nat', '-nL', 'PREROUTING']).then(function (res) { + if (res.code === 0) { + return res.stdout.trim(); + } else { + return ""; + } + }); +} + +function smartdnsServiceStatus() { + return Promise.all([ + getPidOfSmartdns(), + getIPTablesRedirect(), + getIP6TablesRedirect() + ]); +} + +function smartdnsRenderStatus(res) { + var renderHTML = ""; + var isRunning = res[0]; + var ipt = res[1]; + var ip6t = res[2]; + + var serverPort = uci.get_first('smartdns', 'smartdns', 'port'); + var redirectMode = uci.get_first('smartdns', 'smartdns', 'redirect'); + var ipv6Enabled = uci.get_first('smartdns', 'smartdns', 'ipv6_server'); + + if (isRunning) { + renderHTML += "SmartDNS - " + _("RUNNING") + ""; + } else { + renderHTML += "SmartDNS - " + _("NOT RUNNING") + ""; + return renderHTML; + } + + if (redirectMode === "dnsmasq-upstream") { + var matchLine = "127.0.0.1#" + serverPort; + var dnsmasqServer = uci.get_first('dhcp', 'dnsmasq', 'server') || ""; + + if (dnsmasqServer.indexOf(matchLine) < 0) { + renderHTML += "
" + _("Dnsmasq Forwared To Smartdns Failure") + ""; + } + } else if (redirectMode === "redirect") { + var redirectRules = (ipt || '').split(/\n/).filter(function (rule) { + return rule.match(/REDIRECT/) && rule.match(/dpt:53/) && rule.match("ports " + serverPort); + }); + + if (redirectRules.length <= 0) { + renderHTML += "
" + _("IPV4 53 Port Redirect Failure") + ""; + if (ipv6Enabled) { + var redirectRules = (ip6t || '').split(/\n/).filter(function (rule) { + return rule.match(/REDIRECT/) && rule.match(/dpt:53/) && rule.match("ports " + serverPort); + }); + if (redirectRules.length <= 0) { + renderHTML += "
" + _("IPV6 53 Port Redirect Failure") + ""; + } + } + } + } + + return renderHTML; +} + +return L.view.extend({ + load: function () { + return Promise.all([ + uci.load('smartdns'), + uci.load('dhcp') + ]); + }, + render: function (stats) { + var m, s, o; + + m = new form.Map('smartdns', _('SmartDNS')); + m.title = _("SmartDNS Server"); + m.description = _("SmartDNS is a local high-performance DNS server, supports finding fastest IP, " + + "supports ad filtering, and supports avoiding DNS poisoning."); + + s = m.section(form.NamedSection, '_status'); + s.anonymous = true; + s.render = function (section_id) { + L.Poll.add(function () { + return L.resolveDefault(smartdnsServiceStatus()).then(function (res) { + var view = document.getElementById("service_status"); + view.innerHTML = smartdnsRenderStatus(res); + }); + }); + + return E('div', { class: 'cbi-map' }, + E('div', { class: 'cbi-section' }, [ + E('div', { id: 'service_status' }, + _('Collecting data ...')) + ]) + ); + } + + // Basic; + s = m.section(form.TypedSection, "smartdns", _("Settings"), _("General Settings")); + s.anonymous = true; + + s.tab("settings", _("General Settings")); + s.tab("seconddns", _("Second Server Settings")); + s.tab("custom", _("Custom Settings")); + + // Eanble; + o = s.taboption("settings", form.Flag, "enabled", _("Enable"), _("Enable or disable smartdns server")); + o.default = o.disabled; + o.rempty = false; + + // server name; + o = s.taboption("settings", form.Value, "server_name", _("Server Name"), _("Smartdns server name")); + o.default = "smartdns"; + o.datatype = "hostname"; + o.rempty = false; + + // Port; + o = s.taboption("settings", form.Value, "port", _("Local Port"), _("Smartdns local server port")); + o.placeholder = 6053; + o.default = 6053; + o.datatype = "port"; + o.rempty = false; + + // Enable TCP server; + o = s.taboption("settings", form.Flag, "tcp_server", _("TCP Server"), _("Enable TCP DNS Server")); + o.rmempty = false; + o.default = o.enabled; + + // Support IPV6; + o = s.taboption("settings", form.Flag, "ipv6_server", _("IPV6 Server"), _("Enable IPV6 DNS Server")); + o.rmempty = false; + o.default = o.enabled; + + // Support DualStack ip selection; + o = s.taboption("settings", form.Flag, "dualstack_ip_selection", _("Dual-stack IP Selection"), + _("Enable IP selection between IPV4 and IPV6")); + o.rmempty = false; + o.default = o.disabled; + + // Domain prefetch load ; + o = s.taboption("settings", form.Flag, "prefetch_domain", _("Domain prefetch"), + _("Enable domain prefetch, accelerate domain response speed.")); + o.rmempty = false; + o.default = o.disabled; + + // Domain Serve expired + o = s.taboption("settings", form.Flag, "serve_expired", _("Serve expired"), + _("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.disabled; + + // Redirect; + o = s.taboption("settings", form.ListValue, "redirect", _("Redirect"), _("SmartDNS redirect mode")); + o.placeholder = "none"; + o.value("none", _("none")); + o.value("dnsmasq-upstream", _("Run as dnsmasq upstream server")); + o.value("redirect", _("Redirect 53 port to SmartDNS")); + o.default = "none"; + o.rempty = false; + + // cache-size; + o = s.taboption("settings", form.Value, "cache_size", _("Cache Size"), _("DNS domain result cache size")); + o.rempty = true; + + // rr-ttl; + o = s.taboption("settings", form.Value, "rr_ttl", _("Domain TTL"), _("TTL for all domain result.")); + o.rempty = true; + + // rr-ttl-min; + o = s.taboption("settings", form.Value, "rr_ttl_min", _("Domain TTL Min"), + _("Minimum TTL for all domain result.")); + o.rempty = true; + o.placeholder = "300"; + o.default = 300; + o.optional = true; + + // second dns server; + // rr-ttl-max; + o = s.taboption("settings", form.Value, "rr_ttl_max", _("Domain TTL Max"), + _("Maximum TTL for all domain result.")); + o.rempty = true; + + // Eanble; + o = s.taboption("seconddns", form.Flag, "seconddns_enabled", _("Enable"), + _("Enable or disable second DNS server.")); + o.default = o.disabled; + o.rempty = false; + + // Port; + o = s.taboption("seconddns", form.Value, "seconddns_port", _("Local Port"), _("Smartdns local server port")); + o.placeholder = 6553; + o.default = 6553; + o.datatype = "port"; + o.rempty = false; + + // Enable TCP server; + o = s.taboption("seconddns", form.Flag, "seconddns_tcp_server", _("TCP Server"), _("Enable TCP DNS Server")); + o.rmempty = false; + o.default = o.enabled; + + // dns server group; + o = s.taboption("seconddns", form.Value, "seconddns_server_group", _("Server Group"), + _("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", form.Flag, "seconddns_no_speed_check", _("Skip Speed Check"), + _("Do not check speed.")); + o.rmempty = false; + o.default = o.disabled; + + // skip address rules; + o = s.taboption("seconddns", form.Flag, "seconddns_no_rule_addr", _("Skip Address Rules"), + _("Skip address rules.")); + o.rmempty = false; + o.default = o.disabled; + + // skip name server rules; + o = s.taboption("seconddns", form.Flag, "seconddns_no_rule_nameserver", _("Skip Nameserver Rule"), + _("Skip nameserver rules.")); + o.rmempty = false; + o.default = o.disabled; + + // skip ipset rules; + o = s.taboption("seconddns", form.Flag, "seconddns_no_rule_ipset", _("Skip Ipset Rule"), + _("Skip ipset rules.")); + o.rmempty = false; + o.default = o.disabled; + + // skip soa address rule; + o = s.taboption("seconddns", form.Flag, "seconddns_no_rule_soa", _("Skip SOA Address Rule"), + _("Skip SOA address rules.")); + o.rmempty = false; + o.default = o.disabled; + + o = s.taboption("seconddns", form.Flag, "seconddns_no_dualstack_selection", _("Skip Dualstack Selection"), + _("Skip Dualstack Selection.")); + o.rmempty = false; + o.default = o.disabled; + + // skip cache; + o = s.taboption("seconddns", form.Flag, "seconddns_no_cache", _("Skip Cache"), _("Skip Cache.")); + o.rmempty = false; + o.default = o.disabled; + + // Force AAAA SOA + o = s.taboption("seconddns", form.Flag, "force_aaaa_soa", _("Force AAAA SOA"), _("Force AAAA SOA.")); + o.rmempty = false; + o.default = o.disabled; + + // custom settings; + o = s.taboption("custom", form.TextValue, "custom_conf", + "", _("smartdns custom settings")); + + o.rows = 20; + o.cfgvalue = function (section_id) { + return fs.trimmed('/etc/smartdns/custom.conf'); + }; + o.write = function (section_id, formvalue) { + return fs.write('/etc/smartdns/custom.conf', formvalue.trim().replace(/\r\n/g, '\n') + '\n'); + }; + + o = s.taboption("custom", form.Flag, "coredump", _("Generate Coredump"), + _("Generate Coredump file when smartdns crash, coredump file is located at /tmp/smartdns.xxx.core.")); + o.rmempty = false; + o.default = o.disabled; + // Upstream servers; + s = m.section(form.GridSection, "server", _("Upstream Servers"), + _("Upstream Servers, support UDP, TCP protocol. Please configure multiple DNS servers, " + + "including multiple foreign DNS servers.")); + s.anonymous = true; + s.addremove = true; + + s.tab('general', _('General Settings')); + s.tab('advanced', _('Advanced Settings')); + + // enable flag; + o = s.taboption("general", form.Flag, "enabled", _("Enable"), _("Enable")); + o.rmempty = false; + o.default = o.enabled; + o.editable = true; + + // name; + o = s.taboption("general", form.Value, "name", _("DNS Server Name"), _("DNS Server Name")); + + // IP address; + o = s.taboption("general", form.Value, "ip", _("ip"), _("DNS Server ip")); + o.datatype = "or(ipaddr, string)"; + o.rmempty = false; + + // port; + o = s.taboption("general", form.Value, "port", _("port"), _("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.taboption("general", form.ListValue, "type", _("type"), _("DNS Server type")); + o.placeholder = "udp"; + o.value("udp", _("udp")); + o.value("tcp", _("tcp")); + o.value("tls", _("tls")); + o.value("https", _("https")); + o.default = "udp"; + o.rempty = false; + + // Advanced Options + // server group + o = s.taboption("advanced", form.Value, "server_group", _("Server Group"), _("DNS Server group belongs to, " + + "used with nameserver, such as office, home.")) + o.rmempty = true + o.placeholder = "default" + o.datatype = "hostname" + o.rempty = true + o.modalonly = true; + + // blacklist_ip + o = s.taboption("advanced", form.Flag, "blacklist_ip", _("IP Blacklist Filtering"), + _("Filtering IP with blacklist")) + o.rmempty = false + o.default = o.disabled + o.modalonly = true; + + // TLS host verify + o = s.taboption("advanced", form.Value, "tls_host_verify", _("TLS Hostname Verify"), + _("Set TLS hostname to verify.")) + o.default = "" + o.datatype = "string" + o.rempty = true + o.modalonly = true; + o.depends("type", "tls") + o.depends("type", "https") + + // SNI host name + o = s.taboption("advanced", form.Value, "host_name", _("TLS SNI name"), + _("Sets the server name indication for query.")) + o.default = "" + o.datatype = "hostname" + o.rempty = true + o.modalonly = true; + o.depends("type", "tls") + o.depends("type", "https") + + // http host + o = s.taboption("advanced", form.Value, "http_host", _("HTTP Host"), + _("Set the HTTP host used for the query. Use this parameter when the host of the URL address is an IP address.")) + o.default = "" + o.datatype = "hostname" + o.rempty = true + o.modalonly = true; + o.depends("type", "https") + + // SPKI pin + o = s.taboption("advanced", form.Value, "spki_pin", _("TLS SPKI Pinning"), + _("Used to verify the validity of the TLS server, The value is Base64 encoded SPKI fingerprint, " + + "leaving blank to indicate that the validity of TLS is not verified.")) + o.default = "" + o.datatype = "string" + o.rempty = true + o.modalonly = true; + o.depends("type", "tls") + o.depends("type", "https") + + // other args + o = s.taboption("advanced", form.Value, "addition_arg", _("Additional Server Args"), + _("Additional Args for upstream dns servers")) + o.default = "" + o.rempty = true + o.modalonly = true; + + // Doman addresss; + s = m.section(form.TypedSection, "smartdns", _("Advanced Settings"), _("Advanced Settings")); + s.anonymous = true; + + s.tab("domain-address", _("Domain Address"), _("Set Specific domain ip address.")); + s.tab("blackip-list", _("IP Blacklist"), _("Set Specific ip blacklist.")); + + o = s.taboption("domain-address", form.TextValue, "address_conf", + "", + _("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.")); + o.rows = 20; + o.cfgvalue = function (section_id) { + return fs.trimmed('/etc/smartdns/address.conf'); + }; + o.write = function (section_id, formvalue) { + return fs.write('/etc/smartdns/address.conf', formvalue.trim().replace(/\r\n/g, '\n') + '\n'); + }; + + // IP Blacklist; + // blacklist; + o = s.taboption("blackip-list", form.TextValue, "blackip_ip_conf", + "", _("Configure IP blacklists that will be filtered from the results of specific DNS server.")); + o.rows = 20; + o.cfgvalue = function (section_id) { + return fs.trimmed('/etc/smartdns/blacklist-ip.conf'); + }; + o.write = function (section_id, formvalue) { + return fs.write('/etc/smartdns/blacklist-ip.conf', formvalue.trim().replace(/\r\n/g, '\n') + '\n'); + }; + + // Doman addresss; + s = m.section(form.TypedSection, "smartdns", _("Technical Support"), + _("If you like this software, please buy me a cup of coffee.")); + s.anonymous = true; + + o = s.option(form.Button, "web"); + o.title = _("SmartDNS official website"); + o.inputtitle = _("open website"); + o.inputstyle = "apply"; + o.onclick = function () { + window.open("https://pymumu.github.io/smartdns", '_blank'); + }; + + o = s.option(form.Button, "Donate"); + o.title = _("Donate to smartdns"); + o.inputtitle = _("Donate"); + o.inputstyle = "apply"; + o.onclick = function () { + window.open("https://pymumu.github.io/smartdns/#donate", '_blank'); + }; + + return m.render(); + } +}); diff --git a/luasrc/controller/smartdns.lua b/luasrc/controller/smartdns.lua deleted file mode 100644 index 5ab48b4..0000000 --- a/luasrc/controller/smartdns.lua +++ /dev/null @@ -1,86 +0,0 @@ --- --- Copyright (C) 2018-2020 Ruilin Peng (Nick) . --- --- 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 . - -module("luci.controller.smartdns", package.seeall) - -local smartdns = require("luci.model.smartdns") -local http = require ("luci.http") -local sys = require ("luci.sys") - -function index() - if not nixio.fs.access("/etc/config/smartdns") then - return - end - - local page - page = entry({"admin", "services", "smartdns"}, cbi("smartdns/smartdns"), _("SmartDNS"), 60) - page.dependent = true - page = entry({"admin", "services", "smartdns", "status"}, call("act_status")) - page.leaf = true - page = entry({"admin", "services", "smartdns", "upstream"}, cbi("smartdns/upstream"), nil) - page.leaf = true -end - -local function is_running() - return sys.call("pidof smartdns >/dev/null") == 0 -end - -function act_status() - local e={} - local ipv6_server; - local redirect_mode="none"; - - e.ipv6_works = 2; - e.ipv4_works = 2; - e.ipv6_server = 1; - e.dnsmasq_forward = 0; - redirect_mode = smartdns.get_config_option("smartdns", "smartdns", "redirect", nil); - if redirect_mode == "redirect" then - e.redirect = 1 - elseif redirect_mode == "dnsmasq-upstream" then - e.redirect = 2 - else - e.redirect = 0 - end - - e.local_port = smartdns.get_config_option("smartdns", "smartdns", "port", nil); - ipv6_server = smartdns.get_config_option("smartdns", "smartdns", "ipv6_server", nil); - if e.redirect == 1 then - if e.local_port ~= nil and e.local_port ~= "53" then - e.ipv4_works = sys.call("iptables -t nat -nL PREROUTING 2>/dev/null | grep REDIRECT | grep dpt:53 | grep %q >/dev/null 2>&1" % e.local_port) == 0 - if ipv6_server == "1" then - e.ipv6_works = sys.call("ip6tables -t nat -nL PREROUTING 2>/dev/null| grep REDIRECT | grep dpt:53 | grep %q >/dev/null 2>&1" % e.local_port) == 0 - else - e.ipv6_works = 2 - end - else - e.redirect = 0 - end - elseif e.redirect == 2 then - local str; - local dnsmasq_server = sys.exec("uci get dhcp.@dnsmasq[0].server") - if e.local_port ~= nil then - str = "127.0.0.1#" .. e.local_port - if string.sub(dnsmasq_server,1,string.len(str)) == str then - e.dnsmasq_forward = 1 - end - end - end - e.running = is_running() - - http.prepare_content("application/json") - http.write_json(e) -end diff --git a/luasrc/model/cbi/smartdns/smartdns.lua b/luasrc/model/cbi/smartdns/smartdns.lua deleted file mode 100644 index 1565bc8..0000000 --- a/luasrc/model/cbi/smartdns/smartdns.lua +++ /dev/null @@ -1,331 +0,0 @@ --- --- Copyright (C) 2018-2020 Ruilin Peng (Nick) . --- --- 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 . - -local m, s, o -local custom, addr - -local fs = require ("nixio.fs") -local http = require ("luci.http") -local dispatcher = require ("luci.dispatcher") - -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("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.placeholder = "smartdns" -o.datatype = "hostname" -o.rempty = true - ----- Port -o = s:taboption("settings", Value, "port", translate("Local Port"), translate("Smartdns local server port")) -o.placeholder = 6053 -o.default = 6053 -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("settings", Flag, "dualstack_ip_selection", translate("Dual-stack IP Selection"), translate("Enable IP selection between IPV4 and IPV6")) -o.rmempty = false -o.default = o.disabled -o.cfgvalue = function(...) - return Flag.cfgvalue(...) or "0" -end - ----- Domain prefetch load -o = s:taboption("settings", 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 - ----- Redirect -o = s:taboption("settings", ListValue, "redirect", translate("Redirect"), translate("SmartDNS redirect mode")) -o.placeholder = "none" -o:value("none", translate("none")) -o:value("dnsmasq-upstream", translate("Run as dnsmasq upstream server")) -o:value("redirect", translate("Redirect 53 port to SmartDNS")) -o.default = "none" -o.rempty = false - ----- cache-size -o = s:taboption("settings", Value, "cache_size", translate("Cache Size"), translate("DNS domain result cache size")) -o.rempty = true - ----- rr-ttl -o = s:taboption("settings", Value, "rr_ttl", translate("Domain TTL"), translate("TTL for all domain result.")) -o.rempty = true - ----- rr-ttl-min -o = s:taboption("settings", Value, "rr_ttl_min", translate("Domain TTL Min"), translate("Minimum TTL for all domain result.")) -o.rempty = true -o.placeholder = "300" -o.default = 300 -o.optional = true - ----- second dns server ----- rr-ttl-max -o = s:taboption("settings", Value, "rr_ttl_max", translate("Domain TTL Max"), translate("Maximum TTL for all domain result.")) -o.rempty = true - ----- 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 = 7053 -o.default = 7053 -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 - -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 - ----- 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 - ----- 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 Sualstack 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 - ------ 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 fs.readfile("/etc/smartdns/custom.conf") -end - -function custom.write(self, section, value) - value = value:gsub("\r\n?", "\n") - 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 = 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 Address -s = m:section(TypedSection, "smartdns", translate("Domain Address"), - translate("Set Specific domain ip address.")) -s.anonymous = true - ----- address -addr = s:option(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 fs.readfile("/etc/smartdns/address.conf") -end - -function addr.write(self, section, value) - value = value:gsub("\r\n?", "\n") - fs.writefile("/etc/smartdns/address.conf", value) -end - --- IP Blacklist -s = m:section(TypedSection, "smartdns", translate("IP Blacklist"), - translate("Set Specific ip blacklist.")) -s.anonymous = true - ----- blacklist -addr = s:option(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 fs.readfile("/etc/smartdns/blacklist-ip.conf") -end - -function addr.write(self, section, value) - value = value:gsub("\r\n?", "\n") - fs.writefile("/etc/smartdns/blacklist-ip.conf", value) -end - --- 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() - 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() - http.redirect("https://pymumu.github.io/smartdns/#donate") -end - -return m - diff --git a/luasrc/model/cbi/smartdns/upstream.lua b/luasrc/model/cbi/smartdns/upstream.lua deleted file mode 100644 index 40d83af..0000000 --- a/luasrc/model/cbi/smartdns/upstream.lua +++ /dev/null @@ -1,123 +0,0 @@ --- --- Copyright (C) 2018-2020 Ruilin Peng (Nick) . --- --- 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 . - -local m, s, o - -local http = require ("luci.http") -local sid = arg[1] - -m = Map("smartdns", "%s - %s" %{translate("SmartDNS Server"), translate("Upstream DNS Server Configuration")}) -m.redirect = luci.dispatcher.build_url("admin/services/smartdns") - -if m.uci:get("smartdns", sid) ~= "server" then - http.redirect(m.redirect) - return -end - --- [[ Edit Server ]]-- -s = m:section(NamedSection, sid, "server") -s.anonymous = true -s.addremove = false - ----- 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(host, 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 - ----- TLS host verify -o = s:option(Value, "tls_host_verify", translate("TLS Hostname Verify"), translate("Set TLS hostname to verify.")) -o.default = "" -o.datatype = "string" -o.rempty = true -o:depends("type", "tls") -o:depends("type", "https") - ----- SNI host name -o = s:option(Value, "host_name", translate("TLS SNI name"), translate("Sets the server name indication for query.")) -o.default = "" -o.datatype = "hostname" -o.rempty = true -o:depends("type", "tls") -o:depends("type", "https") - ----- http host -o = s:option(Value, "http_host", translate("HTTP Host"), translate("Set the HTTP host used for the query. Use this parameter when the host of the URL address is an IP address.")) -o.default = "" -o.datatype = "hostname" -o.rempty = true -o:depends("type", "https") - ----- server group -o = s:option(Value, "server_group", translate("Server Group"), translate("DNS Server group belongs to, used with nameserver, such as office, home.")) -o.rmempty = true -o.placeholder = "default" -o.datatype = "hostname" -o.rempty = true - ----- blacklist_ip -o = s:option(Flag, "blacklist_ip", translate("IP Blacklist Filtering"), translate("Filtering IP with blacklist")) -o.rmempty = false -o.default = o.disabled -o.cfgvalue = function(...) - return Flag.cfgvalue(...) or "0" -end - ----- anti-Answer-Forgery --- o = s:option(Flag, "check_edns", translate("Anti Answer Forgery"), translate("Anti answer forgery, if DNS does not work properly after enabling, please turn off this feature")) --- o.rmempty = false --- o.default = o.disabled --- o:depends("type", "udp") --- o.cfgvalue = function(...) --- return Flag.cfgvalue(...) or "0" --- end - ----- SPKI pin -o = s:option(Value, "spki_pin", translate("TLS SPKI Pinning"), translate("Used to verify the validity of the TLS server, The value is Base64 encoded SPKI fingerprint, leaving blank to indicate that the validity of TLS is not verified.")) -o.default = "" -o.datatype = "string" -o.rempty = true -o:depends("type", "tls") -o:depends("type", "https") - - ----- other args -o = s:option(Value, "addition_arg", translate("Additional Server Args"), translate("Additional Args for upstream dns servers")) -o.default = "" -o.rempty = true -o.optional = true - -return m \ No newline at end of file diff --git a/luasrc/model/smartdns.lua b/luasrc/model/smartdns.lua deleted file mode 100644 index 9f6da4e..0000000 --- a/luasrc/model/smartdns.lua +++ /dev/null @@ -1,26 +0,0 @@ --- --- Copyright (C) 2018-2020 Ruilin Peng (Nick) . --- --- 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 . - -local uci = require "luci.model.uci".cursor() - -module("luci.model.smartdns", package.seeall) - -function get_config_option(module, section, option, default) - return uci:get_first(module, section, option) or default -end - -return m - diff --git a/luasrc/view/smartdns/smartdns_status.htm b/luasrc/view/smartdns/smartdns_status.htm deleted file mode 100644 index c56dc20..0000000 --- a/luasrc/view/smartdns/smartdns_status.htm +++ /dev/null @@ -1,41 +0,0 @@ - - -
-

- <%:Collecting data...%> -

-
diff --git a/po/zh-cn/smartdns.po b/po/zh-cn/smartdns.po index 0d9579b..4cab4fe 100644 --- a/po/zh-cn/smartdns.po +++ b/po/zh-cn/smartdns.po @@ -11,11 +11,26 @@ msgid "SmartDNS Server" msgstr "SmartDNS 服务器" msgid "SmartDNS is a local high-performance DNS server, supports finding fastest IP, supports ad filtering, and supports avoiding DNS poisoning." -msgstr "SmartDNS是一个本地高性能DNS服务器,支持避免域名污染,支持返回最快IP,支持广告过滤。" +msgstr "SmartDNS是一个本地高性能DNS服务器,支持返回最快IP,支持广告过滤。" msgid "Custom Settings" msgstr "自定义设置" +msgid "General Settings" +msgstr "基本设置" + +msgid "Settings" +msgstr "设置" + +msgid "Advanced Settings" +msgstr "高级设置" + +msgid "RUNNING" +msgstr "运行中" + +msgid "NOT RUNNING" +msgstr "未运行" + msgid "Generate Coredump" msgstr "生成coredump" @@ -73,6 +88,12 @@ msgstr "域名预加载" msgid "Enable domain prefetch, accelerate domain response speed." msgstr "启用域名预加载,加速域名响应速度。" +msgid "Serve expired" +msgstr "缓存过期服务" + +msgid "Attempts to serve old responses from cache with a TTL of 0 in the response without waiting for the actual resolution to finish." +msgstr "查询性能优化,有请求时尝试回应TTL为0的过期记录,以避免查询等待。" + msgid "Redirect" msgstr "重定向" @@ -157,7 +178,7 @@ msgstr "跳过address SOA(#)规则。" msgid "Skip Dualstack Selection" msgstr "跳过双栈优选" -msgid "Skip Sualstack Selection." +msgid "Skip Dualstack Selection." msgstr "跳过双栈优选。" msgid "Skip Cache" @@ -166,6 +187,12 @@ msgstr "跳过cache" msgid "Skip Cache." msgstr "跳过cache。" +msgid "Force AAAA SOA" +msgstr "停用IPV6地址解析" + +msgid "Force AAAA SOA." +msgstr "停用IPV6地址解析。" + msgid "Upstream Servers" msgstr "上游服务器" @@ -276,7 +303,3 @@ msgstr "捐助smartdns项目" msgid "Donate" msgstr "捐助" - - - - diff --git a/root/etc/uci-defaults/50_luci-smartdns b/root/etc/uci-defaults/50_luci-smartdns deleted file mode 100644 index 4e20c1d..0000000 --- a/root/etc/uci-defaults/50_luci-smartdns +++ /dev/null @@ -1,13 +0,0 @@ -#!/bin/sh -# Copyright 2018-2020 Nick Peng -# Licensed to the public under the GPL V3 License. - -uci -q batch <<-EOF >/dev/null - delete ucitrack.@smartdns[-1] - add ucitrack smartdns - set ucitrack.@smartdns[-1].init=smartdns - commit ucitrack -EOF - -rm -f /tmp/luci-indexcache -exit 0 diff --git a/root/usr/share/luci/menu.d/luci-app-smartdns.json b/root/usr/share/luci/menu.d/luci-app-smartdns.json new file mode 100644 index 0000000..91b4402 --- /dev/null +++ b/root/usr/share/luci/menu.d/luci-app-smartdns.json @@ -0,0 +1,12 @@ +{ + "admin/services/smartdns": { + "title": "SmartDNS", + "action": { + "type": "view", + "path": "smartdns/smartdns" + }, + "depends": { + "uci": { "smartdns": true } + } + } +} diff --git a/root/usr/share/rpcd/acl.d/luci-app-smartdns.json b/root/usr/share/rpcd/acl.d/luci-app-smartdns.json new file mode 100644 index 0000000..659d6cd --- /dev/null +++ b/root/usr/share/rpcd/acl.d/luci-app-smartdns.json @@ -0,0 +1,21 @@ +{ + "luci-app-smartdns": { + "description": "Grant access to LuCI app smartdns", + "read": { + "file": { + "/etc/smartdns/*": [ "read" ], + "/usr/sbin/iptables -t nat -nL PREROUTING": [ "exec" ], + "/usr/sbin/ip6tables -t nat -nL PREROUTING": [ "exec" ], + "/usr/sbin/smartdns": [ "exec" ] + }, + "ubus": { + "service": [ "list" ] + } + }, + "write": { + "file": { + "/etc/smartdns/*": [ "write" ] + } + } + } +}