diff --git a/package/luci/files/luci/i18n/smartdns.zh-cn.po b/package/luci/files/luci/i18n/smartdns.zh-cn.po index 5c2dc07..f3c3093 100644 --- a/package/luci/files/luci/i18n/smartdns.zh-cn.po +++ b/package/luci/files/luci/i18n/smartdns.zh-cn.po @@ -17,7 +17,7 @@ msgid "Automatically Set Dnsmasq" msgstr "自动设置Dnsmasq" msgid "Automatically set as upstream of dnsmasq when port changes." -msgstr "自动设置为Dnsmasq的上游服务器" +msgstr "端口更改时自动设为 dnsmasq 的上游。" msgid "Cache Size" msgstr "缓存大小" @@ -30,15 +30,29 @@ msgid "" "DNS server." msgstr "配置需要从指定域名服务器结果过滤的IP黑名单。" +msgid "Configure block domain list." +msgstr "配置屏蔽域名列表" + +msgid "Configure forwarding domain name list." +msgstr "配置分流域名列表" + msgid "Custom Settings" msgstr "自定义设置" +msgid "DNS Block Setting" +msgstr "域名屏蔽设置" + +msgid "DNS Forwarding Setting" +msgstr "域名分流设置" + msgid "DNS Server Name" msgstr "DNS服务器名称" -msgid "" -"DNS Server group belongs to, used with nameserver, such as office, home." -msgstr "DNS服务器所属组, 配合nameserver使用,例如:office,home。" +msgid "DNS Server group" +msgstr "服务器组" + +msgid "DNS Server group belongs to, such as office, home." +msgstr "设置服务器组,例如office,home" msgid "DNS Server ip" msgstr "DNS服务器IP" @@ -52,6 +66,9 @@ msgstr "协议类型" msgid "DNS domain result cache size" msgstr "缓存DNS的结果,缓存大小,配置零则不缓存" +msgid "Description" +msgstr "描述" + msgid "Dnsmasq Forwared To Smartdns Failure" msgstr "重定向dnsmasq到smartdns失败" @@ -64,6 +81,18 @@ msgstr "禁用测速。" msgid "Domain Address" msgstr "域名地址" +msgid "Domain List" +msgstr "域名列表" + +msgid "Domain List File" +msgstr "域名列表文件" + +msgid "Domain Rules" +msgstr "域名规则" + +msgid "Domain Rules Settings" +msgstr "域名规则设置" + msgid "Domain TTL" msgstr "域名TTL" @@ -82,12 +111,27 @@ msgstr "捐助" msgid "Donate to smartdns" msgstr "捐助smartdns项目" +msgid "Download Files" +msgstr "下载文件" + +msgid "Download Files Setting" +msgstr "下载文件设置" + +msgid "" +"Download domain list files for domain-rule and include config files, please " +"refresh the page after download to take effect." +msgstr "" +"下载域名规则所需要的域名列表文件和smartdns配置文件,下载完成后刷新页面。" + msgid "Dual-stack IP Selection" msgstr "双栈IP优选" msgid "Enable" msgstr "启用" +msgid "Enable Auto Update" +msgstr "启用自动更新" + msgid "Enable IP selection between IPV4 and IPV6" msgstr "启用 IPV4 和 IPV6 间的 IP 优选策略" @@ -97,6 +141,9 @@ msgstr "启用IPV6服务器" msgid "Enable TCP DNS Server" msgstr "启用TCP服务器" +msgid "Enable daily auto update." +msgstr "启用每日自动更新" + msgid "Enable domain prefetch, accelerate domain response speed." msgstr "启用域名预加载,加速域名响应速度。" @@ -106,6 +153,18 @@ msgstr "是否启用第二DNS服务器。" msgid "Enable or disable smartdns server" msgstr "启用或禁用SmartDNS服务" +msgid "Exclude DNS Server from default group." +msgstr "从default默认服务器组中排除" + +msgid "Exclude Default Group" +msgstr "从默认组中排除" + +msgid "File Name" +msgstr "文件名" + +msgid "File Type" +msgstr "文件类型" + msgid "Filtering IP with blacklist" msgstr "使用IP黑名单过滤" @@ -148,9 +207,28 @@ msgstr "IP黑名单过滤" msgid "IPV6 Server" msgstr "IPV6服务器" +msgid "IPset Name" +msgstr "IPset名称" + +msgid "IPset name." +msgstr "IPSet名称。" + msgid "If you like this software, please buy me a cup of coffee." msgstr "如果本软件对你有帮助,请给作者加个蛋。" +msgid "Include Config Files
/etc/smartdns/conf.d" +msgstr "包含配置文件
/etc/smartdns/conf.d" + +msgid "" +"Include other config files from /etc/smartdns/conf.d or custom path, can be " +"downloaded from the download page." +msgstr "" +"包含配置文件,路径为/etc/smartdns/conf.d,或自定义配置文件路径,可以从下载页" +"面配置自动下载。" + +msgid "List of files to download." +msgstr "下载文件列表" + msgid "Local Port" msgstr "本地端口" @@ -160,6 +238,15 @@ msgstr "所有域名的最大 TTL 值。" msgid "Minimum TTL for all domain result." msgstr "所有域名的最小 TTL 值。" +msgid "NFTset Name" +msgstr "NFTSet名称" + +msgid "NFTset name format error, format: [#[4|6]:[family#table#set]]" +msgstr "NFTSet名称格式错误,格式:[#[4|6]:[family#table#set]]" + +msgid "NFTset name, format: [#[4|6]:[family#table#set]]" +msgstr "NFTSet名称,格式:[#[4|6]:[family#table#set]]" + msgid "NOT RUNNING" msgstr "未运行" @@ -199,6 +286,9 @@ msgstr "缓存过期服务" msgid "Server Group" msgstr "服务器组" +msgid "Server Group %s not exists" +msgstr "服务器组%s不存在" + msgid "Server Name" msgstr "服务器名称" @@ -216,8 +306,8 @@ msgid "" "the URL address is an IP address." msgstr "设置查询时使用的HTTP主机,当URL地址的host是IP地址时,使用此参数。" -msgid "Sets the server name indication for query." -msgstr "设置查询时使用的服务器SNI名称。" +msgid "Sets the server name indication for query. '-' for disable SNI name." +msgstr "设置服务器SNI名称,‘-’表示禁用SNI名称。" msgid "Settings" msgstr "设置" @@ -281,7 +371,8 @@ msgstr "SmartDNS本地服务端口" msgid "" "Smartdns local server port, smartdns will be automatically set as main dns " "when the port is 53." -msgstr "SmartDNS本地服务端口,当端口号设置为53时,smartdns将会自动配置为主dns。" +msgstr "" +"SmartDNS本地服务端口,当端口号设置为53时,smartdns将会自动配置为主dns。" msgid "Smartdns server name" msgstr "SmartDNS的服务器名称,默认为smartdns,留空为主机名" @@ -312,6 +403,38 @@ msgstr "设置所有域名的 TTL 值。" msgid "Technical Support" msgstr "技术支持" +msgid "URL" +msgstr "URL" + +msgid "URL format error, format: http:// or https://" +msgstr "URL格式错误,格式:http://或https://" + +msgid "Update" +msgstr "更新" + +msgid "Update Files" +msgstr "更新文件" + +msgid "Upload Config File" +msgstr "上传配置文件" + +msgid "Upload Domain List File" +msgstr "上传域名列表文件" + +msgid "Upload domain list file to /etc/smartdns/domain-set" +msgstr "上传域名列表文件到/etc/smartdns/domain-set" + +msgid "" +"Upload domain list file, or configure auto download from Download File " +"Setting page." +msgstr "上传域名列表文件,或在下载文件设置页面设置自动下载。" + +msgid "Upload domain list file." +msgstr "上传域名列表文件" + +msgid "Upload smartdns config file to /etc/smartdns/conf.d" +msgstr "上传配置文件到/etc/smartdns/conf.d" + msgid "Upstream Servers" msgstr "上游服务器" @@ -330,6 +453,9 @@ msgstr "" "用于校验 TLS 服务器的有效性,数值为 Base64 编码的 SPKI 指纹,留空表示不验证 " "TLS 的合法性。" +msgid "domain list (/etc/smartdns/domain-set)" +msgstr "域名列表(/etc/smartdns/domain-set)" + msgid "https" msgstr "https" @@ -342,6 +468,9 @@ msgstr "打开网站" msgid "port" msgstr "端口" +msgid "smartdns config (/etc/smartdns/conf.d)" +msgstr "配置文件(/etc/smartdns/conf.d)" + msgid "smartdns custom settings" msgstr "smartdns 自定义设置,具体配置参数参考指导" diff --git a/package/luci/files/root/usr/share/rpcd/acl.d/luci-app-smartdns.json b/package/luci/files/root/usr/share/rpcd/acl.d/luci-app-smartdns.json index ef1e386..8c4cd01 100644 --- a/package/luci/files/root/usr/share/rpcd/acl.d/luci-app-smartdns.json +++ b/package/luci/files/root/usr/share/rpcd/acl.d/luci-app-smartdns.json @@ -13,7 +13,8 @@ "write": { "file": { "/etc/smartdns/*": [ "write" ], - "/etc/init.d/smartdns restart": [ "exec" ] + "/etc/init.d/smartdns restart": [ "exec" ], + "/etc/init.d/smartdns updatefiles": [ "exec" ] }, "uci": [ "smartdns" ] } diff --git a/package/luci/files/root/www/luci-static/resources/view/smartdns/smartdns.js b/package/luci/files/root/www/luci-static/resources/view/smartdns/smartdns.js index ce32aaf..6873b09 100644 --- a/package/luci/files/root/www/luci-static/resources/view/smartdns/smartdns.js +++ b/package/luci/files/root/www/luci-static/resources/view/smartdns/smartdns.js @@ -89,6 +89,8 @@ return view.extend({ }, render: function (stats) { var m, s, o; + var ss, so; + var servers, downlfiles; m = new form.Map('smartdns', _('SmartDNS')); m.title = _("SmartDNS Server"); @@ -120,14 +122,21 @@ return view.extend({ ]); } + //////////////// // Basic; + //////////////// s = m.section(form.TypedSection, "smartdns", _("Settings"), _("General Settings")); s.anonymous = true; s.tab("settings", _("General Settings")); + s.tab("advanced", _('Advanced Settings')); s.tab("seconddns", _("Second Server Settings")); + s.tab("files", _("Download Files Setting"), _("Download domain list files for domain-rule and include config files, please refresh the page after download to take effect.")); s.tab("custom", _("Custom Settings")); + /////////////////////////////////////// + // Basic Settings + /////////////////////////////////////// o = s.taboption("settings", form.Flag, "enabled", _("Enable"), _("Enable or disable smartdns server")); o.rmempty = false; o.default = o.disabled; @@ -156,54 +165,57 @@ return view.extend({ o.rmempty = false; o.default = o.enabled; + /////////////////////////////////////// + // advanced settings; + /////////////////////////////////////// // Support DualStack ip selection; - o = s.taboption("settings", form.Flag, "dualstack_ip_selection", _("Dual-stack IP Selection"), + o = s.taboption("advanced", form.Flag, "dualstack_ip_selection", _("Dual-stack IP Selection"), _("Enable IP selection between IPV4 and IPV6")); o.rmempty = false; o.default = o.enabled; // Domain prefetch load ; - o = s.taboption("settings", form.Flag, "prefetch_domain", _("Domain prefetch"), + o = s.taboption("advanced", 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"), + o = s.taboption("advanced", 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.enabled; // cache-size; - o = s.taboption("settings", form.Value, "cache_size", _("Cache Size"), _("DNS domain result cache size")); + o = s.taboption("advanced", form.Value, "cache_size", _("Cache Size"), _("DNS domain result cache size")); o.rempty = true; // cache-size; - o = s.taboption("settings", form.Flag, "resolve_local_hostnames", _("Resolve Local Hostnames"), _("Resolve local hostnames by reading Dnsmasq lease file.")); + o = s.taboption("advanced", form.Flag, "resolve_local_hostnames", _("Resolve Local Hostnames"), _("Resolve local hostnames by reading Dnsmasq lease file.")); o.rmempty = false; o.default = o.enabled; // auto-conf-dnsmasq; - o = s.taboption("settings", form.Flag, "auto_set_dnsmasq", _("Automatically Set Dnsmasq"), _("Automatically set as upstream of dnsmasq when port changes.")); + o = s.taboption("advanced", form.Flag, "auto_set_dnsmasq", _("Automatically Set Dnsmasq"), _("Automatically set as upstream of dnsmasq when port changes.")); o.rmempty = false; o.default = o.enabled; // Force AAAA SOA - o = s.taboption("settings", form.Flag, "force_aaaa_soa", _("Force AAAA SOA"), _("Force AAAA SOA.")); + o = s.taboption("advanced", form.Flag, "force_aaaa_soa", _("Force AAAA SOA"), _("Force AAAA SOA.")); o.rmempty = false; o.default = o.disabled; // Force HTTPS SOA - o = s.taboption("settings", form.Flag, "force_https_soa", _("Force HTTPS SOA"), _("Force HTTPS SOA.")); + o = s.taboption("advanced", form.Flag, "force_https_soa", _("Force HTTPS SOA"), _("Force HTTPS SOA.")); o.rmempty = false; o.default = o.enabled; // rr-ttl; - o = s.taboption("settings", form.Value, "rr_ttl", _("Domain TTL"), _("TTL for all domain result.")); + o = s.taboption("advanced", 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"), + o = s.taboption("advanced", form.Value, "rr_ttl_min", _("Domain TTL Min"), _("Minimum TTL for all domain result.")); o.rempty = true; o.placeholder = "600"; @@ -211,16 +223,34 @@ return view.extend({ o.optional = true; // rr-ttl-max; - o = s.taboption("settings", form.Value, "rr_ttl_max", _("Domain TTL Max"), + o = s.taboption("advanced", form.Value, "rr_ttl_max", _("Domain TTL Max"), _("Maximum TTL for all domain result.")); o.rempty = true; // rr-ttl-reply-max; - o = s.taboption("settings", form.Value, "rr_ttl_reply_max", _("Reply Domain TTL Max"), + o = s.taboption("advanced", form.Value, "rr_ttl_reply_max", _("Reply Domain TTL Max"), _("Reply maximum TTL for all domain result.")); o.rempty = true; + // include config + downlfiles = uci.sections('smartdns', 'download-file'); + o = s.taboption("advanced", form.DynamicList, "conf_files", _("Include Config Files
/etc/smartdns/conf.d"), + _("Include other config files from /etc/smartdns/conf.d or custom path, can be downloaded from the download page.")); + for (var i = 0; i < downlfiles.length; i++) { + if (downlfiles[i].type == undefined) { + continue; + } + + if (downlfiles[i].type != 'config') { + continue + } + + o.value(downlfiles[i].name); + } + + /////////////////////////////////////// // second dns server; + /////////////////////////////////////// // Eanble; o = s.taboption("seconddns", form.Flag, "seconddns_enabled", _("Enable"), _("Enable or disable second DNS server.")); @@ -291,10 +321,85 @@ return view.extend({ o.rmempty = false; o.default = o.disabled; + /////////////////////////////////////// + // download Files Settings + /////////////////////////////////////// + o = s.taboption("files", form.Flag, "enable_auto_update", _("Enable Auto Update"), _("Enable daily auto update.")); + o.rmempty = false; + o.default = o.disabled; + o.rempty = true; + + o = s.taboption("files", form.FileUpload, "upload_conf_file", _("Upload Config File"), + _("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.taboption("files", form.FileUpload, "upload_list_file", _("Upload Domain List File"), + _("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.taboption('files', form.DummyValue, "_update", _("Update Files")); + o.renderWidget = function () { + return E('button', { + 'class': 'btn cbi-button cbi-button-apply', + 'id': 'btn_update', + 'click': ui.createHandlerFn(this, function () { + return fs.exec('/etc/init.d/smartdns', ['updatefiles']) + .catch(function (e) { ui.addNotification(null, E('p', e.message), 'error') }); + }) + }, [_("Update")]); + } + + o = s.taboption('files', form.SectionValue, '__files__', form.GridSection, 'download-file', _('Download Files'), + _('List of files to download.')); + + ss = o.subsection; + + ss.addremove = true; + ss.anonymous = true; + ss.sortable = true; + + so = ss.option(form.Value, 'name', _('File Name'), _('File Name')); + so.rmempty = false; + so.datatype = 'file'; + + so = ss.option(form.Value, 'url', _('URL'), _('URL')); + so.rmempty = false; + so.datatype = 'string'; + so.validate = function (section_id, value) { + if (value == "") { + return true; + } + + if (!value.match(/^(http|https|ftp|sftp):\/\//)) { + return _("URL format error, format: http:// or https://"); + } + + return true; + } + + so = ss.option(form.ListValue, "type", _("type"), _("File Type")); + so.value("list", _("domain list (/etc/smartdns/domain-set)")); + so.value("config", _("smartdns config (/etc/smartdns/conf.d)")); + so.default = "list"; + so.rempty = false; + + so = ss.option(form.Value, 'desc', _('Description'), _('Description')); + so.rmempty = true; + so.datatype = 'string'; + + /////////////////////////////////////// // 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'); @@ -312,12 +417,16 @@ return view.extend({ _("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.sortable = true; s.tab('general', _('General Settings')); s.tab('advanced', _('Advanced Settings')); @@ -355,14 +464,30 @@ return view.extend({ 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 = s.taboption("general", form.Value, "server_group", _("Server Group"), _("DNS Server group")) + o.rmempty = true; + o.placeholder = "default"; + o.datatype = "hostname"; + o.rempty = true; + servers = uci.sections('smartdns', 'server'); + var groupnames = new Set(); + for (var i = 0; i < servers.length; i++) { + if (servers[i].server_group == undefined) { + continue; + } + groupnames.add(servers[i].server_group); + } + + for (const groupname of groupnames) { + o.value(groupname); + } + + // Advanced Options + o = s.taboption("advanced", form.Flag, "exclude_default_group", _("Exclude Default Group"), _("Exclude DNS Server from default group.")) + o.rmempty = false; + o.default = o.disabled; + o.editable = true; o.modalonly = true; // blacklist_ip @@ -393,7 +518,7 @@ return view.extend({ // SNI host name o = s.taboption("advanced", form.Value, "host_name", _("TLS SNI name"), - _("Sets the server name indication for query.")) + _("Sets the server name indication for query. '-' for disable SNI name.")) o.default = "" o.datatype = "hostname" o.rempty = true @@ -428,13 +553,155 @@ return view.extend({ o.rempty = true o.modalonly = true; - // Doman addresss; - s = m.section(form.TypedSection, "smartdns", _("Advanced Settings"), _("Advanced Settings")); + //////////////// + // domain rules; + //////////////// + s = m.section(form.TypedSection, "domain-rule", _("Domain Rules"), _("Domain Rules Settings")); s.anonymous = true; + s.nodescriptions = true; + s.tab("forwarding", _('DNS Forwarding Setting')); + s.tab("block", _("DNS Block Setting")); s.tab("domain-address", _("Domain Address"), _("Set Specific domain ip address.")); s.tab("blackip-list", _("IP Blacklist"), _("Set Specific ip blacklist.")); + /////////////////////////////////////// + // domain forwarding; + /////////////////////////////////////// + o = s.taboption("forwarding", form.Value, "server_group", _("Server Group"), _("DNS Server group belongs to, such as office, home.")) + o.rmempty = true + o.placeholder = "default" + o.datatype = "hostname" + o.rempty = true + for (const groupname of groupnames) { + o.value(groupname); + } + o.validate = function (section_id, value) { + if (value == "") { + return true; + } + + var val = uci.sections('smartdns', 'server'); + for (var i = 0; i < val.length; i++) { + if (value == val[i].server_group) { + return true; + } + } + + return _('Server Group %s not exists').format(value); + + } + + o = s.taboption("forwarding", form.Flag, "no_speed_check", _("Skip Speed Check"), + _("Do not check speed.")); + o.rmempty = false; + o.default = o.disabled; + + o = s.taboption("forwarding", form.Flag, "force_aaaa_soa", _("Force AAAA SOA"), _("Force AAAA SOA.")); + o.rmempty = false; + o.default = o.disabled; + + o = s.taboption("forwarding", form.Value, "ipset_name", _("IPset Name"), _("IPset name.")); + o.rmempty = true; + o.datatype = "hostname"; + o.rempty = true; + + o = s.taboption("forwarding", form.Value, "nftset_name", _("NFTset Name"), _("NFTset name, format: [#[4|6]:[family#table#set]]")); + o.rmempty = true; + o.datatype = "string"; + o.rempty = true; + o.validate = function (section_id, value) { + if (value == "") { + return true; + } + + var nftset = value.split(",") + for (var i = 0; i < nftset.length; i++) { + if (!nftset[i].match(/#[4|6]:[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+#[a-zA-Z0-9\-_]+$/)) { + return _("NFTset name format error, format: [#[4|6]:[family#table#set]]"); + } + } + + return true; + } + + o = s.taboption("forwarding", form.FileUpload, "forwarding_domain_set_file", _("Domain List File"), + _("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", form.TextValue, "domain_forwarding_list", + _("Domain List"), _("Configure forwarding domain name list.")); + o.rows = 10; + o.cols = 64; + o.monospace = true; + o.cfgvalue = function (section_id) { + return fs.trimmed('/etc/smartdns/domain-forwarding.list').catch(function (e) { + return ""; + }); + }; + o.write = function (section_id, formvalue) { + return this.cfgvalue(section_id).then(function (value) { + if (value == formvalue) { + return + } + return fs.write('/etc/smartdns/domain-forwarding.list', formvalue.trim().replace(/\r\n/g, '\n') + '\n'); + }); + }; + + /////////////////////////////////////// + // domain block; + /////////////////////////////////////// + o = s.taboption("block", form.FileUpload, "block_domain_set_file", _("Domain List File"), _("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", form.TextValue, "domain_block_list", + _("Domain List"), _("Configure block domain list.")); + o.rows = 10; + o.cols = 64; + o.cfgvalue = function (section_id) { + return fs.trimmed('/etc/smartdns/domain-block.list').catch(function (e) { + return ""; + }); + }; + o.write = function (section_id, formvalue) { + return this.cfgvalue(section_id).then(function (value) { + if (value == formvalue) { + return + } + return fs.write('/etc/smartdns/domain-block.list', 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 this.cfgvalue(section_id).then(function (value) { + if (value == formvalue) { + return + } + return fs.write('/etc/smartdns/blacklist-ip.conf', formvalue.trim().replace(/\r\n/g, '\n') + '\n'); + }); + }; + + /////////////////////////////////////// + // domain address + /////////////////////////////////////// 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 " @@ -452,24 +719,9 @@ return view.extend({ }); }; - // 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 this.cfgvalue(section_id).then(function (value) { - if (value == formvalue) { - return - } - return fs.write('/etc/smartdns/blacklist-ip.conf', formvalue.trim().replace(/\r\n/g, '\n') + '\n'); - }); - }; - - // Doman addresss; + //////////////// + // Support + //////////////// s = m.section(form.TypedSection, "smartdns", _("Technical Support"), _("If you like this software, please buy me a cup of coffee.")); s.anonymous = true; diff --git a/package/openwrt/domain-block.list b/package/openwrt/domain-block.list new file mode 100644 index 0000000..4183bd4 --- /dev/null +++ b/package/openwrt/domain-block.list @@ -0,0 +1,4 @@ +# domain block list, one domain name per line. +# example: block a.com, and b.com +# a.com +# b.com \ No newline at end of file diff --git a/package/openwrt/domain-forwarding.list b/package/openwrt/domain-forwarding.list new file mode 100644 index 0000000..d52b341 --- /dev/null +++ b/package/openwrt/domain-forwarding.list @@ -0,0 +1,4 @@ +# domain forwarding list, one domain name per line. +# example: forwarding a.com, and b.com +# a.com +# b.com \ No newline at end of file diff --git a/package/openwrt/files/etc/config/smartdns b/package/openwrt/files/etc/config/smartdns index df473c8..9a72bc0 100644 --- a/package/openwrt/files/etc/config/smartdns +++ b/package/openwrt/files/etc/config/smartdns @@ -1,3 +1,4 @@ config 'smartdns' option 'enabled' '0' - \ No newline at end of file + +config 'domain-rule' \ No newline at end of file diff --git a/package/openwrt/files/etc/init.d/smartdns b/package/openwrt/files/etc/init.d/smartdns index 35496fe..ab49796 100644 --- a/package/openwrt/files/etc/init.d/smartdns +++ b/package/openwrt/files/etc/init.d/smartdns @@ -23,12 +23,16 @@ SERVICE_WRITE_PID=1 SERVICE_DAEMONIZE=1 SERVICE_PID_FILE="/var/run/smartdns.pid" SMARTDNS_CONF_DIR="/etc/smartdns" +SMARTDNS_CONF_DOWNLOAD_DIR="$SMARTDNS_CONF_DIR/conf.d" +SMARTDNS_DOMAIN_LIST_DOWNLOAD_DIR="$SMARTDNS_CONF_DIR/domain-set" SMARTDNS_VAR_CONF_DIR="/var/etc/smartdns" SMARTDNS_CONF="$SMARTDNS_VAR_CONF_DIR/smartdns.conf" ADDRESS_CONF="$SMARTDNS_CONF_DIR/address.conf" BLACKLIST_IP_CONF="$SMARTDNS_CONF_DIR/blacklist-ip.conf" CUSTOM_CONF="$SMARTDNS_CONF_DIR/custom.conf" SMARTDNS_CONF_TMP="${SMARTDNS_CONF}.tmp" +EXTRA_COMMANDS="updatefiles" +EXTRA_HELP=" updatefiles Update files" COREDUMP="0" RESPAWN="1" DO_RELOAD="0" @@ -174,6 +178,7 @@ load_server() config_get host_name "$section" "host_name" "" config_get http_host "$section" "http_host" "" config_get server_group "$section" "server_group" "" + config_get_bool exclude_default_group "$section" "exclude_default_group" "0" config_get blacklist_ip "$section" "blacklist_ip" "0" config_get check_edns "$section" "check_edns" "0" config_get spki_pin "$section" "spki_pin" "" @@ -205,6 +210,7 @@ load_server() [ -z "$host_name" ] || ADDITIONAL_ARGS="$ADDITIONAL_ARGS -host-name $host_name" [ -z "$http_host" ] || ADDITIONAL_ARGS="$ADDITIONAL_ARGS -http-host $http_host" [ -z "$server_group" ] || ADDITIONAL_ARGS="$ADDITIONAL_ARGS -group $server_group" + [ "$exclude_default_group" = "0" ] || ADDITIONAL_ARGS="$ADDITIONAL_ARGS -exclude-default-group" [ "$blacklist_ip" = "0" ] || ADDITIONAL_ARGS="$ADDITIONAL_ARGS -blacklist-ip" [ "$check_edns" = "0" ] || ADDITIONAL_ARGS="$ADDITIONAL_ARGS -check-edns" [ -z "$spki_pin" ] || ADDITIONAL_ARGS="$ADDITIONAL_ARGS -spki-pin $spki_pin" @@ -220,6 +226,80 @@ load_server() conf_append "$SERVER" "$DNS_ADDRESS $ADDITIONAL_ARGS $addition_arg" } +restart_crond() +{ + /etc/init.d/cron restart >/dev/null 2>&1 +} + +disable_auto_update() +{ + local no_restart="$1" + grep "/etc/init.d/smartdns" /etc/crontabs/root 1>/dev/null 2>&1 + if [ $? -ne 0 ]; then + return + fi + + sed -i '\@/etc/init.d/smartdns@d' /etc/crontabs/root + + if [ "$no_restart" = "1" ]; then + return + fi + + restart_crond +} + +enable_auto_update() +{ + grep "0 5 * * * /etc/init.d/smartdns updatefiles" /etc/crontabs/root 2>/dev/null + if [ $? -eq 0 ]; then + return + fi + + disable_auto_update 1 + echo "0 5 * * * /etc/init.d/smartdns updatefiles" >> /etc/crontabs/root + restart_crond +} + +load_domain_rules() +{ + local section="$1" + local domain_set_args="" + local domain_set_name="domain" + + config_get server_group "$section" "server_group" "" + [ ! -z "$server_group" ] && domain_set_args="$domain_set_args -nameserver $server_group" + + config_get_bool no_speed_check "$section" "no_speed_check" "0" + [ "$no_speed_check" = "1" ] && domain_set_args="$domain_set_args -speed-check-mode none" + + config_get_bool force_aaaa_soa "$section" "force_aaaa_soa" "0" + [ "$force_aaaa_soa" = "1" ] && domain_set_args="$domain_set_args -address #6" + + config_get ipset_name "$section" "ipset_name" "" + [ ! -z "$ipset_name" ] && domain_set_args="$domain_set_args -ipset $ipset_name" + + config_get ipset_name "$section" "nftset_name" "" + [ ! -z "$nftset_name" ] && domain_set_args="$domain_set_args -nftset '$nftset_name'" + + config_get forwarding_domain_set_file "$section" "forwarding_domain_set_file" "" + [ ! -z "$forwarding_domain_set_file" ] && { + conf_append "domain-set" "-name ${domain_set_name}-forwarding-file -file $forwarding_domain_set_file" + conf_append "domain-rules" "/domain-set:${domain_set_name}-forwarding-file/ $domain_set_args" + } + + conf_append "domain-set" "-name ${domain_set_name}-forwarding-list -file /etc/smartdns/domain-forwarding.list" + conf_append "domain-rules" "/domain-set:${domain_set_name}-forwarding-list/ $domain_set_args" + + config_get block_domain_set_file "$section" "block_domain_set_file" + [ ! -z "$block_domain_set_file" ] && { + conf_append "domain-set" "-name ${domain_set_name}-block-file -file $block_domain_set_file" + conf_append "domain-rules" "/domain-set:${domain_set_name}-block-file/ -group block" + } + + conf_append "domain-set" "-name ${domain_set_name}-block-list -file /etc/smartdns/domain-block.list" + conf_append "domain-rules" "/domain-set:${domain_set_name}-block-list/ --address #" +} + load_second_server() { local section="$1" @@ -270,6 +350,21 @@ load_second_server() [ "$seconddns_tcp_server" = "1" ] && conf_append "bind-tcp" "$ADDR:$seconddns_port $ARGS" } +conf_append_conf_files() +{ + local conf_file="$1" + + if [ "$1" != "${1#/}" ]; then + fullpath="$1" + else + fullpath="$SMARTDNS_CONF_DOWNLOAD_DIR/$conf_file" + fi + + [ -f "$fullpath" ] && { + conf_append "conf-file" "$fullpath" + } +} + load_service() { local section="$1" @@ -345,6 +440,9 @@ load_service() config_get log_file "$section" "log_file" "" [ -z "$log_file" ] || conf_append "log-file" "$log_file" + config_get_bool enable_auto_update "$section" "enable_auto_update" "0" + [ "$enable_auto_update" = "1" ] && enable_auto_update || disable_auto_update + config_get redirect "$section" "redirect" "" config_get old_port "$section" "old_port" "0" config_get old_enabled "$section" "old_enabled" "0" @@ -390,6 +488,7 @@ load_service() [ "$old_enabled" = "0" ] && return 1 [ "$old_port" = "53" ] && stop_main_dns "0" [ "$old_port" != "53" ] && [ "$old_auto_set_dnsmasq" = "1" ] && stop_forward_dnsmasq "$old_port" "0" + disable_auto_update return 1 } @@ -428,6 +527,10 @@ load_service() config_foreach load_server "server" + config_list_foreach "$section" "conf_files" conf_append_conf_files + + config_foreach load_domain_rules "domain-rule" + { echo "conf-file $ADDRESS_CONF" echo "conf-file $BLACKLIST_IP_CONF" @@ -473,6 +576,38 @@ unload_service() } } +download_file() { + local section="$1" + + config_get url "$section" "url" "" + config_get name "$section" "name" "" + config_get filetype "$section" "type" "" + + [ -z "$url" ] && return 0 + [ -z "$name" ] && return 0 + [ -z "$filetype" ] && return 0 + + echo "download $filetype file $name from $url" + wget --timeout 120 -q -O "/tmp/$name" "$url" + if [ $? -ne 0 ]; then + echo "download file $name failed" + return 1 + fi + + echo "download file $name success" + if [ "$filetype" = "list" ]; then + mv "/tmp/$name" "$SMARTDNS_DOMAIN_LIST_DOWNLOAD_DIR/$name" + elif [ "$filetype" = "config" ]; then + mv "/tmp/$name" "$SMARTDNS_CONF_DOWNLOAD_DIR/$name" + fi +} + +updatefiles() { + config_load "smartdns" + config_foreach download_file "download-file" + reload_service +} + service_stopped() { config_load "smartdns" diff --git a/package/openwrt/make.sh b/package/openwrt/make.sh index cca3964..f4de1c1 100755 --- a/package/openwrt/make.sh +++ b/package/openwrt/make.sh @@ -23,6 +23,8 @@ SMARTDNS_CONF=$SMARTDNS_DIR/etc/smartdns/smartdns.conf ADDRESS_CONF=$CURR_DIR/address.conf BLACKLIST_IP_CONF=$CURR_DIR/blacklist-ip.conf CUSTOM_CONF=$CURR_DIR/custom.conf +DOMAIN_BLOCK_LIST=$CURR_DIR/domain-block.list +DOMAIN_FORWARDING_LIST=$CURR_DIR/domain-forwarding.list showhelp() { @@ -45,11 +47,15 @@ build() mkdir $ROOT/root/usr/sbin -p mkdir $ROOT/root/etc/init.d -p mkdir $ROOT/root/etc/smartdns/ -p + mkdir $ROOT/root/etc/smartdns/domain-set/ -p + mkdir $ROOT/root/etc/smartdns/conf.d/ -p cp $SMARTDNS_CONF $ROOT/root/etc/smartdns/ cp $ADDRESS_CONF $ROOT/root/etc/smartdns/ cp $BLACKLIST_IP_CONF $ROOT/root/etc/smartdns/ cp $CUSTOM_CONF $ROOT/root/etc/smartdns/ + cp $DOMAIN_BLOCK_LIST $ROOT/root/etc/smartdns/ + cp $DOMAIN_FORWARDING_LIST $ROOT/root/etc/smartdns/ cp $CURR_DIR/files/etc $ROOT/root/ -af cp $SMARTDNS_BIN $ROOT/root/usr/sbin if [ $? -ne 0 ]; then