diff --git a/package/luci-compat/files/luci/i18n/smartdns.zh-cn.po b/package/luci-compat/files/luci/i18n/smartdns.zh-cn.po
index cd1ca6a..cf6670f 100644
--- a/package/luci-compat/files/luci/i18n/smartdns.zh-cn.po
+++ b/package/luci-compat/files/luci/i18n/smartdns.zh-cn.po
@@ -22,7 +22,7 @@ msgstr "自动设置为Dnsmasq的上游服务器"
msgid "Cache Size"
msgstr "缓存大小"
-msgid "Collecting data ..."
+msgid "Collecting data..."
msgstr "正在收集数据..."
msgid ""
@@ -30,12 +30,27 @@ 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, such as office, home."
+msgstr "配置归属服务器组,例如office, home"
+
msgid ""
"DNS Server group belongs to, used with nameserver, such as office, home."
msgstr "DNS服务器所属组, 配合nameserver使用,例如:office,home。"
@@ -52,8 +67,8 @@ msgstr "协议类型"
msgid "DNS domain result cache size"
msgstr "缓存DNS的结果,缓存大小,配置零则不缓存"
-msgid "Dnsmasq Forwared To Smartdns Failure"
-msgstr "重定向dnsmasq到smartdns失败"
+msgid "Description"
+msgstr "描述"
msgid "Do not check certificate."
msgstr "不校验证书的合法性。"
@@ -64,6 +79,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 +109,26 @@ 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 "下载域名文件列表,下载后刷新页面生效"
+
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 +138,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 +150,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黑名单过滤"
@@ -133,9 +189,6 @@ msgid ""
msgstr ""
"当smartdns异常时生成coredump文件,coredump文件在/tmp/smartdns.xxx.core."
-msgid "Grant access to LuCI app smartdns"
-msgstr "授予访问 LuCI 应用 smartdns 的权限"
-
msgid "HTTP Host"
msgstr "HTTP主机"
@@ -148,9 +201,26 @@ 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 "包含配置文件"
+
+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 +230,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 "未运行"
@@ -184,6 +263,12 @@ msgstr "解析本地主机名"
msgid "Resolve local hostnames by reading Dnsmasq lease file."
msgstr "读取Dnsmasq的租约文件解析本地主机名。"
+msgid "Restart"
+msgstr "重启"
+
+msgid "Restart smartdns"
+msgstr "重启服务"
+
msgid "Second Server Settings"
msgstr "第二DNS服务器"
@@ -193,6 +278,9 @@ msgstr "缓存过期服务"
msgid "Server Group"
msgstr "服务器组"
+msgid "Server Group not exists"
+msgstr "服务器组不存在"
+
msgid "Server Name"
msgstr "服务器名称"
@@ -275,7 +363,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,留空为主机名"
@@ -306,6 +395,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 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 DNS Server Configuration"
+msgstr "上游服务器配置"
+
msgid "Upstream Servers"
msgstr "上游服务器"
@@ -324,6 +445,9 @@ msgstr ""
"用于校验 TLS 服务器的有效性,数值为 Base64 编码的 SPKI 指纹,留空表示不验证 "
"TLS 的合法性。"
+msgid "domain list (/etc/smartdns/domain-set)"
+msgstr "域名列表(/etc/smartdns/domain-set)"
+
msgid "https"
msgstr "https"
@@ -336,6 +460,9 @@ msgstr "打开网站"
msgid "port"
msgstr "端口"
+msgid "smartdns config (/etc/smartdns/conf.d)"
+msgstr "配置文件(/etc/smartdns/conf.d)"
+
msgid "smartdns custom settings"
msgstr "smartdns 自定义设置,具体配置参数参考指导"
@@ -350,3 +477,6 @@ msgstr "类型"
msgid "udp"
msgstr "udp"
+
+msgid "update domain list files"
+msgstr "更新列表文件"
diff --git a/package/luci-compat/files/luci/model/cbi/smartdns/smartdns.lua b/package/luci-compat/files/luci/model/cbi/smartdns/smartdns.lua
index 9937c70..45b9479 100644
--- a/package/luci-compat/files/luci/model/cbi/smartdns/smartdns.lua
+++ b/package/luci-compat/files/luci/model/cbi/smartdns/smartdns.lua
@@ -19,6 +19,8 @@ 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.")
@@ -30,6 +32,7 @@ s = m:section(TypedSection, "smartdns", translate("Settings"), translate("Genera
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"))
@@ -69,7 +72,7 @@ o.cfgvalue = function(...)
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 = 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(...)
@@ -77,7 +80,7 @@ o.cfgvalue = function(...)
end
---- Domain prefetch load
-o = s:taboption("settings", Flag, "prefetch_domain", translate("Domain prefetch"), translate("Enable domain prefetch, accelerate domain response speed."))
+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(...)
@@ -85,7 +88,7 @@ o.cfgvalue = function(...)
end
---- Domain Serve expired
-o = s:taboption("settings", Flag, "serve_expired", translate("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
@@ -94,11 +97,11 @@ o.cfgvalue = function(...)
end
---- cache-size
-o = s:taboption("settings", Value, "cache_size", translate("Cache Size"), translate("DNS domain result 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("settings", Flag, "resolve_local_hostnames", translate("Resolve Local Hostnames"), translate("Resolve local hostnames by reading Dnsmasq lease file."));
+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(...)
@@ -106,7 +109,7 @@ o.cfgvalue = function(...)
end
-- Automatically Set Dnsmasq
-o = s:taboption("settings", Flag, "auto_set_dnsmasq", translate("Automatically Set Dnsmasq"), translate("Automatically set as upstream of dnsmasq when port changes."));
+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(...)
@@ -114,7 +117,7 @@ o.cfgvalue = function(...)
end
-- Force AAAA SOA
-o = s:taboption("settings", Flag, "force_aaaa_soa", translate("Force AAAA SOA"), translate("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(...)
@@ -122,7 +125,7 @@ o.cfgvalue = function(...)
end
-- Force HTTPS SOA
-o = s:taboption("settings", Flag, "force_https_soa", translate("Force HTTPS SOA"), translate("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(...)
@@ -130,24 +133,35 @@ o.cfgvalue = function(...)
end
---- rr-ttl
-o = s:taboption("settings", Value, "rr_ttl", translate("Domain TTL"), translate("TTL for all domain result."))
+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("settings", Value, "rr_ttl_min", translate("Domain TTL Min"), translate("Minimum TTL for all domain result."))
+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("settings", Value, "rr_ttl_max", translate("Domain TTL Max"), translate("Maximum TTL for all domain result."))
+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("settings", Value, "rr_ttl_reply_max", translate("Reply Domain TTL Max"), translate("Reply maximum TTL for all domain result."))
+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
/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."))
@@ -305,11 +319,122 @@ o:value("https", translate("https"))
o.default = "udp"
o.rempty = false
-s = m:section(TypedSection, "smartdns", translate("Advanced Settings"), translate("Advanced Settings"));
-s.anonymous = true;
+---- domain rules;
+s = m:section(TypedSection, "domain-rule", translate("Domain Rules"), translate("Domain Rules Settings"))
+s.anonymous = true
+s.nodescriptions = true
-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."));
+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",
@@ -345,6 +470,77 @@ function addr.write(self, section, value)
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."))
@@ -366,5 +562,13 @@ 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
diff --git a/package/luci-compat/files/luci/model/cbi/smartdns/upstream.lua b/package/luci-compat/files/luci/model/cbi/smartdns/upstream.lua
index 1bb612f..49faf11 100644
--- a/package/luci-compat/files/luci/model/cbi/smartdns/upstream.lua
+++ b/package/luci-compat/files/luci/model/cbi/smartdns/upstream.lua
@@ -62,6 +62,13 @@ o.placeholder = "default"
o.datatype = "hostname"
o.rempty = true
+---- exclude default group
+o = s:option(Flag, "exclude_default_group", translate("Exclude Default Group"), translate("Exclude DNS Server from default group."))
+o.rmempty = false
+o.default = o.disabled
+o.editable = true
+o.modalonly = true
+
---- blacklist_ip
o = s:option(Flag, "blacklist_ip", translate("IP Blacklist Filtering"), translate("Filtering IP with blacklist"))
o.rmempty = false
diff --git a/package/luci-compat/files/usr/share/rpcd/acl.d/luci-app-smartdns.json b/package/luci-compat/files/usr/share/rpcd/acl.d/luci-app-smartdns.json
new file mode 100644
index 0000000..8c4cd01
--- /dev/null
+++ b/package/luci-compat/files/usr/share/rpcd/acl.d/luci-app-smartdns.json
@@ -0,0 +1,22 @@
+{
+ "luci-app-smartdns": {
+ "description": "Grant access to LuCI app smartdns",
+ "read": {
+ "file": {
+ "/etc/smartdns/*": [ "read" ]
+ },
+ "ubus": {
+ "service": [ "list" ]
+ },
+ "uci": [ "smartdns" ]
+ },
+ "write": {
+ "file": {
+ "/etc/smartdns/*": [ "write" ],
+ "/etc/init.d/smartdns restart": [ "exec" ],
+ "/etc/init.d/smartdns updatefiles": [ "exec" ]
+ },
+ "uci": [ "smartdns" ]
+ }
+ }
+}
diff --git a/package/luci-compat/make.sh b/package/luci-compat/make.sh
index 1cbce90..3b87850 100755
--- a/package/luci-compat/make.sh
+++ b/package/luci-compat/make.sh
@@ -54,6 +54,7 @@ build()
build_tool
mkdir $ROOT/root/usr/lib/lua/ -p
cp $ROOT/files/luci $ROOT/root/usr/lib/lua/ -af
+ cp $ROOT/files/usr $ROOT/root/ -af
#Generate Language
$PO2LMO $ROOT/files/luci/i18n/smartdns.zh-cn.po $ROOT/root/usr/lib/lua/luci/i18n/smartdns.zh-cn.lmo