luci: unified code style (#2395)
* luci: unified code style - checked newline at end of file - unified indent - removed whitespaces at end of line * luci: change the indentation of lua files to tabs
This commit is contained in:
parent
5e84915db1
commit
36c6425b3f
@ -22,12 +22,12 @@ s.anonymous = true
|
|||||||
s.addremove = true
|
s.addremove = true
|
||||||
s.extedit = api.url("acl_config", "%s")
|
s.extedit = api.url("acl_config", "%s")
|
||||||
function s.create(e, t)
|
function s.create(e, t)
|
||||||
t = TypedSection.create(e, t)
|
t = TypedSection.create(e, t)
|
||||||
luci.http.redirect(e.extedit:format(t))
|
luci.http.redirect(e.extedit:format(t))
|
||||||
end
|
end
|
||||||
function s.remove(e, t)
|
function s.remove(e, t)
|
||||||
sys.call("rm -rf /tmp/etc/passwall_tmp/dns_" .. t .. "*")
|
sys.call("rm -rf /tmp/etc/passwall_tmp/dns_" .. t .. "*")
|
||||||
TypedSection.remove(e, t)
|
TypedSection.remove(e, t)
|
||||||
end
|
end
|
||||||
|
|
||||||
---- Enable
|
---- Enable
|
||||||
@ -41,28 +41,28 @@ o.rmempty = true
|
|||||||
|
|
||||||
local mac_t = {}
|
local mac_t = {}
|
||||||
sys.net.mac_hints(function(e, t)
|
sys.net.mac_hints(function(e, t)
|
||||||
mac_t[e] = {
|
mac_t[e] = {
|
||||||
ip = t,
|
ip = t,
|
||||||
mac = e
|
mac = e
|
||||||
}
|
}
|
||||||
end)
|
end)
|
||||||
|
|
||||||
o = s:option(DummyValue, "sources", translate("Source"))
|
o = s:option(DummyValue, "sources", translate("Source"))
|
||||||
o.rawhtml = true
|
o.rawhtml = true
|
||||||
o.cfgvalue = function(t, n)
|
o.cfgvalue = function(t, n)
|
||||||
local e = ''
|
local e = ''
|
||||||
local v = Value.cfgvalue(t, n) or ''
|
local v = Value.cfgvalue(t, n) or ''
|
||||||
string.gsub(v, '[^' .. " " .. ']+', function(w)
|
string.gsub(v, '[^' .. " " .. ']+', function(w)
|
||||||
local a = w
|
local a = w
|
||||||
if mac_t[w] then
|
if mac_t[w] then
|
||||||
a = a .. ' (' .. mac_t[w].ip .. ')'
|
a = a .. ' (' .. mac_t[w].ip .. ')'
|
||||||
end
|
end
|
||||||
if #e > 0 then
|
if #e > 0 then
|
||||||
e = e .. "<br />"
|
e = e .. "<br />"
|
||||||
end
|
end
|
||||||
e = e .. a
|
e = e .. a
|
||||||
end)
|
end)
|
||||||
return e
|
return e
|
||||||
end
|
end
|
||||||
|
|
||||||
---- TCP Proxy Mode
|
---- TCP Proxy Mode
|
||||||
@ -73,10 +73,10 @@ tcp_proxy_mode:value("default", translate("Default"))
|
|||||||
tcp_proxy_mode:value("disable", translate("No Proxy"))
|
tcp_proxy_mode:value("disable", translate("No Proxy"))
|
||||||
tcp_proxy_mode:value("global", translate("Global Proxy"))
|
tcp_proxy_mode:value("global", translate("Global Proxy"))
|
||||||
if has_chnlist and global_proxy_mode:find("returnhome") then
|
if has_chnlist and global_proxy_mode:find("returnhome") then
|
||||||
tcp_proxy_mode:value("returnhome", translate("China List"))
|
tcp_proxy_mode:value("returnhome", translate("China List"))
|
||||||
else
|
else
|
||||||
tcp_proxy_mode:value("gfwlist", translate("GFW List"))
|
tcp_proxy_mode:value("gfwlist", translate("GFW List"))
|
||||||
tcp_proxy_mode:value("chnroute", translate("Not China List"))
|
tcp_proxy_mode:value("chnroute", translate("Not China List"))
|
||||||
end
|
end
|
||||||
tcp_proxy_mode:value("direct/proxy", translate("Only use direct/proxy list"))
|
tcp_proxy_mode:value("direct/proxy", translate("Only use direct/proxy list"))
|
||||||
|
|
||||||
@ -88,10 +88,10 @@ udp_proxy_mode:value("default", translate("Default"))
|
|||||||
udp_proxy_mode:value("disable", translate("No Proxy"))
|
udp_proxy_mode:value("disable", translate("No Proxy"))
|
||||||
udp_proxy_mode:value("global", translate("Global Proxy"))
|
udp_proxy_mode:value("global", translate("Global Proxy"))
|
||||||
if has_chnlist and global_proxy_mode:find("returnhome") then
|
if has_chnlist and global_proxy_mode:find("returnhome") then
|
||||||
udp_proxy_mode:value("returnhome", translate("China List"))
|
udp_proxy_mode:value("returnhome", translate("China List"))
|
||||||
else
|
else
|
||||||
udp_proxy_mode:value("gfwlist", translate("GFW List"))
|
udp_proxy_mode:value("gfwlist", translate("GFW List"))
|
||||||
udp_proxy_mode:value("chnroute", translate("Not China List"))
|
udp_proxy_mode:value("chnroute", translate("Not China List"))
|
||||||
end
|
end
|
||||||
udp_proxy_mode:value("direct/proxy", translate("Only use direct/proxy list"))
|
udp_proxy_mode:value("direct/proxy", translate("Only use direct/proxy list"))
|
||||||
|
|
||||||
|
@ -9,28 +9,28 @@ m = Map(appname)
|
|||||||
|
|
||||||
local nodes_table = {}
|
local nodes_table = {}
|
||||||
for k, e in ipairs(api.get_valid_nodes()) do
|
for k, e in ipairs(api.get_valid_nodes()) do
|
||||||
nodes_table[#nodes_table + 1] = e
|
nodes_table[#nodes_table + 1] = e
|
||||||
end
|
end
|
||||||
|
|
||||||
local global_proxy_mode = (m:get("@global[0]", "tcp_proxy_mode") or "") .. (m:get("@global[0]", "udp_proxy_mode") or "")
|
local global_proxy_mode = (m:get("@global[0]", "tcp_proxy_mode") or "") .. (m:get("@global[0]", "udp_proxy_mode") or "")
|
||||||
|
|
||||||
local dynamicList_write = function(self, section, value)
|
local dynamicList_write = function(self, section, value)
|
||||||
local t = {}
|
local t = {}
|
||||||
local t2 = {}
|
local t2 = {}
|
||||||
if type(value) == "table" then
|
if type(value) == "table" then
|
||||||
local x
|
local x
|
||||||
for _, x in ipairs(value) do
|
for _, x in ipairs(value) do
|
||||||
if x and #x > 0 then
|
if x and #x > 0 then
|
||||||
if not t2[x] then
|
if not t2[x] then
|
||||||
t2[x] = x
|
t2[x] = x
|
||||||
t[#t+1] = x
|
t[#t+1] = x
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
t = { value }
|
t = { value }
|
||||||
end
|
end
|
||||||
t = table.concat(t, " ")
|
t = table.concat(t, " ")
|
||||||
return DynamicList.write(self, section, t)
|
return DynamicList.write(self, section, t)
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -51,22 +51,22 @@ o.rmempty = true
|
|||||||
|
|
||||||
local mac_t = {}
|
local mac_t = {}
|
||||||
sys.net.mac_hints(function(e, t)
|
sys.net.mac_hints(function(e, t)
|
||||||
mac_t[#mac_t + 1] = {
|
mac_t[#mac_t + 1] = {
|
||||||
ip = t,
|
ip = t,
|
||||||
mac = e
|
mac = e
|
||||||
}
|
}
|
||||||
end)
|
end)
|
||||||
table.sort(mac_t, function(a,b)
|
table.sort(mac_t, function(a,b)
|
||||||
if #a.ip < #b.ip then
|
if #a.ip < #b.ip then
|
||||||
return true
|
return true
|
||||||
elseif #a.ip == #b.ip then
|
elseif #a.ip == #b.ip then
|
||||||
if a.ip < b.ip then
|
if a.ip < b.ip then
|
||||||
return true
|
return true
|
||||||
else
|
else
|
||||||
return #a.ip < #b.ip
|
return #a.ip < #b.ip
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end)
|
end)
|
||||||
|
|
||||||
---- Source
|
---- Source
|
||||||
@ -80,58 +80,58 @@ sources.description = "<ul><li>" .. translate("Example:")
|
|||||||
.. "</li></ul>"
|
.. "</li></ul>"
|
||||||
sources.cast = "string"
|
sources.cast = "string"
|
||||||
for _, key in pairs(mac_t) do
|
for _, key in pairs(mac_t) do
|
||||||
sources:value(key.mac, "%s (%s)" % {key.mac, key.ip})
|
sources:value(key.mac, "%s (%s)" % {key.mac, key.ip})
|
||||||
end
|
end
|
||||||
sources.cfgvalue = function(self, section)
|
sources.cfgvalue = function(self, section)
|
||||||
local value
|
local value
|
||||||
if self.tag_error[section] then
|
if self.tag_error[section] then
|
||||||
value = self:formvalue(section)
|
value = self:formvalue(section)
|
||||||
else
|
else
|
||||||
value = self.map:get(section, self.option)
|
value = self.map:get(section, self.option)
|
||||||
if type(value) == "string" then
|
if type(value) == "string" then
|
||||||
local value2 = {}
|
local value2 = {}
|
||||||
string.gsub(value, '[^' .. " " .. ']+', function(w) table.insert(value2, w) end)
|
string.gsub(value, '[^' .. " " .. ']+', function(w) table.insert(value2, w) end)
|
||||||
value = value2
|
value = value2
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
sources.validate = function(self, value, t)
|
sources.validate = function(self, value, t)
|
||||||
local err = {}
|
local err = {}
|
||||||
for _, v in ipairs(value) do
|
for _, v in ipairs(value) do
|
||||||
local flag = false
|
local flag = false
|
||||||
if v:find("ipset:") and v:find("ipset:") == 1 then
|
if v:find("ipset:") and v:find("ipset:") == 1 then
|
||||||
local ipset = v:gsub("ipset:", "")
|
local ipset = v:gsub("ipset:", "")
|
||||||
if ipset and ipset ~= "" then
|
if ipset and ipset ~= "" then
|
||||||
flag = true
|
flag = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if flag == false and datatypes.macaddr(v) then
|
if flag == false and datatypes.macaddr(v) then
|
||||||
flag = true
|
flag = true
|
||||||
end
|
end
|
||||||
|
|
||||||
if flag == false and datatypes.ip4addr(v) then
|
if flag == false and datatypes.ip4addr(v) then
|
||||||
flag = true
|
flag = true
|
||||||
end
|
end
|
||||||
|
|
||||||
if flag == false and api.iprange(v) then
|
if flag == false and api.iprange(v) then
|
||||||
flag = true
|
flag = true
|
||||||
end
|
end
|
||||||
|
|
||||||
if flag == false then
|
if flag == false then
|
||||||
err[#err + 1] = v
|
err[#err + 1] = v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if #err > 0 then
|
if #err > 0 then
|
||||||
self:add_error(t, "invalid", translate("Not true format, please re-enter!"))
|
self:add_error(t, "invalid", translate("Not true format, please re-enter!"))
|
||||||
for _, v in ipairs(err) do
|
for _, v in ipairs(err) do
|
||||||
self:add_error(t, "invalid", v)
|
self:add_error(t, "invalid", v)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
sources.write = dynamicList_write
|
sources.write = dynamicList_write
|
||||||
|
|
||||||
@ -186,10 +186,10 @@ tcp_proxy_mode:value("default", translate("Default"))
|
|||||||
tcp_proxy_mode:value("disable", translate("No Proxy"))
|
tcp_proxy_mode:value("disable", translate("No Proxy"))
|
||||||
tcp_proxy_mode:value("global", translate("Global Proxy"))
|
tcp_proxy_mode:value("global", translate("Global Proxy"))
|
||||||
if has_chnlist and global_proxy_mode:find("returnhome") then
|
if has_chnlist and global_proxy_mode:find("returnhome") then
|
||||||
tcp_proxy_mode:value("returnhome", translate("China List"))
|
tcp_proxy_mode:value("returnhome", translate("China List"))
|
||||||
else
|
else
|
||||||
tcp_proxy_mode:value("gfwlist", translate("GFW List"))
|
tcp_proxy_mode:value("gfwlist", translate("GFW List"))
|
||||||
tcp_proxy_mode:value("chnroute", translate("Not China List"))
|
tcp_proxy_mode:value("chnroute", translate("Not China List"))
|
||||||
end
|
end
|
||||||
tcp_proxy_mode:value("direct/proxy", translate("Only use direct/proxy list"))
|
tcp_proxy_mode:value("direct/proxy", translate("Only use direct/proxy list"))
|
||||||
|
|
||||||
@ -201,10 +201,10 @@ udp_proxy_mode:value("default", translate("Default"))
|
|||||||
udp_proxy_mode:value("disable", translate("No Proxy"))
|
udp_proxy_mode:value("disable", translate("No Proxy"))
|
||||||
udp_proxy_mode:value("global", translate("Global Proxy"))
|
udp_proxy_mode:value("global", translate("Global Proxy"))
|
||||||
if has_chnlist and global_proxy_mode:find("returnhome") then
|
if has_chnlist and global_proxy_mode:find("returnhome") then
|
||||||
udp_proxy_mode:value("returnhome", translate("China List"))
|
udp_proxy_mode:value("returnhome", translate("China List"))
|
||||||
else
|
else
|
||||||
udp_proxy_mode:value("gfwlist", translate("GFW List"))
|
udp_proxy_mode:value("gfwlist", translate("GFW List"))
|
||||||
udp_proxy_mode:value("chnroute", translate("Not China List"))
|
udp_proxy_mode:value("chnroute", translate("Not China List"))
|
||||||
end
|
end
|
||||||
udp_proxy_mode:value("direct/proxy", translate("Only use direct/proxy list"))
|
udp_proxy_mode:value("direct/proxy", translate("Only use direct/proxy list"))
|
||||||
|
|
||||||
@ -218,8 +218,8 @@ udp_node:value("default", translate("Default"))
|
|||||||
udp_node:value("tcp", translate("Same as the tcp node"))
|
udp_node:value("tcp", translate("Same as the tcp node"))
|
||||||
|
|
||||||
for k, v in pairs(nodes_table) do
|
for k, v in pairs(nodes_table) do
|
||||||
tcp_node:value(v.id, v["remark"])
|
tcp_node:value(v.id, v["remark"])
|
||||||
udp_node:value(v.id, v["remark"])
|
udp_node:value(v.id, v["remark"])
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:option(Flag, "filter_proxy_ipv6", translate("Filter Proxy Host IPv6"), translate("Experimental feature."))
|
o = s:option(Flag, "filter_proxy_ipv6", translate("Filter Proxy Host IPv6"), translate("Experimental feature."))
|
||||||
@ -230,10 +230,10 @@ o:depends({ tcp_node = "default", ['!reverse'] = true })
|
|||||||
o = s:option(ListValue, "dns_mode", translate("Filter Mode"))
|
o = s:option(ListValue, "dns_mode", translate("Filter Mode"))
|
||||||
o:depends({ tcp_node = "default", ['!reverse'] = true })
|
o:depends({ tcp_node = "default", ['!reverse'] = true })
|
||||||
if api.is_finded("dns2socks") then
|
if api.is_finded("dns2socks") then
|
||||||
o:value("dns2socks", "dns2socks")
|
o:value("dns2socks", "dns2socks")
|
||||||
end
|
end
|
||||||
if has_xray then
|
if has_xray then
|
||||||
o:value("xray", "Xray")
|
o:value("xray", "Xray")
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:option(ListValue, "v2ray_dns_mode", " ")
|
o = s:option(ListValue, "v2ray_dns_mode", " ")
|
||||||
@ -255,40 +255,40 @@ o:depends("dns_mode", "dns2socks")
|
|||||||
o:depends("v2ray_dns_mode", "tcp")
|
o:depends("v2ray_dns_mode", "tcp")
|
||||||
|
|
||||||
if has_v2ray or has_xray then
|
if has_v2ray or has_xray then
|
||||||
o = s:option(Value, "remote_dns_doh", translate("Remote DNS DoH"))
|
o = s:option(Value, "remote_dns_doh", translate("Remote DNS DoH"))
|
||||||
o:value("https://1.1.1.1/dns-query", "CloudFlare")
|
o:value("https://1.1.1.1/dns-query", "CloudFlare")
|
||||||
o:value("https://1.1.1.2/dns-query", "CloudFlare-Security")
|
o:value("https://1.1.1.2/dns-query", "CloudFlare-Security")
|
||||||
o:value("https://8.8.4.4/dns-query", "Google 8844")
|
o:value("https://8.8.4.4/dns-query", "Google 8844")
|
||||||
o:value("https://8.8.8.8/dns-query", "Google 8888")
|
o:value("https://8.8.8.8/dns-query", "Google 8888")
|
||||||
o:value("https://9.9.9.9/dns-query", "Quad9-Recommended")
|
o:value("https://9.9.9.9/dns-query", "Quad9-Recommended")
|
||||||
o:value("https://208.67.222.222/dns-query", "OpenDNS")
|
o:value("https://208.67.222.222/dns-query", "OpenDNS")
|
||||||
o:value("https://dns.adguard.com/dns-query,176.103.130.130", "AdGuard")
|
o:value("https://dns.adguard.com/dns-query,176.103.130.130", "AdGuard")
|
||||||
o:value("https://doh.libredns.gr/dns-query,116.202.176.26", "LibreDNS")
|
o:value("https://doh.libredns.gr/dns-query,116.202.176.26", "LibreDNS")
|
||||||
o:value("https://doh.libredns.gr/ads,116.202.176.26", "LibreDNS (No Ads)")
|
o:value("https://doh.libredns.gr/ads,116.202.176.26", "LibreDNS (No Ads)")
|
||||||
o.default = "https://1.1.1.1/dns-query"
|
o.default = "https://1.1.1.1/dns-query"
|
||||||
o.validate = function(self, value, t)
|
o.validate = function(self, value, t)
|
||||||
if value ~= "" then
|
if value ~= "" then
|
||||||
value = api.trim(value)
|
value = api.trim(value)
|
||||||
local flag = 0
|
local flag = 0
|
||||||
local util = require "luci.util"
|
local util = require "luci.util"
|
||||||
local val = util.split(value, ",")
|
local val = util.split(value, ",")
|
||||||
local url = val[1]
|
local url = val[1]
|
||||||
val[1] = nil
|
val[1] = nil
|
||||||
for i = 1, #val do
|
for i = 1, #val do
|
||||||
local v = val[i]
|
local v = val[i]
|
||||||
if v then
|
if v then
|
||||||
if not api.datatypes.ipmask4(v) then
|
if not api.datatypes.ipmask4(v) then
|
||||||
flag = 1
|
flag = 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if flag == 0 then
|
if flag == 0 then
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return nil, translate("DoH request address") .. " " .. translate("Format must be:") .. " URL,IP"
|
return nil, translate("DoH request address") .. " " .. translate("Format must be:") .. " URL,IP"
|
||||||
end
|
end
|
||||||
o:depends("v2ray_dns_mode", "doh")
|
o:depends("v2ray_dns_mode", "doh")
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:option(Value, "dns_client_ip", translate("EDNS Client Subnet"))
|
o = s:option(Value, "dns_client_ip", translate("EDNS Client Subnet"))
|
||||||
@ -296,20 +296,20 @@ o.datatype = "ipaddr"
|
|||||||
o:depends("v2ray_dns_mode", "doh")
|
o:depends("v2ray_dns_mode", "doh")
|
||||||
|
|
||||||
if has_chnlist then
|
if has_chnlist then
|
||||||
when_chnroute_default_dns = s:option(ListValue, "when_chnroute_default_dns", translate("When using the chnroute list the default DNS"))
|
when_chnroute_default_dns = s:option(ListValue, "when_chnroute_default_dns", translate("When using the chnroute list the default DNS"))
|
||||||
when_chnroute_default_dns.default = "direct"
|
when_chnroute_default_dns.default = "direct"
|
||||||
when_chnroute_default_dns:value("remote", translate("Remote DNS"))
|
when_chnroute_default_dns:value("remote", translate("Remote DNS"))
|
||||||
when_chnroute_default_dns:value("direct", translate("Direct DNS"))
|
when_chnroute_default_dns:value("direct", translate("Direct DNS"))
|
||||||
when_chnroute_default_dns.description = "<ul>"
|
when_chnroute_default_dns.description = "<ul>"
|
||||||
.. "<li>" .. translate("Remote DNS can avoid more DNS leaks, but some domestic domain names maybe to proxy!") .. "</li>"
|
.. "<li>" .. translate("Remote DNS can avoid more DNS leaks, but some domestic domain names maybe to proxy!") .. "</li>"
|
||||||
.. "<li>" .. translate("Direct DNS Internet experience may be better, but DNS will be leaked!") .. "</li>"
|
.. "<li>" .. translate("Direct DNS Internet experience may be better, but DNS will be leaked!") .. "</li>"
|
||||||
if api.is_finded("chinadns-ng") then
|
if api.is_finded("chinadns-ng") then
|
||||||
when_chnroute_default_dns:value("chinadns_ng", translate("ChinaDNS-NG"))
|
when_chnroute_default_dns:value("chinadns_ng", translate("ChinaDNS-NG"))
|
||||||
when_chnroute_default_dns.default = "chinadns_ng"
|
when_chnroute_default_dns.default = "chinadns_ng"
|
||||||
end
|
end
|
||||||
when_chnroute_default_dns.description = when_chnroute_default_dns.description .. "</li></ul>"
|
when_chnroute_default_dns.description = when_chnroute_default_dns.description .. "</li></ul>"
|
||||||
when_chnroute_default_dns:depends("tcp_proxy_mode", "chnroute")
|
when_chnroute_default_dns:depends("tcp_proxy_mode", "chnroute")
|
||||||
when_chnroute_default_dns:depends("udp_proxy_mode", "chnroute")
|
when_chnroute_default_dns:depends("udp_proxy_mode", "chnroute")
|
||||||
end
|
end
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
@ -5,24 +5,24 @@ m = Map(appname)
|
|||||||
|
|
||||||
-- [[ App Settings ]]--
|
-- [[ App Settings ]]--
|
||||||
s = m:section(TypedSection, "global_app", translate("App Update"),
|
s = m:section(TypedSection, "global_app", translate("App Update"),
|
||||||
"<font color='red'>" ..
|
"<font color='red'>" ..
|
||||||
translate("Please confirm that your firmware supports FPU.") ..
|
translate("Please confirm that your firmware supports FPU.") ..
|
||||||
"</font>")
|
"</font>")
|
||||||
s.anonymous = true
|
s.anonymous = true
|
||||||
s:append(Template(appname .. "/app_update/app_version"))
|
s:append(Template(appname .. "/app_update/app_version"))
|
||||||
|
|
||||||
local k, v
|
local k, v
|
||||||
local com = require "luci.passwall.com"
|
local com = require "luci.passwall.com"
|
||||||
for k, v in pairs(com) do
|
for k, v in pairs(com) do
|
||||||
o = s:option(Value, k:gsub("%-","_") .. "_file", translatef("%s App Path", v.name))
|
o = s:option(Value, k:gsub("%-","_") .. "_file", translatef("%s App Path", v.name))
|
||||||
o.default = v.default_path or ("/usr/bin/"..k)
|
o.default = v.default_path or ("/usr/bin/"..k)
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:option(DummyValue, "tips", " ")
|
o = s:option(DummyValue, "tips", " ")
|
||||||
o.rawhtml = true
|
o.rawhtml = true
|
||||||
o.cfgvalue = function(t, n)
|
o.cfgvalue = function(t, n)
|
||||||
return string.format('<font color="red">%s</font>', translate("if you want to run from memory, change the path, /tmp beginning then save the application and update it manually."))
|
return string.format('<font color="red">%s</font>', translate("if you want to run from memory, change the path, /tmp beginning then save the application and update it manually."))
|
||||||
end
|
end
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
@ -3,7 +3,7 @@ local appname = api.appname
|
|||||||
|
|
||||||
local nodes_table = {}
|
local nodes_table = {}
|
||||||
for k, e in ipairs(api.get_valid_nodes()) do
|
for k, e in ipairs(api.get_valid_nodes()) do
|
||||||
nodes_table[#nodes_table + 1] = e
|
nodes_table[#nodes_table + 1] = e
|
||||||
end
|
end
|
||||||
|
|
||||||
m = Map(appname)
|
m = Map(appname)
|
||||||
@ -31,21 +31,21 @@ o.default = 3
|
|||||||
|
|
||||||
o = s:option(DynamicList, "tcp_node", "TCP " .. translate("List of backup nodes"))
|
o = s:option(DynamicList, "tcp_node", "TCP " .. translate("List of backup nodes"))
|
||||||
for k, v in pairs(nodes_table) do
|
for k, v in pairs(nodes_table) do
|
||||||
if v.node_type == "normal" then
|
if v.node_type == "normal" then
|
||||||
o:value(v.id, v["remark"])
|
o:value(v.id, v["remark"])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
function o.write(self, section, value)
|
function o.write(self, section, value)
|
||||||
local t = {}
|
local t = {}
|
||||||
local t2 = {}
|
local t2 = {}
|
||||||
if type(value) == "table" then
|
if type(value) == "table" then
|
||||||
local x
|
local x
|
||||||
for _, x in ipairs(value) do
|
for _, x in ipairs(value) do
|
||||||
if x and #x > 0 then
|
if x and #x > 0 then
|
||||||
if not t2[x] then
|
if not t2[x] then
|
||||||
t2[x] = x
|
t2[x] = x
|
||||||
t[#t+1] = x
|
t[#t+1] = x
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
@ -10,66 +10,66 @@ m = Map(appname)
|
|||||||
|
|
||||||
local nodes_table = {}
|
local nodes_table = {}
|
||||||
for k, e in ipairs(api.get_valid_nodes()) do
|
for k, e in ipairs(api.get_valid_nodes()) do
|
||||||
nodes_table[#nodes_table + 1] = e
|
nodes_table[#nodes_table + 1] = e
|
||||||
end
|
end
|
||||||
|
|
||||||
local tcp_socks_server = "127.0.0.1" .. ":" .. (uci:get(appname, "@global[0]", "tcp_node_socks_port") or "1070")
|
local tcp_socks_server = "127.0.0.1" .. ":" .. (uci:get(appname, "@global[0]", "tcp_node_socks_port") or "1070")
|
||||||
local socks_table = {}
|
local socks_table = {}
|
||||||
socks_table[#socks_table + 1] = {
|
socks_table[#socks_table + 1] = {
|
||||||
id = tcp_socks_server,
|
id = tcp_socks_server,
|
||||||
remarks = tcp_socks_server .. " - " .. translate("TCP Node")
|
remarks = tcp_socks_server .. " - " .. translate("TCP Node")
|
||||||
}
|
}
|
||||||
uci:foreach(appname, "socks", function(s)
|
uci:foreach(appname, "socks", function(s)
|
||||||
if s.enabled == "1" and s.node then
|
if s.enabled == "1" and s.node then
|
||||||
local id, remarks
|
local id, remarks
|
||||||
for k, n in pairs(nodes_table) do
|
for k, n in pairs(nodes_table) do
|
||||||
if (s.node == n.id) then
|
if (s.node == n.id) then
|
||||||
remarks = n["remark"]; break
|
remarks = n["remark"]; break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
id = "127.0.0.1" .. ":" .. s.port
|
id = "127.0.0.1" .. ":" .. s.port
|
||||||
socks_table[#socks_table + 1] = {
|
socks_table[#socks_table + 1] = {
|
||||||
id = id,
|
id = id,
|
||||||
remarks = id .. " - " .. (remarks or translate("Misconfigured"))
|
remarks = id .. " - " .. (remarks or translate("Misconfigured"))
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local doh_validate = function(self, value, t)
|
local doh_validate = function(self, value, t)
|
||||||
if value ~= "" then
|
if value ~= "" then
|
||||||
value = api.trim(value)
|
value = api.trim(value)
|
||||||
local flag = 0
|
local flag = 0
|
||||||
local util = require "luci.util"
|
local util = require "luci.util"
|
||||||
local val = util.split(value, ",")
|
local val = util.split(value, ",")
|
||||||
local url = val[1]
|
local url = val[1]
|
||||||
val[1] = nil
|
val[1] = nil
|
||||||
for i = 1, #val do
|
for i = 1, #val do
|
||||||
local v = val[i]
|
local v = val[i]
|
||||||
if v then
|
if v then
|
||||||
if not datatypes.ipmask4(v) then
|
if not datatypes.ipmask4(v) then
|
||||||
flag = 1
|
flag = 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if flag == 0 then
|
if flag == 0 then
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return nil, translate("DoH request address") .. " " .. translate("Format must be:") .. " URL,IP"
|
return nil, translate("DoH request address") .. " " .. translate("Format must be:") .. " URL,IP"
|
||||||
end
|
end
|
||||||
|
|
||||||
local redir_mode_validate = function(self, value, t)
|
local redir_mode_validate = function(self, value, t)
|
||||||
local tcp_proxy_mode_v = tcp_proxy_mode:formvalue(t) or ""
|
local tcp_proxy_mode_v = tcp_proxy_mode:formvalue(t) or ""
|
||||||
local udp_proxy_mode_v = udp_proxy_mode:formvalue(t) or ""
|
local udp_proxy_mode_v = udp_proxy_mode:formvalue(t) or ""
|
||||||
local localhost_tcp_proxy_mode_v = localhost_tcp_proxy_mode:formvalue(t) or ""
|
local localhost_tcp_proxy_mode_v = localhost_tcp_proxy_mode:formvalue(t) or ""
|
||||||
local localhost_udp_proxy_mode_v = localhost_udp_proxy_mode:formvalue(t) or ""
|
local localhost_udp_proxy_mode_v = localhost_udp_proxy_mode:formvalue(t) or ""
|
||||||
local s = tcp_proxy_mode_v .. udp_proxy_mode_v .. localhost_tcp_proxy_mode_v .. localhost_udp_proxy_mode_v
|
local s = tcp_proxy_mode_v .. udp_proxy_mode_v .. localhost_tcp_proxy_mode_v .. localhost_udp_proxy_mode_v
|
||||||
if s:find("returnhome") then
|
if s:find("returnhome") then
|
||||||
if s:find("chnroute") or s:find("gfwlist") then
|
if s:find("chnroute") or s:find("gfwlist") then
|
||||||
return nil, translate("China list or gfwlist cannot be used together with outside China list!")
|
return nil, translate("China list or gfwlist cannot be used together with outside China list!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
|
|
||||||
m:append(Template(appname .. "/global/status"))
|
m:append(Template(appname .. "/global/status"))
|
||||||
@ -89,80 +89,80 @@ tcp_node = s:taboption("Main", ListValue, "tcp_node", "<a style='color: red'>" .
|
|||||||
tcp_node.description = ""
|
tcp_node.description = ""
|
||||||
local current_node = luci.sys.exec(string.format("[ -f '/tmp/etc/%s/id/TCP' ] && echo -n $(cat /tmp/etc/%s/id/TCP)", appname, appname))
|
local current_node = luci.sys.exec(string.format("[ -f '/tmp/etc/%s/id/TCP' ] && echo -n $(cat /tmp/etc/%s/id/TCP)", appname, appname))
|
||||||
if current_node and current_node ~= "" and current_node ~= "nil" then
|
if current_node and current_node ~= "" and current_node ~= "nil" then
|
||||||
local n = uci:get_all(appname, current_node)
|
local n = uci:get_all(appname, current_node)
|
||||||
if n then
|
if n then
|
||||||
if tonumber(m:get("@auto_switch[0]", "enable") or 0) == 1 then
|
if tonumber(m:get("@auto_switch[0]", "enable") or 0) == 1 then
|
||||||
local remarks = api.get_full_node_remarks(n)
|
local remarks = api.get_full_node_remarks(n)
|
||||||
local url = api.url("node_config", current_node)
|
local url = api.url("node_config", current_node)
|
||||||
tcp_node.description = tcp_node.description .. translatef("Current node: %s", string.format('<a href="%s">%s</a>', url, remarks)) .. "<br />"
|
tcp_node.description = tcp_node.description .. translatef("Current node: %s", string.format('<a href="%s">%s</a>', url, remarks)) .. "<br />"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
tcp_node:value("nil", translate("Close"))
|
tcp_node:value("nil", translate("Close"))
|
||||||
|
|
||||||
-- 分流
|
-- 分流
|
||||||
if (has_v2ray or has_xray) and #nodes_table > 0 then
|
if (has_v2ray or has_xray) and #nodes_table > 0 then
|
||||||
local normal_list = {}
|
local normal_list = {}
|
||||||
local shunt_list = {}
|
local shunt_list = {}
|
||||||
for k, v in pairs(nodes_table) do
|
for k, v in pairs(nodes_table) do
|
||||||
if v.node_type == "normal" then
|
if v.node_type == "normal" then
|
||||||
normal_list[#normal_list + 1] = v
|
normal_list[#normal_list + 1] = v
|
||||||
end
|
end
|
||||||
if v.protocol and v.protocol == "_shunt" then
|
if v.protocol and v.protocol == "_shunt" then
|
||||||
shunt_list[#shunt_list + 1] = v
|
shunt_list[#shunt_list + 1] = v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for k, v in pairs(shunt_list) do
|
for k, v in pairs(shunt_list) do
|
||||||
uci:foreach(appname, "shunt_rules", function(e)
|
uci:foreach(appname, "shunt_rules", function(e)
|
||||||
local id = e[".name"]
|
local id = e[".name"]
|
||||||
if id and e.remarks then
|
if id and e.remarks then
|
||||||
o = s:taboption("Main", ListValue, v.id .. "." .. id .. "_node", string.format('* <a href="%s" target="_blank">%s</a>', api.url("shunt_rules", id), e.remarks))
|
o = s:taboption("Main", ListValue, v.id .. "." .. id .. "_node", string.format('* <a href="%s" target="_blank">%s</a>', api.url("shunt_rules", id), e.remarks))
|
||||||
o:depends("tcp_node", v.id)
|
o:depends("tcp_node", v.id)
|
||||||
o:value("nil", translate("Close"))
|
o:value("nil", translate("Close"))
|
||||||
o:value("_default", translate("Default"))
|
o:value("_default", translate("Default"))
|
||||||
o:value("_direct", translate("Direct Connection"))
|
o:value("_direct", translate("Direct Connection"))
|
||||||
o:value("_blackhole", translate("Blackhole"))
|
o:value("_blackhole", translate("Blackhole"))
|
||||||
for k1, v1 in pairs(normal_list) do
|
for k1, v1 in pairs(normal_list) do
|
||||||
o:value(v1.id, v1["remark"])
|
o:value(v1.id, v1["remark"])
|
||||||
end
|
end
|
||||||
o.cfgvalue = function(self, section)
|
o.cfgvalue = function(self, section)
|
||||||
return m:get(v.id, id) or "nil"
|
return m:get(v.id, id) or "nil"
|
||||||
end
|
end
|
||||||
o.write = function(self, section, value)
|
o.write = function(self, section, value)
|
||||||
m:set(v.id, id, value)
|
m:set(v.id, id, value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
local id = "default_node"
|
local id = "default_node"
|
||||||
o = s:taboption("Main", ListValue, v.id .. "." .. id, string.format('* <a style="color:red">%s</a>', translate("Default")))
|
o = s:taboption("Main", ListValue, v.id .. "." .. id, string.format('* <a style="color:red">%s</a>', translate("Default")))
|
||||||
o:depends("tcp_node", v.id)
|
o:depends("tcp_node", v.id)
|
||||||
o:value("_direct", translate("Direct Connection"))
|
o:value("_direct", translate("Direct Connection"))
|
||||||
o:value("_blackhole", translate("Blackhole"))
|
o:value("_blackhole", translate("Blackhole"))
|
||||||
for k1, v1 in pairs(normal_list) do
|
for k1, v1 in pairs(normal_list) do
|
||||||
o:value(v1.id, v1["remark"])
|
o:value(v1.id, v1["remark"])
|
||||||
end
|
end
|
||||||
o.cfgvalue = function(self, section)
|
o.cfgvalue = function(self, section)
|
||||||
return m:get(v.id, id) or "nil"
|
return m:get(v.id, id) or "nil"
|
||||||
end
|
end
|
||||||
o.write = function(self, section, value)
|
o.write = function(self, section, value)
|
||||||
m:set(v.id, id, value)
|
m:set(v.id, id, value)
|
||||||
end
|
end
|
||||||
|
|
||||||
local id = "main_node"
|
local id = "main_node"
|
||||||
o = s:taboption("Main", ListValue, v.id .. "." .. id, string.format('* <a style="color:red">%s</a>', translate("Default Preproxy")), translate("When using, localhost will connect this node first and then use this node to connect the default node."))
|
o = s:taboption("Main", ListValue, v.id .. "." .. id, string.format('* <a style="color:red">%s</a>', translate("Default Preproxy")), translate("When using, localhost will connect this node first and then use this node to connect the default node."))
|
||||||
o:depends("tcp_node", v.id)
|
o:depends("tcp_node", v.id)
|
||||||
o:value("nil", translate("Close"))
|
o:value("nil", translate("Close"))
|
||||||
for k1, v1 in pairs(normal_list) do
|
for k1, v1 in pairs(normal_list) do
|
||||||
o:value(v1.id, v1["remark"])
|
o:value(v1.id, v1["remark"])
|
||||||
end
|
end
|
||||||
o.cfgvalue = function(self, section)
|
o.cfgvalue = function(self, section)
|
||||||
return m:get(v.id, id) or "nil"
|
return m:get(v.id, id) or "nil"
|
||||||
end
|
end
|
||||||
o.write = function(self, section, value)
|
o.write = function(self, section, value)
|
||||||
m:set(v.id, id, value)
|
m:set(v.id, id, value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
udp_node = s:taboption("Main", ListValue, "udp_node", "<a style='color: red'>" .. translate("UDP Node") .. "</a>")
|
udp_node = s:taboption("Main", ListValue, "udp_node", "<a style='color: red'>" .. translate("UDP Node") .. "</a>")
|
||||||
@ -175,9 +175,9 @@ tcp_node_socks_port.datatype = "port"
|
|||||||
|
|
||||||
--[[
|
--[[
|
||||||
if has_v2ray or has_xray then
|
if has_v2ray or has_xray then
|
||||||
tcp_node_http_port = s:taboption("Main", Value, "tcp_node_http_port", translate("TCP Node") .. " HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use"))
|
tcp_node_http_port = s:taboption("Main", Value, "tcp_node_http_port", translate("TCP Node") .. " HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use"))
|
||||||
tcp_node_http_port.default = 0
|
tcp_node_http_port.default = 0
|
||||||
tcp_node_http_port.datatype = "port"
|
tcp_node_http_port.datatype = "port"
|
||||||
end
|
end
|
||||||
]]--
|
]]--
|
||||||
|
|
||||||
@ -192,13 +192,13 @@ dns_mode = s:taboption("DNS", ListValue, "dns_mode", translate("Filter Mode"))
|
|||||||
dns_mode.rmempty = false
|
dns_mode.rmempty = false
|
||||||
dns_mode:reset_values()
|
dns_mode:reset_values()
|
||||||
if api.is_finded("dns2tcp") then
|
if api.is_finded("dns2tcp") then
|
||||||
dns_mode:value("dns2tcp", translatef("Requery DNS By %s", "TCP"))
|
dns_mode:value("dns2tcp", translatef("Requery DNS By %s", "TCP"))
|
||||||
end
|
end
|
||||||
if api.is_finded("dns2socks") then
|
if api.is_finded("dns2socks") then
|
||||||
dns_mode:value("dns2socks", "dns2socks")
|
dns_mode:value("dns2socks", "dns2socks")
|
||||||
end
|
end
|
||||||
if has_xray then
|
if has_xray then
|
||||||
dns_mode:value("xray", "Xray")
|
dns_mode:value("xray", "Xray")
|
||||||
end
|
end
|
||||||
dns_mode:value("udp", translatef("Requery DNS By %s", "UDP"))
|
dns_mode:value("udp", translatef("Requery DNS By %s", "UDP"))
|
||||||
|
|
||||||
@ -208,24 +208,24 @@ o:value("doh", "DoH")
|
|||||||
o:value("fakedns", "FakeDNS")
|
o:value("fakedns", "FakeDNS")
|
||||||
o:depends("dns_mode", "xray")
|
o:depends("dns_mode", "xray")
|
||||||
o.validate = function(self, value, t)
|
o.validate = function(self, value, t)
|
||||||
if value == "fakedns" then
|
if value == "fakedns" then
|
||||||
local _dns_mode = dns_mode:formvalue(t)
|
local _dns_mode = dns_mode:formvalue(t)
|
||||||
local _tcp_node = tcp_node:formvalue(t)
|
local _tcp_node = tcp_node:formvalue(t)
|
||||||
if m:get(_tcp_node, "type"):lower() ~= _dns_mode then
|
if m:get(_tcp_node, "type"):lower() ~= _dns_mode then
|
||||||
return nil, translatef("TCP node must be '%s' type to use FakeDNS.", _dns_mode)
|
return nil, translatef("TCP node must be '%s' type to use FakeDNS.", _dns_mode)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:taboption("DNS", Value, "socks_server", translate("Socks Server"), translate("Make sure socks service is available on this address."))
|
o = s:taboption("DNS", Value, "socks_server", translate("Socks Server"), translate("Make sure socks service is available on this address."))
|
||||||
for k, v in pairs(socks_table) do o:value(v.id, v.remarks) end
|
for k, v in pairs(socks_table) do o:value(v.id, v.remarks) end
|
||||||
o.default = socks_table[1].id
|
o.default = socks_table[1].id
|
||||||
o.validate = function(self, value, t)
|
o.validate = function(self, value, t)
|
||||||
if not datatypes.ipaddrport(value) then
|
if not datatypes.ipaddrport(value) then
|
||||||
return nil, translate("Socks Server") .. " " .. translate("Not valid IP format, please re-enter!")
|
return nil, translate("Socks Server") .. " " .. translate("Not valid IP format, please re-enter!")
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
o:depends({dns_mode = "dns2socks"})
|
o:depends({dns_mode = "dns2socks"})
|
||||||
|
|
||||||
@ -263,7 +263,7 @@ o:depends("v2ray_dns_mode", "doh")
|
|||||||
|
|
||||||
o = s:taboption("DNS", Value, "dns_client_ip", translate("EDNS Client Subnet"))
|
o = s:taboption("DNS", Value, "dns_client_ip", translate("EDNS Client Subnet"))
|
||||||
o.description = translate("Notify the DNS server when the DNS query is notified, the location of the client (cannot be a private IP address).") .. "<br />" ..
|
o.description = translate("Notify the DNS server when the DNS query is notified, the location of the client (cannot be a private IP address).") .. "<br />" ..
|
||||||
translate("This feature requires the DNS server to support the Edns Client Subnet (RFC7871).")
|
translate("This feature requires the DNS server to support the Edns Client Subnet (RFC7871).")
|
||||||
o.datatype = "ipaddr"
|
o.datatype = "ipaddr"
|
||||||
o:depends("v2ray_dns_mode", "tcp")
|
o:depends("v2ray_dns_mode", "tcp")
|
||||||
o:depends("v2ray_dns_mode", "doh")
|
o:depends("v2ray_dns_mode", "doh")
|
||||||
@ -276,25 +276,25 @@ o:depends({dns_mode = "xray", v2ray_dns_mode = "doh"})
|
|||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
|
|
||||||
if has_chnlist then
|
if has_chnlist then
|
||||||
when_chnroute_default_dns = s:taboption("DNS", ListValue, "when_chnroute_default_dns", translate("When using the chnroute list the default DNS"))
|
when_chnroute_default_dns = s:taboption("DNS", ListValue, "when_chnroute_default_dns", translate("When using the chnroute list the default DNS"))
|
||||||
when_chnroute_default_dns.default = "direct"
|
when_chnroute_default_dns.default = "direct"
|
||||||
when_chnroute_default_dns:value("remote", translate("Remote DNS"))
|
when_chnroute_default_dns:value("remote", translate("Remote DNS"))
|
||||||
when_chnroute_default_dns:value("direct", translate("Direct DNS"))
|
when_chnroute_default_dns:value("direct", translate("Direct DNS"))
|
||||||
when_chnroute_default_dns.description = "<ul>"
|
when_chnroute_default_dns.description = "<ul>"
|
||||||
.. "<li>" .. translate("Remote DNS can avoid more DNS leaks, but some domestic domain names maybe to proxy!") .. "</li>"
|
.. "<li>" .. translate("Remote DNS can avoid more DNS leaks, but some domestic domain names maybe to proxy!") .. "</li>"
|
||||||
.. "<li>" .. translate("Direct DNS Internet experience may be better, but DNS will be leaked!") .. "</li>"
|
.. "<li>" .. translate("Direct DNS Internet experience may be better, but DNS will be leaked!") .. "</li>"
|
||||||
if api.is_finded("chinadns-ng") then
|
if api.is_finded("chinadns-ng") then
|
||||||
when_chnroute_default_dns:value("chinadns_ng", translate("ChinaDNS-NG"))
|
when_chnroute_default_dns:value("chinadns_ng", translate("ChinaDNS-NG"))
|
||||||
when_chnroute_default_dns.default = "chinadns_ng"
|
when_chnroute_default_dns.default = "chinadns_ng"
|
||||||
end
|
end
|
||||||
when_chnroute_default_dns.description = when_chnroute_default_dns.description .. "</li></ul>"
|
when_chnroute_default_dns.description = when_chnroute_default_dns.description .. "</li></ul>"
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:taboption("DNS", Button, "clear_ipset", translate("Clear IPSET"), translate("Try this feature if the rule modification does not take effect."))
|
o = s:taboption("DNS", Button, "clear_ipset", translate("Clear IPSET"), translate("Try this feature if the rule modification does not take effect."))
|
||||||
o.inputstyle = "remove"
|
o.inputstyle = "remove"
|
||||||
function o.write(e, e)
|
function o.write(e, e)
|
||||||
luci.sys.call("[ -n \"$(nft list sets 2>/dev/null | grep \"gfwlist\")\" ] && /usr/share/" .. appname .. "/nftables.sh flush_nftset || /usr/share/" .. appname .. "/iptables.sh flush_ipset > /dev/null 2>&1 &")
|
luci.sys.call("[ -n \"$(nft list sets 2>/dev/null | grep \"gfwlist\")\" ] && /usr/share/" .. appname .. "/nftables.sh flush_nftset || /usr/share/" .. appname .. "/iptables.sh flush_ipset > /dev/null 2>&1 &")
|
||||||
luci.http.redirect(api.url("log"))
|
luci.http.redirect(api.url("log"))
|
||||||
end
|
end
|
||||||
|
|
||||||
s:tab("Proxy", translate("Mode"))
|
s:tab("Proxy", translate("Mode"))
|
||||||
@ -306,7 +306,7 @@ tcp_proxy_mode:value("global", translate("Global Proxy"))
|
|||||||
tcp_proxy_mode:value("gfwlist", translate("GFW List"))
|
tcp_proxy_mode:value("gfwlist", translate("GFW List"))
|
||||||
tcp_proxy_mode:value("chnroute", translate("Not China List"))
|
tcp_proxy_mode:value("chnroute", translate("Not China List"))
|
||||||
if has_chnlist then
|
if has_chnlist then
|
||||||
tcp_proxy_mode:value("returnhome", translate("China List"))
|
tcp_proxy_mode:value("returnhome", translate("China List"))
|
||||||
end
|
end
|
||||||
tcp_proxy_mode:value("direct/proxy", translate("Only use direct/proxy list"))
|
tcp_proxy_mode:value("direct/proxy", translate("Only use direct/proxy list"))
|
||||||
tcp_proxy_mode.default = "chnroute"
|
tcp_proxy_mode.default = "chnroute"
|
||||||
@ -319,7 +319,7 @@ udp_proxy_mode:value("global", translate("Global Proxy"))
|
|||||||
udp_proxy_mode:value("gfwlist", translate("GFW List"))
|
udp_proxy_mode:value("gfwlist", translate("GFW List"))
|
||||||
udp_proxy_mode:value("chnroute", translate("Not China List"))
|
udp_proxy_mode:value("chnroute", translate("Not China List"))
|
||||||
if has_chnlist then
|
if has_chnlist then
|
||||||
udp_proxy_mode:value("returnhome", translate("China List"))
|
udp_proxy_mode:value("returnhome", translate("China List"))
|
||||||
end
|
end
|
||||||
udp_proxy_mode:value("direct/proxy", translate("Only use direct/proxy list"))
|
udp_proxy_mode:value("direct/proxy", translate("Only use direct/proxy list"))
|
||||||
udp_proxy_mode.default = "chnroute"
|
udp_proxy_mode.default = "chnroute"
|
||||||
@ -332,7 +332,7 @@ localhost_tcp_proxy_mode:value("global", translate("Global Proxy"))
|
|||||||
localhost_tcp_proxy_mode:value("gfwlist", translate("GFW List"))
|
localhost_tcp_proxy_mode:value("gfwlist", translate("GFW List"))
|
||||||
localhost_tcp_proxy_mode:value("chnroute", translate("Not China List"))
|
localhost_tcp_proxy_mode:value("chnroute", translate("Not China List"))
|
||||||
if has_chnlist then
|
if has_chnlist then
|
||||||
localhost_tcp_proxy_mode:value("returnhome", translate("China List"))
|
localhost_tcp_proxy_mode:value("returnhome", translate("China List"))
|
||||||
end
|
end
|
||||||
localhost_tcp_proxy_mode:value("disable", translate("No Proxy"))
|
localhost_tcp_proxy_mode:value("disable", translate("No Proxy"))
|
||||||
localhost_tcp_proxy_mode:value("direct/proxy", translate("Only use direct/proxy list"))
|
localhost_tcp_proxy_mode:value("direct/proxy", translate("Only use direct/proxy list"))
|
||||||
@ -346,7 +346,7 @@ localhost_udp_proxy_mode:value("global", translate("Global Proxy"))
|
|||||||
localhost_udp_proxy_mode:value("gfwlist", translate("GFW List"))
|
localhost_udp_proxy_mode:value("gfwlist", translate("GFW List"))
|
||||||
localhost_udp_proxy_mode:value("chnroute", translate("Not China List"))
|
localhost_udp_proxy_mode:value("chnroute", translate("Not China List"))
|
||||||
if has_chnlist then
|
if has_chnlist then
|
||||||
localhost_udp_proxy_mode:value("returnhome", translate("China List"))
|
localhost_udp_proxy_mode:value("returnhome", translate("China List"))
|
||||||
end
|
end
|
||||||
localhost_udp_proxy_mode:value("disable", translate("No Proxy"))
|
localhost_udp_proxy_mode:value("disable", translate("No Proxy"))
|
||||||
localhost_udp_proxy_mode:value("direct/proxy", translate("Only use direct/proxy list"))
|
localhost_udp_proxy_mode:value("direct/proxy", translate("Only use direct/proxy list"))
|
||||||
@ -356,7 +356,7 @@ localhost_udp_proxy_mode.validate = redir_mode_validate
|
|||||||
tips = s:taboption("Proxy", DummyValue, "tips", " ")
|
tips = s:taboption("Proxy", DummyValue, "tips", " ")
|
||||||
tips.rawhtml = true
|
tips.rawhtml = true
|
||||||
tips.cfgvalue = function(t, n)
|
tips.cfgvalue = function(t, n)
|
||||||
return string.format('<a style="color: red" href="%s">%s</a>', api.url("acl"), translate("Want different devices to use different proxy modes/ports/nodes? Please use access control."))
|
return string.format('<a style="color: red" href="%s">%s</a>', api.url("acl"), translate("Want different devices to use different proxy modes/ports/nodes? Please use access control."))
|
||||||
end
|
end
|
||||||
|
|
||||||
s:tab("log", translate("Log"))
|
s:tab("log", translate("Log"))
|
||||||
@ -395,13 +395,13 @@ s.anonymous = true
|
|||||||
s.addremove = true
|
s.addremove = true
|
||||||
s.template = "cbi/tblsection"
|
s.template = "cbi/tblsection"
|
||||||
function s.create(e, t)
|
function s.create(e, t)
|
||||||
TypedSection.create(e, api.gen_uuid())
|
TypedSection.create(e, api.gen_uuid())
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:option(DummyValue, "status", translate("Status"))
|
o = s:option(DummyValue, "status", translate("Status"))
|
||||||
o.rawhtml = true
|
o.rawhtml = true
|
||||||
o.cfgvalue = function(t, n)
|
o.cfgvalue = function(t, n)
|
||||||
return string.format('<div class="_status" socks_id="%s"></div>', n)
|
return string.format('<div class="_status" socks_id="%s"></div>', n)
|
||||||
end
|
end
|
||||||
|
|
||||||
---- Enable
|
---- Enable
|
||||||
@ -413,10 +413,10 @@ socks_node = s:option(ListValue, "node", translate("Socks Node"))
|
|||||||
|
|
||||||
local n = 1
|
local n = 1
|
||||||
uci:foreach(appname, "socks", function(s)
|
uci:foreach(appname, "socks", function(s)
|
||||||
if s[".name"] == section then
|
if s[".name"] == section then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
n = n + 1
|
n = n + 1
|
||||||
end)
|
end)
|
||||||
|
|
||||||
o = s:option(Value, "port", "Socks " .. translate("Listen Port"))
|
o = s:option(Value, "port", "Socks " .. translate("Listen Port"))
|
||||||
@ -425,21 +425,21 @@ o.datatype = "port"
|
|||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
|
|
||||||
if has_v2ray or has_xray then
|
if has_v2ray or has_xray then
|
||||||
o = s:option(Value, "http_port", "HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use"))
|
o = s:option(Value, "http_port", "HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use"))
|
||||||
o.default = 0
|
o.default = 0
|
||||||
o.datatype = "port"
|
o.datatype = "port"
|
||||||
end
|
end
|
||||||
|
|
||||||
for k, v in pairs(nodes_table) do
|
for k, v in pairs(nodes_table) do
|
||||||
tcp_node:value(v.id, v["remark"])
|
tcp_node:value(v.id, v["remark"])
|
||||||
udp_node:value(v.id, v["remark"])
|
udp_node:value(v.id, v["remark"])
|
||||||
if v.type == "Socks" then
|
if v.type == "Socks" then
|
||||||
if has_v2ray or has_xray then
|
if has_v2ray or has_xray then
|
||||||
socks_node:value(v.id, v["remark"])
|
socks_node:value(v.id, v["remark"])
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
socks_node:value(v.id, v["remark"])
|
socks_node:value(v.id, v["remark"])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
m:append(Template(appname .. "/global/footer"))
|
m:append(Template(appname .. "/global/footer"))
|
||||||
|
@ -6,13 +6,13 @@ local datatypes = api.datatypes
|
|||||||
|
|
||||||
local nodes_table = {}
|
local nodes_table = {}
|
||||||
for k, e in ipairs(api.get_valid_nodes()) do
|
for k, e in ipairs(api.get_valid_nodes()) do
|
||||||
if e.node_type == "normal" then
|
if e.node_type == "normal" then
|
||||||
nodes_table[#nodes_table + 1] = {
|
nodes_table[#nodes_table + 1] = {
|
||||||
id = e[".name"],
|
id = e[".name"],
|
||||||
obj = e,
|
obj = e,
|
||||||
remarks = e["remark"]
|
remarks = e["remark"]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
m = Map(appname)
|
m = Map(appname)
|
||||||
@ -41,31 +41,31 @@ o:depends("balancing_enable", true)
|
|||||||
|
|
||||||
---- Console Port
|
---- Console Port
|
||||||
o = s:option(Value, "console_port", translate("Console Port"), translate(
|
o = s:option(Value, "console_port", translate("Console Port"), translate(
|
||||||
"In the browser input routing IP plus port access, such as:192.168.1.1:1188"))
|
"In the browser input routing IP plus port access, such as:192.168.1.1:1188"))
|
||||||
o.default = "1188"
|
o.default = "1188"
|
||||||
o:depends("balancing_enable", true)
|
o:depends("balancing_enable", true)
|
||||||
|
|
||||||
-- [[ Balancing Settings ]]--
|
-- [[ Balancing Settings ]]--
|
||||||
s = m:section(TypedSection, "haproxy_config", "",
|
s = m:section(TypedSection, "haproxy_config", "",
|
||||||
"<font color='red'>" ..
|
"<font color='red'>" ..
|
||||||
translate("Add a node, Export Of Multi WAN Only support Multi Wan. Load specific gravity range 1-256. Multiple primary servers can be load balanced, standby will only be enabled when the primary server is offline! Multiple groups can be set, Haproxy port same one for each group.") ..
|
translate("Add a node, Export Of Multi WAN Only support Multi Wan. Load specific gravity range 1-256. Multiple primary servers can be load balanced, standby will only be enabled when the primary server is offline! Multiple groups can be set, Haproxy port same one for each group.") ..
|
||||||
"\n" .. translate("Note that the node configuration parameters for load balancing must be consistent, otherwise problems can arise!") ..
|
"\n" .. translate("Note that the node configuration parameters for load balancing must be consistent, otherwise problems can arise!") ..
|
||||||
"</font>")
|
"</font>")
|
||||||
s.template = "cbi/tblsection"
|
s.template = "cbi/tblsection"
|
||||||
s.sortable = true
|
s.sortable = true
|
||||||
s.anonymous = true
|
s.anonymous = true
|
||||||
s.addremove = true
|
s.addremove = true
|
||||||
|
|
||||||
s.create = function(e, t)
|
s.create = function(e, t)
|
||||||
TypedSection.create(e, api.gen_uuid())
|
TypedSection.create(e, api.gen_uuid())
|
||||||
end
|
end
|
||||||
|
|
||||||
s.remove = function(self, section)
|
s.remove = function(self, section)
|
||||||
for k, v in pairs(self.children) do
|
for k, v in pairs(self.children) do
|
||||||
v.rmempty = true
|
v.rmempty = true
|
||||||
v.validate = nil
|
v.validate = nil
|
||||||
end
|
end
|
||||||
TypedSection.remove(self, section)
|
TypedSection.remove(self, section)
|
||||||
end
|
end
|
||||||
|
|
||||||
---- Enable
|
---- Enable
|
||||||
@ -78,18 +78,18 @@ o = s:option(Value, "lbss", translate("Node Address"))
|
|||||||
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
|
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
o.validate = function(self, value)
|
o.validate = function(self, value)
|
||||||
if not value then return nil end
|
if not value then return nil end
|
||||||
local t = m:get(value) or nil
|
local t = m:get(value) or nil
|
||||||
if t and t[".type"] == "nodes" then
|
if t and t[".type"] == "nodes" then
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
if datatypes.hostport(value) or datatypes.ip4addrport(value) then
|
if datatypes.hostport(value) or datatypes.ip4addrport(value) then
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
if api.is_ipv6addrport(value) then
|
if api.is_ipv6addrport(value) then
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
return nil, value
|
return nil, value
|
||||||
end
|
end
|
||||||
|
|
||||||
---- Haproxy Port
|
---- Haproxy Port
|
||||||
|
@ -3,53 +3,53 @@ local appname = api.appname
|
|||||||
local uci = api.uci
|
local uci = api.uci
|
||||||
|
|
||||||
if not arg[1] or not uci:get(appname, arg[1]) then
|
if not arg[1] or not uci:get(appname, arg[1]) then
|
||||||
luci.http.redirect(api.url("node_list"))
|
luci.http.redirect(api.url("node_list"))
|
||||||
end
|
end
|
||||||
|
|
||||||
local ss_encrypt_method_list = {
|
local ss_encrypt_method_list = {
|
||||||
"rc4-md5", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "aes-128-ctr",
|
"rc4-md5", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "aes-128-ctr",
|
||||||
"aes-192-ctr", "aes-256-ctr", "bf-cfb", "salsa20", "chacha20", "chacha20-ietf",
|
"aes-192-ctr", "aes-256-ctr", "bf-cfb", "salsa20", "chacha20", "chacha20-ietf",
|
||||||
"aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
|
"aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
|
||||||
"xchacha20-ietf-poly1305"
|
"xchacha20-ietf-poly1305"
|
||||||
}
|
}
|
||||||
|
|
||||||
local ss_rust_encrypt_method_list = {
|
local ss_rust_encrypt_method_list = {
|
||||||
"plain", "none",
|
"plain", "none",
|
||||||
"aes-128-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
|
"aes-128-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
|
||||||
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
||||||
}
|
}
|
||||||
|
|
||||||
local ssr_encrypt_method_list = {
|
local ssr_encrypt_method_list = {
|
||||||
"none", "table", "rc2-cfb", "rc4", "rc4-md5", "rc4-md5-6", "aes-128-cfb",
|
"none", "table", "rc2-cfb", "rc4", "rc4-md5", "rc4-md5-6", "aes-128-cfb",
|
||||||
"aes-192-cfb", "aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr",
|
"aes-192-cfb", "aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr",
|
||||||
"bf-cfb", "camellia-128-cfb", "camellia-192-cfb", "camellia-256-cfb",
|
"bf-cfb", "camellia-128-cfb", "camellia-192-cfb", "camellia-256-cfb",
|
||||||
"cast5-cfb", "des-cfb", "idea-cfb", "seed-cfb", "salsa20", "chacha20",
|
"cast5-cfb", "des-cfb", "idea-cfb", "seed-cfb", "salsa20", "chacha20",
|
||||||
"chacha20-ietf"
|
"chacha20-ietf"
|
||||||
}
|
}
|
||||||
|
|
||||||
local ssr_protocol_list = {
|
local ssr_protocol_list = {
|
||||||
"origin", "verify_simple", "verify_deflate", "verify_sha1", "auth_simple",
|
"origin", "verify_simple", "verify_deflate", "verify_sha1", "auth_simple",
|
||||||
"auth_sha1", "auth_sha1_v2", "auth_sha1_v4", "auth_aes128_md5",
|
"auth_sha1", "auth_sha1_v2", "auth_sha1_v4", "auth_aes128_md5",
|
||||||
"auth_aes128_sha1", "auth_chain_a", "auth_chain_b", "auth_chain_c",
|
"auth_aes128_sha1", "auth_chain_a", "auth_chain_b", "auth_chain_c",
|
||||||
"auth_chain_d", "auth_chain_e", "auth_chain_f"
|
"auth_chain_d", "auth_chain_e", "auth_chain_f"
|
||||||
}
|
}
|
||||||
local ssr_obfs_list = {
|
local ssr_obfs_list = {
|
||||||
"plain", "http_simple", "http_post", "random_head", "tls_simple",
|
"plain", "http_simple", "http_post", "random_head", "tls_simple",
|
||||||
"tls1.0_session_auth", "tls1.2_ticket_auth"
|
"tls1.0_session_auth", "tls1.2_ticket_auth"
|
||||||
}
|
}
|
||||||
|
|
||||||
local v_ss_encrypt_method_list = {
|
local v_ss_encrypt_method_list = {
|
||||||
"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305"
|
"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305"
|
||||||
}
|
}
|
||||||
|
|
||||||
local x_ss_encrypt_method_list = {
|
local x_ss_encrypt_method_list = {
|
||||||
"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "xchacha20-poly1305", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "xchacha20-poly1305", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
||||||
}
|
}
|
||||||
|
|
||||||
local security_list = {"none", "auto", "aes-128-gcm", "chacha20-poly1305", "zero"}
|
local security_list = {"none", "auto", "aes-128-gcm", "chacha20-poly1305", "zero"}
|
||||||
|
|
||||||
local header_type_list = {
|
local header_type_list = {
|
||||||
"none", "srtp", "utp", "wechat-video", "dtls", "wireguard"
|
"none", "srtp", "utp", "wechat-video", "dtls", "wireguard"
|
||||||
}
|
}
|
||||||
local encrypt_methods_ss_aead = {
|
local encrypt_methods_ss_aead = {
|
||||||
"chacha20-ietf-poly1305",
|
"chacha20-ietf-poly1305",
|
||||||
@ -75,42 +75,42 @@ remarks.rmempty = false
|
|||||||
|
|
||||||
type = s:option(ListValue, "type", translate("Type"))
|
type = s:option(ListValue, "type", translate("Type"))
|
||||||
if api.is_finded("ipt2socks") then
|
if api.is_finded("ipt2socks") then
|
||||||
type:value("Socks", translate("Socks"))
|
type:value("Socks", translate("Socks"))
|
||||||
end
|
end
|
||||||
if api.is_finded("ss-redir") then
|
if api.is_finded("ss-redir") then
|
||||||
type:value("SS", translate("Shadowsocks Libev"))
|
type:value("SS", translate("Shadowsocks Libev"))
|
||||||
end
|
end
|
||||||
if api.is_finded("sslocal") then
|
if api.is_finded("sslocal") then
|
||||||
type:value("SS-Rust", translate("Shadowsocks Rust"))
|
type:value("SS-Rust", translate("Shadowsocks Rust"))
|
||||||
end
|
end
|
||||||
if api.is_finded("ssr-redir") then
|
if api.is_finded("ssr-redir") then
|
||||||
type:value("SSR", translate("ShadowsocksR Libev"))
|
type:value("SSR", translate("ShadowsocksR Libev"))
|
||||||
end
|
end
|
||||||
if api.is_finded("v2ray") then
|
if api.is_finded("v2ray") then
|
||||||
type:value("V2ray", translate("V2ray"))
|
type:value("V2ray", translate("V2ray"))
|
||||||
end
|
end
|
||||||
if api.is_finded("xray") then
|
if api.is_finded("xray") then
|
||||||
type:value("Xray", translate("Xray"))
|
type:value("Xray", translate("Xray"))
|
||||||
end
|
end
|
||||||
if api.is_finded("brook") then
|
if api.is_finded("brook") then
|
||||||
type:value("Brook", translate("Brook"))
|
type:value("Brook", translate("Brook"))
|
||||||
end
|
end
|
||||||
--[[
|
--[[
|
||||||
if api.is_finded("trojan-plus") or api.is_finded("trojan") then
|
if api.is_finded("trojan-plus") or api.is_finded("trojan") then
|
||||||
type:value("Trojan", translate("Trojan"))
|
type:value("Trojan", translate("Trojan"))
|
||||||
end
|
end
|
||||||
]]--
|
]]--
|
||||||
if api.is_finded("trojan-plus") then
|
if api.is_finded("trojan-plus") then
|
||||||
type:value("Trojan-Plus", translate("Trojan-Plus"))
|
type:value("Trojan-Plus", translate("Trojan-Plus"))
|
||||||
end
|
end
|
||||||
if api.is_finded("trojan-go") then
|
if api.is_finded("trojan-go") then
|
||||||
type:value("Trojan-Go", translate("Trojan-Go"))
|
type:value("Trojan-Go", translate("Trojan-Go"))
|
||||||
end
|
end
|
||||||
if api.is_finded("naive") then
|
if api.is_finded("naive") then
|
||||||
type:value("Naiveproxy", translate("NaiveProxy"))
|
type:value("Naiveproxy", translate("NaiveProxy"))
|
||||||
end
|
end
|
||||||
if api.is_finded("hysteria") then
|
if api.is_finded("hysteria") then
|
||||||
type:value("Hysteria", translate("Hysteria"))
|
type:value("Hysteria", translate("Hysteria"))
|
||||||
end
|
end
|
||||||
|
|
||||||
protocol = s:option(ListValue, "protocol", translate("Protocol"))
|
protocol = s:option(ListValue, "protocol", translate("Protocol"))
|
||||||
@ -133,12 +133,12 @@ iface:depends("protocol", "_iface")
|
|||||||
|
|
||||||
local nodes_table = {}
|
local nodes_table = {}
|
||||||
for k, e in ipairs(api.get_valid_nodes()) do
|
for k, e in ipairs(api.get_valid_nodes()) do
|
||||||
if e.node_type == "normal" then
|
if e.node_type == "normal" then
|
||||||
nodes_table[#nodes_table + 1] = {
|
nodes_table[#nodes_table + 1] = {
|
||||||
id = e[".name"],
|
id = e[".name"],
|
||||||
remarks = e["remark"]
|
remarks = e["remark"]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- 负载均衡列表
|
-- 负载均衡列表
|
||||||
@ -148,33 +148,33 @@ balancing_node:depends("protocol", "_balancing")
|
|||||||
|
|
||||||
-- 分流
|
-- 分流
|
||||||
uci:foreach(appname, "shunt_rules", function(e)
|
uci:foreach(appname, "shunt_rules", function(e)
|
||||||
if e[".name"] and e.remarks then
|
if e[".name"] and e.remarks then
|
||||||
o = s:option(ListValue, e[".name"], string.format('* <a href="%s" target="_blank">%s</a>', api.url("shunt_rules", e[".name"]), e.remarks))
|
o = s:option(ListValue, e[".name"], string.format('* <a href="%s" target="_blank">%s</a>', api.url("shunt_rules", e[".name"]), e.remarks))
|
||||||
o:value("nil", translate("Close"))
|
o:value("nil", translate("Close"))
|
||||||
o:value("_default", translate("Default"))
|
o:value("_default", translate("Default"))
|
||||||
o:value("_direct", translate("Direct Connection"))
|
o:value("_direct", translate("Direct Connection"))
|
||||||
o:value("_blackhole", translate("Blackhole"))
|
o:value("_blackhole", translate("Blackhole"))
|
||||||
o:depends("protocol", "_shunt")
|
o:depends("protocol", "_shunt")
|
||||||
|
|
||||||
if #nodes_table > 0 then
|
if #nodes_table > 0 then
|
||||||
_proxy_tag = s:option(ListValue, e[".name"] .. "_proxy_tag", string.format('* <a style="color:red">%s</a>', e.remarks .. " " .. translate("Preproxy")))
|
_proxy_tag = s:option(ListValue, e[".name"] .. "_proxy_tag", string.format('* <a style="color:red">%s</a>', e.remarks .. " " .. translate("Preproxy")))
|
||||||
_proxy_tag:value("nil", translate("Close"))
|
_proxy_tag:value("nil", translate("Close"))
|
||||||
_proxy_tag:value("default", translate("Default"))
|
_proxy_tag:value("default", translate("Default"))
|
||||||
_proxy_tag:value("main", translate("Default Preproxy"))
|
_proxy_tag:value("main", translate("Default Preproxy"))
|
||||||
_proxy_tag.default = "nil"
|
_proxy_tag.default = "nil"
|
||||||
|
|
||||||
for k, v in pairs(nodes_table) do
|
for k, v in pairs(nodes_table) do
|
||||||
o:value(v.id, v.remarks)
|
o:value(v.id, v.remarks)
|
||||||
_proxy_tag:depends(e[".name"], v.id)
|
_proxy_tag:depends(e[".name"], v.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
shunt_tips = s:option(DummyValue, "shunt_tips", " ")
|
shunt_tips = s:option(DummyValue, "shunt_tips", " ")
|
||||||
shunt_tips.rawhtml = true
|
shunt_tips.rawhtml = true
|
||||||
shunt_tips.cfgvalue = function(t, n)
|
shunt_tips.cfgvalue = function(t, n)
|
||||||
return string.format('<a style="color: red" href="../rule">%s</a>', translate("No shunt rules? Click me to go to add."))
|
return string.format('<a style="color: red" href="../rule">%s</a>', translate("No shunt rules? Click me to go to add."))
|
||||||
end
|
end
|
||||||
shunt_tips:depends("protocol", "_shunt")
|
shunt_tips:depends("protocol", "_shunt")
|
||||||
|
|
||||||
@ -185,12 +185,12 @@ for k, v in pairs(nodes_table) do default_node:value(v.id, v.remarks) end
|
|||||||
default_node:depends("protocol", "_shunt")
|
default_node:depends("protocol", "_shunt")
|
||||||
|
|
||||||
if #nodes_table > 0 then
|
if #nodes_table > 0 then
|
||||||
o = s:option(ListValue, "main_node", string.format('* <a style="color:red">%s</a>', translate("Default Preproxy")), translate("When using, localhost will connect this node first and then use this node to connect the default node."))
|
o = s:option(ListValue, "main_node", string.format('* <a style="color:red">%s</a>', translate("Default Preproxy")), translate("When using, localhost will connect this node first and then use this node to connect the default node."))
|
||||||
o:value("nil", translate("Close"))
|
o:value("nil", translate("Close"))
|
||||||
for k, v in pairs(nodes_table) do
|
for k, v in pairs(nodes_table) do
|
||||||
o:value(v.id, v.remarks)
|
o:value(v.id, v.remarks)
|
||||||
o:depends("default_node", v.id)
|
o:depends("default_node", v.id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
dialerProxy = s:option(Flag, "dialerProxy", translate("dialerProxy"))
|
dialerProxy = s:option(Flag, "dialerProxy", translate("dialerProxy"))
|
||||||
@ -504,13 +504,13 @@ uuid:depends({ type = "Xray", protocol = "vless" })
|
|||||||
tls = s:option(Flag, "tls", translate("TLS"))
|
tls = s:option(Flag, "tls", translate("TLS"))
|
||||||
tls.default = 0
|
tls.default = 0
|
||||||
tls.validate = function(self, value, t)
|
tls.validate = function(self, value, t)
|
||||||
if value then
|
if value then
|
||||||
local type = type:formvalue(t) or ""
|
local type = type:formvalue(t) or ""
|
||||||
if value == "0" and (type == "Trojan" or type == "Trojan-Plus") then
|
if value == "0" and (type == "Trojan" or type == "Trojan-Plus") then
|
||||||
return nil, translate("Original Trojan only supported 'tls', please choose 'tls'.")
|
return nil, translate("Original Trojan only supported 'tls', please choose 'tls'.")
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
tls:depends({ type = "V2ray", protocol = "vmess" })
|
tls:depends({ type = "V2ray", protocol = "vmess" })
|
||||||
tls:depends({ type = "V2ray", protocol = "vless" })
|
tls:depends({ type = "V2ray", protocol = "vless" })
|
||||||
@ -926,11 +926,11 @@ hysteria_disable_mtu_discovery = s:option(Flag, "hysteria_disable_mtu_discovery"
|
|||||||
hysteria_disable_mtu_discovery:depends("type", "Hysteria")
|
hysteria_disable_mtu_discovery:depends("type", "Hysteria")
|
||||||
|
|
||||||
protocol.validate = function(self, value)
|
protocol.validate = function(self, value)
|
||||||
if value == "_shunt" or value == "_balancing" then
|
if value == "_shunt" or value == "_balancing" then
|
||||||
address.rmempty = true
|
address.rmempty = true
|
||||||
port.rmempty = true
|
port.rmempty = true
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
@ -26,104 +26,104 @@ s.addremove = true
|
|||||||
s.template = "cbi/tblsection"
|
s.template = "cbi/tblsection"
|
||||||
s.extedit = api.url("node_config", "%s")
|
s.extedit = api.url("node_config", "%s")
|
||||||
function s.create(e, t)
|
function s.create(e, t)
|
||||||
local uuid = api.gen_uuid()
|
local uuid = api.gen_uuid()
|
||||||
t = uuid
|
t = uuid
|
||||||
TypedSection.create(e, t)
|
TypedSection.create(e, t)
|
||||||
luci.http.redirect(e.extedit:format(t))
|
luci.http.redirect(e.extedit:format(t))
|
||||||
end
|
end
|
||||||
|
|
||||||
function s.remove(e, t)
|
function s.remove(e, t)
|
||||||
m.uci:foreach(appname, "socks", function(s)
|
m.uci:foreach(appname, "socks", function(s)
|
||||||
if s["node"] == t then
|
if s["node"] == t then
|
||||||
m:del(s[".name"])
|
m:del(s[".name"])
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
m.uci:foreach(appname, "haproxy_config", function(s)
|
m.uci:foreach(appname, "haproxy_config", function(s)
|
||||||
if s["lbss"] and s["lbss"] == t then
|
if s["lbss"] and s["lbss"] == t then
|
||||||
m:del(s[".name"])
|
m:del(s[".name"])
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
m.uci:foreach(appname, "acl_rule", function(s)
|
m.uci:foreach(appname, "acl_rule", function(s)
|
||||||
if s["tcp_node"] and s["tcp_node"] == t then
|
if s["tcp_node"] and s["tcp_node"] == t then
|
||||||
m:set(s[".name"], "tcp_node", "default")
|
m:set(s[".name"], "tcp_node", "default")
|
||||||
end
|
end
|
||||||
if s["udp_node"] and s["udp_node"] == t then
|
if s["udp_node"] and s["udp_node"] == t then
|
||||||
m:set(s[".name"], "udp_node", "default")
|
m:set(s[".name"], "udp_node", "default")
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
for k, v in ipairs(m:get("@auto_switch[0]", "tcp_node") or {}) do
|
for k, v in ipairs(m:get("@auto_switch[0]", "tcp_node") or {}) do
|
||||||
if v and v == t then
|
if v and v == t then
|
||||||
sys.call(string.format("uci -q del_list %s.@auto_switch[0].tcp_node='%s'", appname, v))
|
sys.call(string.format("uci -q del_list %s.@auto_switch[0].tcp_node='%s'", appname, v))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
TypedSection.remove(e, t)
|
TypedSection.remove(e, t)
|
||||||
local new_node = "nil"
|
local new_node = "nil"
|
||||||
local node0 = m:get("@nodes[0]") or nil
|
local node0 = m:get("@nodes[0]") or nil
|
||||||
if node0 then
|
if node0 then
|
||||||
new_node = node0[".name"]
|
new_node = node0[".name"]
|
||||||
end
|
end
|
||||||
if (m:get("@global[0]", "tcp_node") or "nil") == t then
|
if (m:get("@global[0]", "tcp_node") or "nil") == t then
|
||||||
m:set('@global[0]', "tcp_node", new_node)
|
m:set('@global[0]', "tcp_node", new_node)
|
||||||
end
|
end
|
||||||
if (m:get("@global[0]", "udp_node") or "nil") == t then
|
if (m:get("@global[0]", "udp_node") or "nil") == t then
|
||||||
m:set('@global[0]', "udp_node", new_node)
|
m:set('@global[0]', "udp_node", new_node)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
s.sortable = true
|
s.sortable = true
|
||||||
-- 简洁模式
|
-- 简洁模式
|
||||||
o = s:option(DummyValue, "add_from", "")
|
o = s:option(DummyValue, "add_from", "")
|
||||||
o.cfgvalue = function(t, n)
|
o.cfgvalue = function(t, n)
|
||||||
local v = Value.cfgvalue(t, n)
|
local v = Value.cfgvalue(t, n)
|
||||||
if v and v ~= '' then
|
if v and v ~= '' then
|
||||||
local group = m:get(n, "group") or ""
|
local group = m:get(n, "group") or ""
|
||||||
if group ~= "" then
|
if group ~= "" then
|
||||||
v = v .. " " .. group
|
v = v .. " " .. group
|
||||||
end
|
end
|
||||||
return v
|
return v
|
||||||
else
|
else
|
||||||
return ''
|
return ''
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
o = s:option(DummyValue, "remarks", translate("Remarks"))
|
o = s:option(DummyValue, "remarks", translate("Remarks"))
|
||||||
o.rawhtml = true
|
o.rawhtml = true
|
||||||
o.cfgvalue = function(t, n)
|
o.cfgvalue = function(t, n)
|
||||||
local str = ""
|
local str = ""
|
||||||
local is_sub = m:get(n, "is_sub") or ""
|
local is_sub = m:get(n, "is_sub") or ""
|
||||||
local group = m:get(n, "group") or ""
|
local group = m:get(n, "group") or ""
|
||||||
local remarks = m:get(n, "remarks") or ""
|
local remarks = m:get(n, "remarks") or ""
|
||||||
local type = m:get(n, "type") or ""
|
local type = m:get(n, "type") or ""
|
||||||
str = str .. string.format("<input type='hidden' id='cbid.%s.%s.type' value='%s'/>", appname, n, type)
|
str = str .. string.format("<input type='hidden' id='cbid.%s.%s.type' value='%s'/>", appname, n, type)
|
||||||
if type == "V2ray" or type == "Xray" then
|
if type == "V2ray" or type == "Xray" then
|
||||||
local protocol = m:get(n, "protocol")
|
local protocol = m:get(n, "protocol")
|
||||||
if protocol == "_balancing" then
|
if protocol == "_balancing" then
|
||||||
protocol = translate("Balancing")
|
protocol = translate("Balancing")
|
||||||
elseif protocol == "_shunt" then
|
elseif protocol == "_shunt" then
|
||||||
protocol = translate("Shunt")
|
protocol = translate("Shunt")
|
||||||
elseif protocol == "vmess" then
|
elseif protocol == "vmess" then
|
||||||
protocol = "VMess"
|
protocol = "VMess"
|
||||||
elseif protocol == "vless" then
|
elseif protocol == "vless" then
|
||||||
protocol = "VLESS"
|
protocol = "VLESS"
|
||||||
else
|
else
|
||||||
protocol = protocol:gsub("^%l",string.upper)
|
protocol = protocol:gsub("^%l",string.upper)
|
||||||
end
|
end
|
||||||
type = type .. " " .. protocol
|
type = type .. " " .. protocol
|
||||||
end
|
end
|
||||||
local address = m:get(n, "address") or ""
|
local address = m:get(n, "address") or ""
|
||||||
local port = m:get(n, "port") or ""
|
local port = m:get(n, "port") or ""
|
||||||
str = str .. translate(type) .. ":" .. remarks
|
str = str .. translate(type) .. ":" .. remarks
|
||||||
if address ~= "" and port ~= "" then
|
if address ~= "" and port ~= "" then
|
||||||
if nodes_ping:find("info") then
|
if nodes_ping:find("info") then
|
||||||
if datatypes.ip6addr(address) then
|
if datatypes.ip6addr(address) then
|
||||||
str = str .. string.format("([%s]:%s)", address, port)
|
str = str .. string.format("([%s]:%s)", address, port)
|
||||||
else
|
else
|
||||||
str = str .. string.format("(%s:%s)", address, port)
|
str = str .. string.format("(%s:%s)", address, port)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
str = str .. string.format("<input type='hidden' id='cbid.%s.%s.address' value='%s'/>", appname, n, address)
|
str = str .. string.format("<input type='hidden' id='cbid.%s.%s.address' value='%s'/>", appname, n, address)
|
||||||
str = str .. string.format("<input type='hidden' id='cbid.%s.%s.port' value='%s'/>", appname, n, port)
|
str = str .. string.format("<input type='hidden' id='cbid.%s.%s.port' value='%s'/>", appname, n, port)
|
||||||
end
|
end
|
||||||
return str
|
return str
|
||||||
end
|
end
|
||||||
|
|
||||||
---- Ping
|
---- Ping
|
||||||
@ -131,19 +131,19 @@ o = s:option(DummyValue, "ping")
|
|||||||
o.width = "8%"
|
o.width = "8%"
|
||||||
o.rawhtml = true
|
o.rawhtml = true
|
||||||
o.cfgvalue = function(t, n)
|
o.cfgvalue = function(t, n)
|
||||||
local result = "---"
|
local result = "---"
|
||||||
if not nodes_ping:find("auto_ping") then
|
if not nodes_ping:find("auto_ping") then
|
||||||
result = string.format('<span class="ping"><a href="javascript:void(0)" onclick="javascript:ping_node(\'%s\',this)">Ping</a></span>', n)
|
result = string.format('<span class="ping"><a href="javascript:void(0)" onclick="javascript:ping_node(\'%s\',this)">Ping</a></span>', n)
|
||||||
else
|
else
|
||||||
result = string.format('<span class="ping_value" cbiid="%s">---</span>', n)
|
result = string.format('<span class="ping_value" cbiid="%s">---</span>', n)
|
||||||
end
|
end
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:option(DummyValue, "_url_test")
|
o = s:option(DummyValue, "_url_test")
|
||||||
o.rawhtml = true
|
o.rawhtml = true
|
||||||
o.cfgvalue = function(t, n)
|
o.cfgvalue = function(t, n)
|
||||||
return string.format('<input type="button" class="cbi-button" value="%s" onclick="javascript:urltest_node(\'%s\',this)"', translate("Availability test"), n)
|
return string.format('<input type="button" class="cbi-button" value="%s" onclick="javascript:urltest_node(\'%s\',this)"', translate("Availability test"), n)
|
||||||
end
|
end
|
||||||
|
|
||||||
m:append(Template(appname .. "/node_list/node_list"))
|
m:append(Template(appname .. "/node_list/node_list"))
|
||||||
|
@ -9,24 +9,24 @@ local has_trojan_go = api.is_finded("trojan-go")
|
|||||||
local ss_aead_type = {}
|
local ss_aead_type = {}
|
||||||
local trojan_type = {}
|
local trojan_type = {}
|
||||||
if has_ss then
|
if has_ss then
|
||||||
ss_aead_type[#ss_aead_type + 1] = "shadowsocks-libev"
|
ss_aead_type[#ss_aead_type + 1] = "shadowsocks-libev"
|
||||||
end
|
end
|
||||||
if has_ss_rust then
|
if has_ss_rust then
|
||||||
ss_aead_type[#ss_aead_type + 1] = "shadowsocks-rust"
|
ss_aead_type[#ss_aead_type + 1] = "shadowsocks-rust"
|
||||||
end
|
end
|
||||||
if has_trojan_plus then
|
if has_trojan_plus then
|
||||||
trojan_type[#trojan_type + 1] = "trojan-plus"
|
trojan_type[#trojan_type + 1] = "trojan-plus"
|
||||||
end
|
end
|
||||||
if has_v2ray then
|
if has_v2ray then
|
||||||
trojan_type[#trojan_type + 1] = "v2ray"
|
trojan_type[#trojan_type + 1] = "v2ray"
|
||||||
ss_aead_type[#ss_aead_type + 1] = "v2ray"
|
ss_aead_type[#ss_aead_type + 1] = "v2ray"
|
||||||
end
|
end
|
||||||
if has_xray then
|
if has_xray then
|
||||||
trojan_type[#trojan_type + 1] = "xray"
|
trojan_type[#trojan_type + 1] = "xray"
|
||||||
ss_aead_type[#ss_aead_type + 1] = "xray"
|
ss_aead_type[#ss_aead_type + 1] = "xray"
|
||||||
end
|
end
|
||||||
if has_trojan_go then
|
if has_trojan_go then
|
||||||
trojan_type[#trojan_type + 1] = "trojan-go"
|
trojan_type[#trojan_type + 1] = "trojan-go"
|
||||||
end
|
end
|
||||||
|
|
||||||
m = Map(appname)
|
m = Map(appname)
|
||||||
@ -47,31 +47,31 @@ o = s:option(DynamicList, "filter_discard_list", translate("Discard List"))
|
|||||||
o = s:option(DynamicList, "filter_keep_list", translate("Keep List"))
|
o = s:option(DynamicList, "filter_keep_list", translate("Keep List"))
|
||||||
|
|
||||||
if #ss_aead_type > 0 then
|
if #ss_aead_type > 0 then
|
||||||
o = s:option(ListValue, "ss_aead_type", translate("SS AEAD Node Use Type"))
|
o = s:option(ListValue, "ss_aead_type", translate("SS AEAD Node Use Type"))
|
||||||
for key, value in pairs(ss_aead_type) do
|
for key, value in pairs(ss_aead_type) do
|
||||||
o:value(value, translate(value:gsub("^%l",string.upper)))
|
o:value(value, translate(value:gsub("^%l",string.upper)))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if #trojan_type > 0 then
|
if #trojan_type > 0 then
|
||||||
o = s:option(ListValue, "trojan_type", translate("Trojan Node Use Type"))
|
o = s:option(ListValue, "trojan_type", translate("Trojan Node Use Type"))
|
||||||
for key, value in pairs(trojan_type) do
|
for key, value in pairs(trojan_type) do
|
||||||
o:value(value, translate(value:gsub("^%l",string.upper)))
|
o:value(value, translate(value:gsub("^%l",string.upper)))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---- Subscribe Delete All
|
---- Subscribe Delete All
|
||||||
o = s:option(Button, "_stop", translate("Delete All Subscribe Node"))
|
o = s:option(Button, "_stop", translate("Delete All Subscribe Node"))
|
||||||
o.inputstyle = "remove"
|
o.inputstyle = "remove"
|
||||||
function o.write(e, e)
|
function o.write(e, e)
|
||||||
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua truncate > /dev/null 2>&1")
|
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua truncate > /dev/null 2>&1")
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:option(Button, "_update", translate("Manual subscription All"))
|
o = s:option(Button, "_update", translate("Manual subscription All"))
|
||||||
o.inputstyle = "apply"
|
o.inputstyle = "apply"
|
||||||
function o.write(t, n)
|
function o.write(t, n)
|
||||||
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start > /dev/null 2>&1 &")
|
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start > /dev/null 2>&1 &")
|
||||||
luci.http.redirect(api.url("log"))
|
luci.http.redirect(api.url("log"))
|
||||||
end
|
end
|
||||||
|
|
||||||
s = m:section(TypedSection, "subscribe_list", "", "<font color='red'>" .. translate("Please input the subscription url first, save and submit before manual subscription.") .. "</font>")
|
s = m:section(TypedSection, "subscribe_list", "", "<font color='red'>" .. translate("Please input the subscription url first, save and submit before manual subscription.") .. "</font>")
|
||||||
@ -81,39 +81,39 @@ s.sortable = true
|
|||||||
s.template = "cbi/tblsection"
|
s.template = "cbi/tblsection"
|
||||||
s.extedit = api.url("node_subscribe_config", "%s")
|
s.extedit = api.url("node_subscribe_config", "%s")
|
||||||
function s.create(e, t)
|
function s.create(e, t)
|
||||||
local id = TypedSection.create(e, t)
|
local id = TypedSection.create(e, t)
|
||||||
luci.http.redirect(e.extedit:format(id))
|
luci.http.redirect(e.extedit:format(id))
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:option(Value, "remark", translate("Remarks"))
|
o = s:option(Value, "remark", translate("Remarks"))
|
||||||
o.width = "auto"
|
o.width = "auto"
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
o.validate = function(self, value, t)
|
o.validate = function(self, value, t)
|
||||||
if value then
|
if value then
|
||||||
local count = 0
|
local count = 0
|
||||||
m.uci:foreach(appname, "subscribe_list", function(e)
|
m.uci:foreach(appname, "subscribe_list", function(e)
|
||||||
if e[".name"] ~= t and e["remark"] == value then
|
if e[".name"] ~= t and e["remark"] == value then
|
||||||
count = count + 1
|
count = count + 1
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
if count > 0 then
|
if count > 0 then
|
||||||
return nil, translate("This remark already exists, please change a new remark.")
|
return nil, translate("This remark already exists, please change a new remark.")
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:option(DummyValue, "_node_count")
|
o = s:option(DummyValue, "_node_count")
|
||||||
o.rawhtml = true
|
o.rawhtml = true
|
||||||
o.cfgvalue = function(t, n)
|
o.cfgvalue = function(t, n)
|
||||||
local remark = m:get(n, "remark") or ""
|
local remark = m:get(n, "remark") or ""
|
||||||
local num = 0
|
local num = 0
|
||||||
m.uci:foreach(appname, "nodes", function(s)
|
m.uci:foreach(appname, "nodes", function(s)
|
||||||
if s["add_from"] ~= "" and s["add_from"] == remark then
|
if s["add_from"] ~= "" and s["add_from"] == remark then
|
||||||
num = num + 1
|
num = num + 1
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
return string.format("<span title='%s' style='color:red'>%s</span>", remark .. " " .. translate("Node num") .. ": " .. num, num)
|
return string.format("<span title='%s' style='color:red'>%s</span>", remark .. " " .. translate("Node num") .. ": " .. num, num)
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:option(Value, "url", translate("Subscribe URL"))
|
o = s:option(Value, "url", translate("Subscribe URL"))
|
||||||
@ -123,15 +123,15 @@ o.rmempty = false
|
|||||||
o = s:option(Button, "_remove", translate("Delete the subscribed node"))
|
o = s:option(Button, "_remove", translate("Delete the subscribed node"))
|
||||||
o.inputstyle = "remove"
|
o.inputstyle = "remove"
|
||||||
function o.write(t, n)
|
function o.write(t, n)
|
||||||
local remark = m:get(n, "remark") or ""
|
local remark = m:get(n, "remark") or ""
|
||||||
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua truncate " .. remark .. " > /dev/null 2>&1")
|
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua truncate " .. remark .. " > /dev/null 2>&1")
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:option(Button, "_update", translate("Manual subscription"))
|
o = s:option(Button, "_update", translate("Manual subscription"))
|
||||||
o.inputstyle = "apply"
|
o.inputstyle = "apply"
|
||||||
function o.write(t, n)
|
function o.write(t, n)
|
||||||
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start " .. n .. " > /dev/null 2>&1 &")
|
luci.sys.call("lua /usr/share/" .. appname .. "/subscribe.lua start " .. n .. " > /dev/null 2>&1 &")
|
||||||
luci.http.redirect(api.url("log"))
|
luci.http.redirect(api.url("log"))
|
||||||
end
|
end
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
@ -10,24 +10,24 @@ local has_trojan_go = api.is_finded("trojan-go")
|
|||||||
local ss_aead_type = {}
|
local ss_aead_type = {}
|
||||||
local trojan_type = {}
|
local trojan_type = {}
|
||||||
if has_ss then
|
if has_ss then
|
||||||
ss_aead_type[#ss_aead_type + 1] = "shadowsocks-libev"
|
ss_aead_type[#ss_aead_type + 1] = "shadowsocks-libev"
|
||||||
end
|
end
|
||||||
if has_ss_rust then
|
if has_ss_rust then
|
||||||
ss_aead_type[#ss_aead_type + 1] = "shadowsocks-rust"
|
ss_aead_type[#ss_aead_type + 1] = "shadowsocks-rust"
|
||||||
end
|
end
|
||||||
if has_trojan_plus then
|
if has_trojan_plus then
|
||||||
trojan_type[#trojan_type + 1] = "trojan-plus"
|
trojan_type[#trojan_type + 1] = "trojan-plus"
|
||||||
end
|
end
|
||||||
if has_v2ray then
|
if has_v2ray then
|
||||||
trojan_type[#trojan_type + 1] = "v2ray"
|
trojan_type[#trojan_type + 1] = "v2ray"
|
||||||
ss_aead_type[#ss_aead_type + 1] = "v2ray"
|
ss_aead_type[#ss_aead_type + 1] = "v2ray"
|
||||||
end
|
end
|
||||||
if has_xray then
|
if has_xray then
|
||||||
trojan_type[#trojan_type + 1] = "xray"
|
trojan_type[#trojan_type + 1] = "xray"
|
||||||
ss_aead_type[#ss_aead_type + 1] = "xray"
|
ss_aead_type[#ss_aead_type + 1] = "xray"
|
||||||
end
|
end
|
||||||
if has_trojan_go then
|
if has_trojan_go then
|
||||||
trojan_type[#trojan_type + 1] = "trojan-go"
|
trojan_type[#trojan_type + 1] = "trojan-go"
|
||||||
end
|
end
|
||||||
|
|
||||||
m = Map(appname)
|
m = Map(appname)
|
||||||
@ -68,21 +68,21 @@ o:depends("filter_keyword_mode", "3")
|
|||||||
o:depends("filter_keyword_mode", "4")
|
o:depends("filter_keyword_mode", "4")
|
||||||
|
|
||||||
if #ss_aead_type > 0 then
|
if #ss_aead_type > 0 then
|
||||||
o = s:option(ListValue, "ss_aead_type", translate("SS AEAD Node Use Type"))
|
o = s:option(ListValue, "ss_aead_type", translate("SS AEAD Node Use Type"))
|
||||||
o.default = "global"
|
o.default = "global"
|
||||||
o:value("global", translate("Use global config"))
|
o:value("global", translate("Use global config"))
|
||||||
for key, value in pairs(ss_aead_type) do
|
for key, value in pairs(ss_aead_type) do
|
||||||
o:value(value, translate(value:gsub("^%l",string.upper)))
|
o:value(value, translate(value:gsub("^%l",string.upper)))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if #trojan_type > 0 then
|
if #trojan_type > 0 then
|
||||||
o = s:option(ListValue, "trojan_type", translate("Trojan Node Use Type"))
|
o = s:option(ListValue, "trojan_type", translate("Trojan Node Use Type"))
|
||||||
o.default = "global"
|
o.default = "global"
|
||||||
o:value("global", translate("Use global config"))
|
o:value("global", translate("Use global config"))
|
||||||
for key, value in pairs(trojan_type) do
|
for key, value in pairs(trojan_type) do
|
||||||
o:value(value, translate(value:gsub("^%l",string.upper)))
|
o:value(value, translate(value:gsub("^%l",string.upper)))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---- Enable auto update subscribe
|
---- Enable auto update subscribe
|
||||||
|
@ -15,7 +15,7 @@ s.addremove = false
|
|||||||
|
|
||||||
---- Delay Start
|
---- Delay Start
|
||||||
o = s:option(Value, "start_delay", translate("Delay Start"),
|
o = s:option(Value, "start_delay", translate("Delay Start"),
|
||||||
translate("Units:seconds"))
|
translate("Units:seconds"))
|
||||||
o.default = "1"
|
o.default = "1"
|
||||||
o.rmempty = true
|
o.rmempty = true
|
||||||
|
|
||||||
@ -54,7 +54,7 @@ for e = 0, 23 do o:value(e, e .. translate("oclock")) end
|
|||||||
|
|
||||||
-- [[ Forwarding Settings ]]--
|
-- [[ Forwarding Settings ]]--
|
||||||
s = m:section(TypedSection, "global_forwarding",
|
s = m:section(TypedSection, "global_forwarding",
|
||||||
translate("Forwarding Settings"))
|
translate("Forwarding Settings"))
|
||||||
s.anonymous = true
|
s.anonymous = true
|
||||||
s.addremove = false
|
s.addremove = false
|
||||||
|
|
||||||
@ -66,9 +66,9 @@ o:value("1:65535", translate("All"))
|
|||||||
|
|
||||||
---- UDP No Redir Ports
|
---- UDP No Redir Ports
|
||||||
o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"),
|
o = s:option(Value, "udp_no_redir_ports", translate("UDP No Redir Ports"),
|
||||||
"<font color='red'>" .. translate(
|
"<font color='red'>" .. translate(
|
||||||
"Fill in the ports you don't want to be forwarded by the agent, with the highest priority.") ..
|
"Fill in the ports you don't want to be forwarded by the agent, with the highest priority.") ..
|
||||||
"</font>")
|
"</font>")
|
||||||
o.default = "disable"
|
o.default = "disable"
|
||||||
o:value("disable", translate("No patterns are used"))
|
o:value("disable", translate("No patterns are used"))
|
||||||
o:value("1:65535", translate("All"))
|
o:value("1:65535", translate("All"))
|
||||||
@ -101,36 +101,36 @@ o:value("53", "DNS")
|
|||||||
o = s:option(ListValue, "use_nft", translate("Firewall tools"))
|
o = s:option(ListValue, "use_nft", translate("Firewall tools"))
|
||||||
o.default = "0"
|
o.default = "0"
|
||||||
if has_fw3 then
|
if has_fw3 then
|
||||||
o:value("0", "IPtables")
|
o:value("0", "IPtables")
|
||||||
end
|
end
|
||||||
if has_fw4 then
|
if has_fw4 then
|
||||||
o:value("1", "NFtables")
|
o:value("1", "NFtables")
|
||||||
end
|
end
|
||||||
|
|
||||||
if (os.execute("lsmod | grep -i REDIRECT >/dev/null") == 0 and os.execute("lsmod | grep -i TPROXY >/dev/null") == 0) or (os.execute("lsmod | grep -i nft_redir >/dev/null") == 0 and os.execute("lsmod | grep -i nft_tproxy >/dev/null") == 0) then
|
if (os.execute("lsmod | grep -i REDIRECT >/dev/null") == 0 and os.execute("lsmod | grep -i TPROXY >/dev/null") == 0) or (os.execute("lsmod | grep -i nft_redir >/dev/null") == 0 and os.execute("lsmod | grep -i nft_tproxy >/dev/null") == 0) then
|
||||||
o = s:option(ListValue, "tcp_proxy_way", translate("TCP Proxy Way"))
|
o = s:option(ListValue, "tcp_proxy_way", translate("TCP Proxy Way"))
|
||||||
o.default = "tproxy"
|
o.default = "redirect"
|
||||||
o:value("redirect", "REDIRECT")
|
o:value("redirect", "REDIRECT")
|
||||||
o:value("tproxy", "TPROXY")
|
o:value("tproxy", "TPROXY")
|
||||||
o:depends("ipv6_tproxy", false)
|
o:depends("ipv6_tproxy", false)
|
||||||
|
|
||||||
o = s:option(ListValue, "_tcp_proxy_way", translate("TCP Proxy Way"))
|
o = s:option(ListValue, "_tcp_proxy_way", translate("TCP Proxy Way"))
|
||||||
o.default = "tproxy"
|
o.default = "tproxy"
|
||||||
o:value("tproxy", "TPROXY")
|
o:value("tproxy", "TPROXY")
|
||||||
o:depends("ipv6_tproxy", true)
|
o:depends("ipv6_tproxy", true)
|
||||||
o.write = function(self, section, value)
|
o.write = function(self, section, value)
|
||||||
return self.map:set(section, "tcp_proxy_way", value)
|
return self.map:set(section, "tcp_proxy_way", value)
|
||||||
end
|
end
|
||||||
|
|
||||||
if os.execute("lsmod | grep -i ip6table_mangle >/dev/null") == 0 or os.execute("lsmod | grep -i nft_tproxy >/dev/null") == 0 then
|
if os.execute("lsmod | grep -i ip6table_mangle >/dev/null") == 0 or os.execute("lsmod | grep -i nft_tproxy >/dev/null") == 0 then
|
||||||
---- IPv6 TProxy
|
---- IPv6 TProxy
|
||||||
o = s:option(Flag, "ipv6_tproxy", translate("IPv6 TProxy"),
|
o = s:option(Flag, "ipv6_tproxy", translate("IPv6 TProxy"),
|
||||||
"<font color='red'>" .. translate(
|
"<font color='red'>" .. translate(
|
||||||
"Experimental feature. Make sure that your node supports IPv6.") ..
|
"Experimental feature. Make sure that your node supports IPv6.") ..
|
||||||
"</font>")
|
"</font>")
|
||||||
o.default = 0
|
o.default = 0
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:option(Flag, "accept_icmp", translate("Hijacking ICMP (PING)"))
|
o = s:option(Flag, "accept_icmp", translate("Hijacking ICMP (PING)"))
|
||||||
@ -141,31 +141,31 @@ o:depends("ipv6_tproxy", true)
|
|||||||
o.default = 0
|
o.default = 0
|
||||||
|
|
||||||
if has_v2ray or has_xray then
|
if has_v2ray or has_xray then
|
||||||
o = s:option(Flag, "sniffing", translate("Sniffing (V2Ray/Xray)"), translate("When using the V2ray/Xray shunt, must be enabled, otherwise the shunt will invalid."))
|
o = s:option(Flag, "sniffing", translate("Sniffing (V2Ray/Xray)"), translate("When using the V2ray/Xray shunt, must be enabled, otherwise the shunt will invalid."))
|
||||||
o.default = 1
|
o.default = 1
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
|
|
||||||
if has_xray then
|
if has_xray then
|
||||||
route_only = s:option(Flag, "route_only", translate("Sniffing Route Only (Xray)"), translate("When enabled, the server not will resolve the domain name again."))
|
route_only = s:option(Flag, "route_only", translate("Sniffing Route Only (Xray)"), translate("When enabled, the server not will resolve the domain name again."))
|
||||||
route_only.default = 0
|
route_only.default = 0
|
||||||
route_only:depends("sniffing", true)
|
route_only:depends("sniffing", true)
|
||||||
|
|
||||||
local domains_excluded = string.format("/usr/share/%s/rules/domains_excluded", appname)
|
local domains_excluded = string.format("/usr/share/%s/rules/domains_excluded", appname)
|
||||||
o = s:option(TextValue, "no_sniffing_hosts", translate("No Sniffing Lists"), translate("Hosts added into No Sniffing Lists will not resolve again on server (Xray only)."))
|
o = s:option(TextValue, "no_sniffing_hosts", translate("No Sniffing Lists"), translate("Hosts added into No Sniffing Lists will not resolve again on server (Xray only)."))
|
||||||
o.rows = 15
|
o.rows = 15
|
||||||
o.wrap = "off"
|
o.wrap = "off"
|
||||||
o.cfgvalue = function(self, section) return fs.readfile(domains_excluded) or "" end
|
o.cfgvalue = function(self, section) return fs.readfile(domains_excluded) or "" end
|
||||||
o.write = function(self, section, value) fs.writefile(domains_excluded, value:gsub("\r\n", "\n")) end
|
o.write = function(self, section, value) fs.writefile(domains_excluded, value:gsub("\r\n", "\n")) end
|
||||||
o.remove = function(self, section, value)
|
o.remove = function(self, section, value)
|
||||||
if route_only:formvalue(section) == "0" then
|
if route_only:formvalue(section) == "0" then
|
||||||
fs.writefile(domains_excluded, "")
|
fs.writefile(domains_excluded, "")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
o:depends({sniffing = true, route_only = false})
|
o:depends({sniffing = true, route_only = false})
|
||||||
|
|
||||||
o = s:option(Value, "buffer_size", translate("Buffer Size (Xray)"), translate("Buffer size for every connection (kB)"))
|
o = s:option(Value, "buffer_size", translate("Buffer Size (Xray)"), translate("Buffer size for every connection (kB)"))
|
||||||
o.rmempty = true
|
o.rmempty = true
|
||||||
o.datatype = "uinteger"
|
o.datatype = "uinteger"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return m
|
return m
|
||||||
|
@ -62,30 +62,30 @@ o.default = 0
|
|||||||
o:depends("auto_update", true)
|
o:depends("auto_update", true)
|
||||||
|
|
||||||
if has_v2ray or has_xray then
|
if has_v2ray or has_xray then
|
||||||
o = s:option(Value, "v2ray_location_asset", translate("Location of V2ray/Xray asset"), translate("This variable specifies a directory where geoip.dat and geosite.dat files are."))
|
o = s:option(Value, "v2ray_location_asset", translate("Location of V2ray/Xray asset"), translate("This variable specifies a directory where geoip.dat and geosite.dat files are."))
|
||||||
o.default = "/usr/share/v2ray/"
|
o.default = "/usr/share/v2ray/"
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
|
|
||||||
s = m:section(TypedSection, "shunt_rules", "V2ray/Xray " .. translate("Shunt Rule"), "<a style='color: red'>" .. translate("Please note attention to the priority, the higher the order, the higher the priority.") .. "</a>")
|
s = m:section(TypedSection, "shunt_rules", "V2ray/Xray " .. translate("Shunt Rule"), "<a style='color: red'>" .. translate("Please note attention to the priority, the higher the order, the higher the priority.") .. "</a>")
|
||||||
s.template = "cbi/tblsection"
|
s.template = "cbi/tblsection"
|
||||||
s.anonymous = false
|
s.anonymous = false
|
||||||
s.addremove = true
|
s.addremove = true
|
||||||
s.sortable = true
|
s.sortable = true
|
||||||
s.extedit = api.url("shunt_rules", "%s")
|
s.extedit = api.url("shunt_rules", "%s")
|
||||||
function s.create(e, t)
|
function s.create(e, t)
|
||||||
TypedSection.create(e, t)
|
TypedSection.create(e, t)
|
||||||
luci.http.redirect(e.extedit:format(t))
|
luci.http.redirect(e.extedit:format(t))
|
||||||
end
|
end
|
||||||
function s.remove(e, t)
|
function s.remove(e, t)
|
||||||
m.uci:foreach(appname, "nodes", function(s)
|
m.uci:foreach(appname, "nodes", function(s)
|
||||||
if s["protocol"] and s["protocol"] == "_shunt" then
|
if s["protocol"] and s["protocol"] == "_shunt" then
|
||||||
m:del(s[".name"], t)
|
m:del(s[".name"], t)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
TypedSection.remove(e, t)
|
TypedSection.remove(e, t)
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:option(DummyValue, "remarks", translate("Remarks"))
|
o = s:option(DummyValue, "remarks", translate("Remarks"))
|
||||||
end
|
end
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
@ -24,28 +24,28 @@ o = s:taboption("direct_list", TextValue, "direct_host", "", "<font color='red'>
|
|||||||
o.rows = 15
|
o.rows = 15
|
||||||
o.wrap = "off"
|
o.wrap = "off"
|
||||||
o.cfgvalue = function(self, section)
|
o.cfgvalue = function(self, section)
|
||||||
return fs.readfile(direct_host) or ""
|
return fs.readfile(direct_host) or ""
|
||||||
end
|
end
|
||||||
o.write = function(self, section, value)
|
o.write = function(self, section, value)
|
||||||
fs.writefile(direct_host, value:gsub("\r\n", "\n"))
|
fs.writefile(direct_host, value:gsub("\r\n", "\n"))
|
||||||
sys.call("rm -rf /tmp/etc/passwall_tmp/dns_*")
|
sys.call("rm -rf /tmp/etc/passwall_tmp/dns_*")
|
||||||
end
|
end
|
||||||
o.remove = function(self, section, value)
|
o.remove = function(self, section, value)
|
||||||
fs.writefile(direct_host, "")
|
fs.writefile(direct_host, "")
|
||||||
sys.call("rm -rf /tmp/etc/passwall_tmp/dns_*")
|
sys.call("rm -rf /tmp/etc/passwall_tmp/dns_*")
|
||||||
end
|
end
|
||||||
o.validate = function(self, value)
|
o.validate = function(self, value)
|
||||||
local hosts= {}
|
local hosts= {}
|
||||||
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(hosts, w) end)
|
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(hosts, w) end)
|
||||||
for index, host in ipairs(hosts) do
|
for index, host in ipairs(hosts) do
|
||||||
if host:find("#") and host:find("#") == 1 then
|
if host:find("#") and host:find("#") == 1 then
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
if not datatypes.hostname(host) then
|
if not datatypes.hostname(host) then
|
||||||
return nil, host .. " " .. translate("Not valid domain name, please re-enter!")
|
return nil, host .. " " .. translate("Not valid domain name, please re-enter!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
|
|
||||||
---- Direct IP
|
---- Direct IP
|
||||||
@ -54,26 +54,26 @@ o = s:taboption("direct_list", TextValue, "direct_ip", "", "<font color='red'>"
|
|||||||
o.rows = 15
|
o.rows = 15
|
||||||
o.wrap = "off"
|
o.wrap = "off"
|
||||||
o.cfgvalue = function(self, section)
|
o.cfgvalue = function(self, section)
|
||||||
return fs.readfile(direct_ip) or ""
|
return fs.readfile(direct_ip) or ""
|
||||||
end
|
end
|
||||||
o.write = function(self, section, value)
|
o.write = function(self, section, value)
|
||||||
fs.writefile(direct_ip, value:gsub("\r\n", "\n"))
|
fs.writefile(direct_ip, value:gsub("\r\n", "\n"))
|
||||||
end
|
end
|
||||||
o.remove = function(self, section, value)
|
o.remove = function(self, section, value)
|
||||||
fs.writefile(direct_ip, "")
|
fs.writefile(direct_ip, "")
|
||||||
end
|
end
|
||||||
o.validate = function(self, value)
|
o.validate = function(self, value)
|
||||||
local ipmasks= {}
|
local ipmasks= {}
|
||||||
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, w) end)
|
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, w) end)
|
||||||
for index, ipmask in ipairs(ipmasks) do
|
for index, ipmask in ipairs(ipmasks) do
|
||||||
if ipmask:find("#") and ipmask:find("#") == 1 then
|
if ipmask:find("#") and ipmask:find("#") == 1 then
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
if not ( datatypes.ipmask4(ipmask) or datatypes.ipmask6(ipmask) ) then
|
if not ( datatypes.ipmask4(ipmask) or datatypes.ipmask6(ipmask) ) then
|
||||||
return nil, ipmask .. " " .. translate("Not valid IP format, please re-enter!")
|
return nil, ipmask .. " " .. translate("Not valid IP format, please re-enter!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
|
|
||||||
---- Proxy Hosts
|
---- Proxy Hosts
|
||||||
@ -82,28 +82,28 @@ o = s:taboption("proxy_list", TextValue, "proxy_host", "", "<font color='red'>"
|
|||||||
o.rows = 15
|
o.rows = 15
|
||||||
o.wrap = "off"
|
o.wrap = "off"
|
||||||
o.cfgvalue = function(self, section)
|
o.cfgvalue = function(self, section)
|
||||||
return fs.readfile(proxy_host) or ""
|
return fs.readfile(proxy_host) or ""
|
||||||
end
|
end
|
||||||
o.write = function(self, section, value)
|
o.write = function(self, section, value)
|
||||||
fs.writefile(proxy_host, value:gsub("\r\n", "\n"))
|
fs.writefile(proxy_host, value:gsub("\r\n", "\n"))
|
||||||
sys.call("rm -rf /tmp/etc/passwall_tmp/dns_*")
|
sys.call("rm -rf /tmp/etc/passwall_tmp/dns_*")
|
||||||
end
|
end
|
||||||
o.remove = function(self, section, value)
|
o.remove = function(self, section, value)
|
||||||
fs.writefile(proxy_host, "")
|
fs.writefile(proxy_host, "")
|
||||||
sys.call("rm -rf /tmp/etc/passwall_tmp/dns_*")
|
sys.call("rm -rf /tmp/etc/passwall_tmp/dns_*")
|
||||||
end
|
end
|
||||||
o.validate = function(self, value)
|
o.validate = function(self, value)
|
||||||
local hosts= {}
|
local hosts= {}
|
||||||
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(hosts, w) end)
|
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(hosts, w) end)
|
||||||
for index, host in ipairs(hosts) do
|
for index, host in ipairs(hosts) do
|
||||||
if host:find("#") and host:find("#") == 1 then
|
if host:find("#") and host:find("#") == 1 then
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
if not datatypes.hostname(host) then
|
if not datatypes.hostname(host) then
|
||||||
return nil, host .. " " .. translate("Not valid domain name, please re-enter!")
|
return nil, host .. " " .. translate("Not valid domain name, please re-enter!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
|
|
||||||
---- Proxy IP
|
---- Proxy IP
|
||||||
@ -112,26 +112,26 @@ o = s:taboption("proxy_list", TextValue, "proxy_ip", "", "<font color='red'>" ..
|
|||||||
o.rows = 15
|
o.rows = 15
|
||||||
o.wrap = "off"
|
o.wrap = "off"
|
||||||
o.cfgvalue = function(self, section)
|
o.cfgvalue = function(self, section)
|
||||||
return fs.readfile(proxy_ip) or ""
|
return fs.readfile(proxy_ip) or ""
|
||||||
end
|
end
|
||||||
o.write = function(self, section, value)
|
o.write = function(self, section, value)
|
||||||
fs.writefile(proxy_ip, value:gsub("\r\n", "\n"))
|
fs.writefile(proxy_ip, value:gsub("\r\n", "\n"))
|
||||||
end
|
end
|
||||||
o.remove = function(self, section, value)
|
o.remove = function(self, section, value)
|
||||||
fs.writefile(proxy_ip, "")
|
fs.writefile(proxy_ip, "")
|
||||||
end
|
end
|
||||||
o.validate = function(self, value)
|
o.validate = function(self, value)
|
||||||
local ipmasks= {}
|
local ipmasks= {}
|
||||||
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, w) end)
|
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, w) end)
|
||||||
for index, ipmask in ipairs(ipmasks) do
|
for index, ipmask in ipairs(ipmasks) do
|
||||||
if ipmask:find("#") and ipmask:find("#") == 1 then
|
if ipmask:find("#") and ipmask:find("#") == 1 then
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
if not ( datatypes.ipmask4(ipmask) or datatypes.ipmask6(ipmask) ) then
|
if not ( datatypes.ipmask4(ipmask) or datatypes.ipmask6(ipmask) ) then
|
||||||
return nil, ipmask .. " " .. translate("Not valid IP format, please re-enter!")
|
return nil, ipmask .. " " .. translate("Not valid IP format, please re-enter!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
|
|
||||||
---- Block Hosts
|
---- Block Hosts
|
||||||
@ -140,26 +140,26 @@ o = s:taboption("block_list", TextValue, "block_host", "", "<font color='red'>"
|
|||||||
o.rows = 15
|
o.rows = 15
|
||||||
o.wrap = "off"
|
o.wrap = "off"
|
||||||
o.cfgvalue = function(self, section)
|
o.cfgvalue = function(self, section)
|
||||||
return fs.readfile(block_host) or ""
|
return fs.readfile(block_host) or ""
|
||||||
end
|
end
|
||||||
o.write = function(self, section, value)
|
o.write = function(self, section, value)
|
||||||
fs.writefile(block_host, value:gsub("\r\n", "\n"))
|
fs.writefile(block_host, value:gsub("\r\n", "\n"))
|
||||||
end
|
end
|
||||||
o.remove = function(self, section, value)
|
o.remove = function(self, section, value)
|
||||||
fs.writefile(block_host, "")
|
fs.writefile(block_host, "")
|
||||||
end
|
end
|
||||||
o.validate = function(self, value)
|
o.validate = function(self, value)
|
||||||
local hosts= {}
|
local hosts= {}
|
||||||
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(hosts, w) end)
|
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(hosts, w) end)
|
||||||
for index, host in ipairs(hosts) do
|
for index, host in ipairs(hosts) do
|
||||||
if host:find("#") and host:find("#") == 1 then
|
if host:find("#") and host:find("#") == 1 then
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
if not datatypes.hostname(host) then
|
if not datatypes.hostname(host) then
|
||||||
return nil, host .. " " .. translate("Not valid domain name, please re-enter!")
|
return nil, host .. " " .. translate("Not valid domain name, please re-enter!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
|
|
||||||
---- Block IP
|
---- Block IP
|
||||||
@ -168,26 +168,26 @@ o = s:taboption("block_list", TextValue, "block_ip", "", "<font color='red'>" ..
|
|||||||
o.rows = 15
|
o.rows = 15
|
||||||
o.wrap = "off"
|
o.wrap = "off"
|
||||||
o.cfgvalue = function(self, section)
|
o.cfgvalue = function(self, section)
|
||||||
return fs.readfile(block_ip) or ""
|
return fs.readfile(block_ip) or ""
|
||||||
end
|
end
|
||||||
o.write = function(self, section, value)
|
o.write = function(self, section, value)
|
||||||
fs.writefile(block_ip, value:gsub("\r\n", "\n"))
|
fs.writefile(block_ip, value:gsub("\r\n", "\n"))
|
||||||
end
|
end
|
||||||
o.remove = function(self, section, value)
|
o.remove = function(self, section, value)
|
||||||
fs.writefile(block_ip, "")
|
fs.writefile(block_ip, "")
|
||||||
end
|
end
|
||||||
o.validate = function(self, value)
|
o.validate = function(self, value)
|
||||||
local ipmasks= {}
|
local ipmasks= {}
|
||||||
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, w) end)
|
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, w) end)
|
||||||
for index, ipmask in ipairs(ipmasks) do
|
for index, ipmask in ipairs(ipmasks) do
|
||||||
if ipmask:find("#") and ipmask:find("#") == 1 then
|
if ipmask:find("#") and ipmask:find("#") == 1 then
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
if not ( datatypes.ipmask4(ipmask) or datatypes.ipmask6(ipmask) ) then
|
if not ( datatypes.ipmask4(ipmask) or datatypes.ipmask6(ipmask) ) then
|
||||||
return nil, ipmask .. " " .. translate("Not valid IP format, please re-enter!")
|
return nil, ipmask .. " " .. translate("Not valid IP format, please re-enter!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
|
|
||||||
---- Lan IPv4
|
---- Lan IPv4
|
||||||
@ -196,26 +196,26 @@ o = s:taboption("lan_ip_list", TextValue, "lanlist_ipv4", "", "<font color='red'
|
|||||||
o.rows = 15
|
o.rows = 15
|
||||||
o.wrap = "off"
|
o.wrap = "off"
|
||||||
o.cfgvalue = function(self, section)
|
o.cfgvalue = function(self, section)
|
||||||
return fs.readfile(lanlist_ipv4) or ""
|
return fs.readfile(lanlist_ipv4) or ""
|
||||||
end
|
end
|
||||||
o.write = function(self, section, value)
|
o.write = function(self, section, value)
|
||||||
fs.writefile(lanlist_ipv4, value:gsub("\r\n", "\n"))
|
fs.writefile(lanlist_ipv4, value:gsub("\r\n", "\n"))
|
||||||
end
|
end
|
||||||
o.remove = function(self, section, value)
|
o.remove = function(self, section, value)
|
||||||
fs.writefile(lanlist_ipv4, "")
|
fs.writefile(lanlist_ipv4, "")
|
||||||
end
|
end
|
||||||
o.validate = function(self, value)
|
o.validate = function(self, value)
|
||||||
local ipmasks= {}
|
local ipmasks= {}
|
||||||
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, w) end)
|
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, w) end)
|
||||||
for index, ipmask in ipairs(ipmasks) do
|
for index, ipmask in ipairs(ipmasks) do
|
||||||
if ipmask:find("#") and ipmask:find("#") == 1 then
|
if ipmask:find("#") and ipmask:find("#") == 1 then
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
if not datatypes.ipmask4(ipmask) then
|
if not datatypes.ipmask4(ipmask) then
|
||||||
return nil, ipmask .. " " .. translate("Not valid IPv4 format, please re-enter!")
|
return nil, ipmask .. " " .. translate("Not valid IPv4 format, please re-enter!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
|
|
||||||
---- Lan IPv6
|
---- Lan IPv6
|
||||||
@ -224,26 +224,26 @@ o = s:taboption("lan_ip_list", TextValue, "lanlist_ipv6", "", "<font color='red'
|
|||||||
o.rows = 15
|
o.rows = 15
|
||||||
o.wrap = "off"
|
o.wrap = "off"
|
||||||
o.cfgvalue = function(self, section)
|
o.cfgvalue = function(self, section)
|
||||||
return fs.readfile(lanlist_ipv6) or ""
|
return fs.readfile(lanlist_ipv6) or ""
|
||||||
end
|
end
|
||||||
o.write = function(self, section, value)
|
o.write = function(self, section, value)
|
||||||
fs.writefile(lanlist_ipv6, value:gsub("\r\n", "\n"))
|
fs.writefile(lanlist_ipv6, value:gsub("\r\n", "\n"))
|
||||||
end
|
end
|
||||||
o.remove = function(self, section, value)
|
o.remove = function(self, section, value)
|
||||||
fs.writefile(lanlist_ipv6, "")
|
fs.writefile(lanlist_ipv6, "")
|
||||||
end
|
end
|
||||||
o.validate = function(self, value)
|
o.validate = function(self, value)
|
||||||
local ipmasks= {}
|
local ipmasks= {}
|
||||||
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, w) end)
|
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, w) end)
|
||||||
for index, ipmask in ipairs(ipmasks) do
|
for index, ipmask in ipairs(ipmasks) do
|
||||||
if ipmask:find("#") and ipmask:find("#") == 1 then
|
if ipmask:find("#") and ipmask:find("#") == 1 then
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
if not datatypes.ipmask6(ipmask) then
|
if not datatypes.ipmask6(ipmask) then
|
||||||
return nil, ipmask .. " " .. translate("Not valid IPv6 format, please re-enter!")
|
return nil, ipmask .. " " .. translate("Not valid IPv6 format, please re-enter!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
|
|
||||||
---- Route Hosts
|
---- Route Hosts
|
||||||
@ -252,13 +252,13 @@ o = s:taboption("route_hosts", TextValue, "hosts", "", "<font color='red'>" .. t
|
|||||||
o.rows = 15
|
o.rows = 15
|
||||||
o.wrap = "off"
|
o.wrap = "off"
|
||||||
o.cfgvalue = function(self, section)
|
o.cfgvalue = function(self, section)
|
||||||
return fs.readfile(hosts) or ""
|
return fs.readfile(hosts) or ""
|
||||||
end
|
end
|
||||||
o.write = function(self, section, value)
|
o.write = function(self, section, value)
|
||||||
fs.writefile(hosts, value:gsub("\r\n", "\n"))
|
fs.writefile(hosts, value:gsub("\r\n", "\n"))
|
||||||
end
|
end
|
||||||
o.remove = function(self, section, value)
|
o.remove = function(self, section, value)
|
||||||
fs.writefile(hosts, "")
|
fs.writefile(hosts, "")
|
||||||
end
|
end
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
@ -22,29 +22,29 @@ domain_list = s:option(TextValue, "domain_list", translate("Domain"))
|
|||||||
domain_list.rows = 10
|
domain_list.rows = 10
|
||||||
domain_list.wrap = "off"
|
domain_list.wrap = "off"
|
||||||
domain_list.validate = function(self, value)
|
domain_list.validate = function(self, value)
|
||||||
local hosts= {}
|
local hosts= {}
|
||||||
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(hosts, w) end)
|
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(hosts, w) end)
|
||||||
for index, host in ipairs(hosts) do
|
for index, host in ipairs(hosts) do
|
||||||
local flag = 1
|
local flag = 1
|
||||||
local tmp_host = host
|
local tmp_host = host
|
||||||
if host:find("regexp:") and host:find("regexp:") == 1 then
|
if host:find("regexp:") and host:find("regexp:") == 1 then
|
||||||
flag = 0
|
flag = 0
|
||||||
elseif host:find("domain:.") and host:find("domain:.") == 1 then
|
elseif host:find("domain:.") and host:find("domain:.") == 1 then
|
||||||
tmp_host = host:gsub("domain:", "")
|
tmp_host = host:gsub("domain:", "")
|
||||||
elseif host:find("full:.") and host:find("full:.") == 1 then
|
elseif host:find("full:.") and host:find("full:.") == 1 then
|
||||||
tmp_host = host:gsub("full:", "")
|
tmp_host = host:gsub("full:", "")
|
||||||
elseif host:find("geosite:") and host:find("geosite:") == 1 then
|
elseif host:find("geosite:") and host:find("geosite:") == 1 then
|
||||||
flag = 0
|
flag = 0
|
||||||
elseif host:find("ext:") and host:find("ext:") == 1 then
|
elseif host:find("ext:") and host:find("ext:") == 1 then
|
||||||
flag = 0
|
flag = 0
|
||||||
end
|
end
|
||||||
if flag == 1 then
|
if flag == 1 then
|
||||||
if not datatypes.hostname(tmp_host) then
|
if not datatypes.hostname(tmp_host) then
|
||||||
return nil, tmp_host .. " " .. translate("Not valid domain name, please re-enter!")
|
return nil, tmp_host .. " " .. translate("Not valid domain name, please re-enter!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
domain_list.description = "<br /><ul><li>" .. translate("Plaintext: If this string matches any part of the targeting domain, this rule takes effet. Example: rule 'sina.com' matches targeting domain 'sina.com', 'sina.com.cn' and 'www.sina.com', but not 'sina.cn'.")
|
domain_list.description = "<br /><ul><li>" .. translate("Plaintext: If this string matches any part of the targeting domain, this rule takes effet. Example: rule 'sina.com' matches targeting domain 'sina.com', 'sina.com.cn' and 'www.sina.com', but not 'sina.cn'.")
|
||||||
.. "</li><li>" .. translate("Regular expression: Begining with 'regexp:', the rest is a regular expression. When the regexp matches targeting domain, this rule takes effect. Example: rule 'regexp:\\.goo.*\\.com$' matches 'www.google.com' and 'fonts.googleapis.com', but not 'google.com'.")
|
.. "</li><li>" .. translate("Regular expression: Begining with 'regexp:', the rest is a regular expression. When the regexp matches targeting domain, this rule takes effect. Example: rule 'regexp:\\.goo.*\\.com$' matches 'www.google.com' and 'fonts.googleapis.com', but not 'google.com'.")
|
||||||
@ -57,18 +57,18 @@ ip_list = s:option(TextValue, "ip_list", "IP")
|
|||||||
ip_list.rows = 10
|
ip_list.rows = 10
|
||||||
ip_list.wrap = "off"
|
ip_list.wrap = "off"
|
||||||
ip_list.validate = function(self, value)
|
ip_list.validate = function(self, value)
|
||||||
local ipmasks= {}
|
local ipmasks= {}
|
||||||
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, w) end)
|
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, w) end)
|
||||||
for index, ipmask in ipairs(ipmasks) do
|
for index, ipmask in ipairs(ipmasks) do
|
||||||
if ipmask:find("geoip:") and ipmask:find("geoip:") == 1 then
|
if ipmask:find("geoip:") and ipmask:find("geoip:") == 1 then
|
||||||
elseif ipmask:find("ext:") and ipmask:find("ext:") == 1 then
|
elseif ipmask:find("ext:") and ipmask:find("ext:") == 1 then
|
||||||
else
|
else
|
||||||
if not (datatypes.ipmask4(ipmask) or datatypes.ipmask6(ipmask)) then
|
if not (datatypes.ipmask4(ipmask) or datatypes.ipmask6(ipmask)) then
|
||||||
return nil, ipmask .. " " .. translate("Not valid IP format, please re-enter!")
|
return nil, ipmask .. " " .. translate("Not valid IP format, please re-enter!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
ip_list.description = "<br /><ul><li>" .. translate("IP: such as '127.0.0.1'.")
|
ip_list.description = "<br /><ul><li>" .. translate("IP: such as '127.0.0.1'.")
|
||||||
.. "</li><li>" .. translate("CIDR: such as '127.0.0.0/8'.")
|
.. "</li><li>" .. translate("CIDR: such as '127.0.0.0/8'.")
|
||||||
|
@ -16,15 +16,15 @@ t.sortable = true
|
|||||||
t.template = "cbi/tblsection"
|
t.template = "cbi/tblsection"
|
||||||
t.extedit = api.url("server_user", "%s")
|
t.extedit = api.url("server_user", "%s")
|
||||||
function t.create(e, t)
|
function t.create(e, t)
|
||||||
local uuid = api.gen_uuid()
|
local uuid = api.gen_uuid()
|
||||||
t = uuid
|
t = uuid
|
||||||
TypedSection.create(e, t)
|
TypedSection.create(e, t)
|
||||||
luci.http.redirect(e.extedit:format(t))
|
luci.http.redirect(e.extedit:format(t))
|
||||||
end
|
end
|
||||||
function t.remove(e, t)
|
function t.remove(e, t)
|
||||||
e.map.proceed = true
|
e.map.proceed = true
|
||||||
e.map:del(t)
|
e.map:del(t)
|
||||||
luci.http.redirect(api.url("server"))
|
luci.http.redirect(api.url("server"))
|
||||||
end
|
end
|
||||||
|
|
||||||
e = t:option(Flag, "enable", translate("Enable"))
|
e = t:option(Flag, "enable", translate("Enable"))
|
||||||
@ -34,7 +34,7 @@ e.rmempty = false
|
|||||||
e = t:option(DummyValue, "status", translate("Status"))
|
e = t:option(DummyValue, "status", translate("Status"))
|
||||||
e.rawhtml = true
|
e.rawhtml = true
|
||||||
e.cfgvalue = function(t, n)
|
e.cfgvalue = function(t, n)
|
||||||
return string.format('<font class="_users_status">%s</font>', translate("Collecting data..."))
|
return string.format('<font class="_users_status">%s</font>', translate("Collecting data..."))
|
||||||
end
|
end
|
||||||
|
|
||||||
e = t:option(DummyValue, "remarks", translate("Remarks"))
|
e = t:option(DummyValue, "remarks", translate("Remarks"))
|
||||||
@ -43,21 +43,21 @@ e.width = "15%"
|
|||||||
---- Type
|
---- Type
|
||||||
e = t:option(DummyValue, "type", translate("Type"))
|
e = t:option(DummyValue, "type", translate("Type"))
|
||||||
e.cfgvalue = function(t, n)
|
e.cfgvalue = function(t, n)
|
||||||
local v = Value.cfgvalue(t, n)
|
local v = Value.cfgvalue(t, n)
|
||||||
if v then
|
if v then
|
||||||
if v == "V2ray" or v == "Xray" then
|
if v == "V2ray" or v == "Xray" then
|
||||||
local protocol = m:get(n, "protocol")
|
local protocol = m:get(n, "protocol")
|
||||||
if protocol == "vmess" then
|
if protocol == "vmess" then
|
||||||
protocol = "VMess"
|
protocol = "VMess"
|
||||||
elseif protocol == "vless" then
|
elseif protocol == "vless" then
|
||||||
protocol = "VLESS"
|
protocol = "VLESS"
|
||||||
else
|
else
|
||||||
protocol = protocol:gsub("^%l",string.upper)
|
protocol = protocol:gsub("^%l",string.upper)
|
||||||
end
|
end
|
||||||
return v .. " -> " .. protocol
|
return v .. " -> " .. protocol
|
||||||
end
|
end
|
||||||
return v
|
return v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
e = t:option(DummyValue, "port", translate("Port"))
|
e = t:option(DummyValue, "port", translate("Port"))
|
||||||
@ -70,4 +70,3 @@ m:append(Template("passwall/server/log"))
|
|||||||
|
|
||||||
m:append(Template("passwall/server/users_list_status"))
|
m:append(Template("passwall/server/users_list_status"))
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
@ -1,49 +1,49 @@
|
|||||||
local api = require "luci.passwall.api"
|
local api = require "luci.passwall.api"
|
||||||
|
|
||||||
local ss_encrypt_method_list = {
|
local ss_encrypt_method_list = {
|
||||||
"rc4-md5", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "aes-128-ctr",
|
"rc4-md5", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "aes-128-ctr",
|
||||||
"aes-192-ctr", "aes-256-ctr", "bf-cfb", "camellia-128-cfb",
|
"aes-192-ctr", "aes-256-ctr", "bf-cfb", "camellia-128-cfb",
|
||||||
"camellia-192-cfb", "camellia-256-cfb", "salsa20", "chacha20",
|
"camellia-192-cfb", "camellia-256-cfb", "salsa20", "chacha20",
|
||||||
"chacha20-ietf", -- aead
|
"chacha20-ietf", -- aead
|
||||||
"aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
|
"aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
|
||||||
"xchacha20-ietf-poly1305"
|
"xchacha20-ietf-poly1305"
|
||||||
}
|
}
|
||||||
|
|
||||||
local ss_rust_encrypt_method_list = {
|
local ss_rust_encrypt_method_list = {
|
||||||
"plain", "none",
|
"plain", "none",
|
||||||
"aes-128-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
|
"aes-128-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
|
||||||
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
||||||
}
|
}
|
||||||
|
|
||||||
local ssr_encrypt_method_list = {
|
local ssr_encrypt_method_list = {
|
||||||
"none", "table", "rc2-cfb", "rc4", "rc4-md5", "rc4-md5-6", "aes-128-cfb",
|
"none", "table", "rc2-cfb", "rc4", "rc4-md5", "rc4-md5-6", "aes-128-cfb",
|
||||||
"aes-192-cfb", "aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr",
|
"aes-192-cfb", "aes-256-cfb", "aes-128-ctr", "aes-192-ctr", "aes-256-ctr",
|
||||||
"bf-cfb", "camellia-128-cfb", "camellia-192-cfb", "camellia-256-cfb",
|
"bf-cfb", "camellia-128-cfb", "camellia-192-cfb", "camellia-256-cfb",
|
||||||
"cast5-cfb", "des-cfb", "idea-cfb", "seed-cfb", "salsa20", "chacha20",
|
"cast5-cfb", "des-cfb", "idea-cfb", "seed-cfb", "salsa20", "chacha20",
|
||||||
"chacha20-ietf"
|
"chacha20-ietf"
|
||||||
}
|
}
|
||||||
|
|
||||||
local ssr_protocol_list = {
|
local ssr_protocol_list = {
|
||||||
"origin", "verify_simple", "verify_deflate", "verify_sha1", "auth_simple",
|
"origin", "verify_simple", "verify_deflate", "verify_sha1", "auth_simple",
|
||||||
"auth_sha1", "auth_sha1_v2", "auth_sha1_v4", "auth_aes128_md5",
|
"auth_sha1", "auth_sha1_v2", "auth_sha1_v4", "auth_aes128_md5",
|
||||||
"auth_aes128_sha1", "auth_chain_a", "auth_chain_b", "auth_chain_c",
|
"auth_aes128_sha1", "auth_chain_a", "auth_chain_b", "auth_chain_c",
|
||||||
"auth_chain_d", "auth_chain_e", "auth_chain_f"
|
"auth_chain_d", "auth_chain_e", "auth_chain_f"
|
||||||
}
|
}
|
||||||
local ssr_obfs_list = {
|
local ssr_obfs_list = {
|
||||||
"plain", "http_simple", "http_post", "random_head", "tls_simple",
|
"plain", "http_simple", "http_post", "random_head", "tls_simple",
|
||||||
"tls1.0_session_auth", "tls1.2_ticket_auth"
|
"tls1.0_session_auth", "tls1.2_ticket_auth"
|
||||||
}
|
}
|
||||||
|
|
||||||
local v_ss_encrypt_method_list = {
|
local v_ss_encrypt_method_list = {
|
||||||
"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305"
|
"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305"
|
||||||
}
|
}
|
||||||
|
|
||||||
local x_ss_encrypt_method_list = {
|
local x_ss_encrypt_method_list = {
|
||||||
"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "xchacha20-poly1305", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "xchacha20-poly1305", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
||||||
}
|
}
|
||||||
|
|
||||||
local header_type_list = {
|
local header_type_list = {
|
||||||
"none", "srtp", "utp", "wechat-video", "dtls", "wireguard"
|
"none", "srtp", "utp", "wechat-video", "dtls", "wireguard"
|
||||||
}
|
}
|
||||||
|
|
||||||
local encrypt_methods_ss_aead = {
|
local encrypt_methods_ss_aead = {
|
||||||
@ -69,39 +69,39 @@ remarks.rmempty = false
|
|||||||
|
|
||||||
type = s:option(ListValue, "type", translate("Type"))
|
type = s:option(ListValue, "type", translate("Type"))
|
||||||
if api.is_finded("microsocks") then
|
if api.is_finded("microsocks") then
|
||||||
type:value("Socks", translate("Socks"))
|
type:value("Socks", translate("Socks"))
|
||||||
end
|
end
|
||||||
if api.is_finded("ss-server") then
|
if api.is_finded("ss-server") then
|
||||||
type:value("SS", translate("Shadowsocks"))
|
type:value("SS", translate("Shadowsocks"))
|
||||||
end
|
end
|
||||||
if api.is_finded("ssserver") then
|
if api.is_finded("ssserver") then
|
||||||
type:value("SS-Rust", translate("Shadowsocks Rust"))
|
type:value("SS-Rust", translate("Shadowsocks Rust"))
|
||||||
end
|
end
|
||||||
if api.is_finded("ssr-server") then
|
if api.is_finded("ssr-server") then
|
||||||
type:value("SSR", translate("ShadowsocksR"))
|
type:value("SSR", translate("ShadowsocksR"))
|
||||||
end
|
end
|
||||||
if api.is_finded("v2ray") then
|
if api.is_finded("v2ray") then
|
||||||
type:value("V2ray", translate("V2ray"))
|
type:value("V2ray", translate("V2ray"))
|
||||||
end
|
end
|
||||||
if api.is_finded("xray") then
|
if api.is_finded("xray") then
|
||||||
type:value("Xray", translate("Xray"))
|
type:value("Xray", translate("Xray"))
|
||||||
end
|
end
|
||||||
if api.is_finded("brook") then
|
if api.is_finded("brook") then
|
||||||
type:value("Brook", translate("Brook"))
|
type:value("Brook", translate("Brook"))
|
||||||
end
|
end
|
||||||
--[[
|
--[[
|
||||||
if api.is_finded("trojan-plus") or api.is_finded("trojan") then
|
if api.is_finded("trojan-plus") or api.is_finded("trojan") then
|
||||||
type:value("Trojan", translate("Trojan"))
|
type:value("Trojan", translate("Trojan"))
|
||||||
end
|
end
|
||||||
]]--
|
]]--
|
||||||
if api.is_finded("trojan-plus") then
|
if api.is_finded("trojan-plus") then
|
||||||
type:value("Trojan-Plus", translate("Trojan-Plus"))
|
type:value("Trojan-Plus", translate("Trojan-Plus"))
|
||||||
end
|
end
|
||||||
if api.is_finded("trojan-go") then
|
if api.is_finded("trojan-go") then
|
||||||
type:value("Trojan-Go", translate("Trojan-Go"))
|
type:value("Trojan-Go", translate("Trojan-Go"))
|
||||||
end
|
end
|
||||||
if api.is_finded("hysteria") then
|
if api.is_finded("hysteria") then
|
||||||
type:value("Hysteria", translate("Hysteria"))
|
type:value("Hysteria", translate("Hysteria"))
|
||||||
end
|
end
|
||||||
|
|
||||||
protocol = s:option(ListValue, "protocol", translate("Protocol"))
|
protocol = s:option(ListValue, "protocol", translate("Protocol"))
|
||||||
@ -137,14 +137,14 @@ port.rmempty = false
|
|||||||
|
|
||||||
auth = s:option(Flag, "auth", translate("Auth"))
|
auth = s:option(Flag, "auth", translate("Auth"))
|
||||||
auth.validate = function(self, value, t)
|
auth.validate = function(self, value, t)
|
||||||
if value and value == "1" then
|
if value and value == "1" then
|
||||||
local user_v = username:formvalue(t) or ""
|
local user_v = username:formvalue(t) or ""
|
||||||
local pass_v = password:formvalue(t) or ""
|
local pass_v = password:formvalue(t) or ""
|
||||||
if user_v == "" or pass_v == "" then
|
if user_v == "" or pass_v == "" then
|
||||||
return nil, translate("Username and Password must be used together!")
|
return nil, translate("Username and Password must be used together!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
auth:depends("type", "Socks")
|
auth:depends("type", "Socks")
|
||||||
auth:depends({ type = "V2ray", protocol = "socks" })
|
auth:depends({ type = "V2ray", protocol = "socks" })
|
||||||
@ -343,7 +343,7 @@ udp_forward:depends({ type = "Xray", protocol = "socks" })
|
|||||||
|
|
||||||
uuid = s:option(DynamicList, "uuid", translate("ID") .. "/" .. translate("Password"))
|
uuid = s:option(DynamicList, "uuid", translate("ID") .. "/" .. translate("Password"))
|
||||||
for i = 1, 3 do
|
for i = 1, 3 do
|
||||||
uuid:value(api.gen_uuid(1))
|
uuid:value(api.gen_uuid(1))
|
||||||
end
|
end
|
||||||
uuid:depends({ type = "V2ray", protocol = "vmess" })
|
uuid:depends({ type = "V2ray", protocol = "vmess" })
|
||||||
uuid:depends({ type = "V2ray", protocol = "vless" })
|
uuid:depends({ type = "V2ray", protocol = "vless" })
|
||||||
@ -358,20 +358,20 @@ uuid:depends("type", "Trojan-Plus")
|
|||||||
tls = s:option(Flag, "tls", translate("TLS"))
|
tls = s:option(Flag, "tls", translate("TLS"))
|
||||||
tls.default = 0
|
tls.default = 0
|
||||||
tls.validate = function(self, value, t)
|
tls.validate = function(self, value, t)
|
||||||
if value then
|
if value then
|
||||||
local type = type:formvalue(t) or ""
|
local type = type:formvalue(t) or ""
|
||||||
if value == "0" and (type == "Trojan" or type == "Trojan-Plus") then
|
if value == "0" and (type == "Trojan" or type == "Trojan-Plus") then
|
||||||
return nil, translate("Original Trojan only supported 'tls', please choose 'tls'.")
|
return nil, translate("Original Trojan only supported 'tls', please choose 'tls'.")
|
||||||
end
|
end
|
||||||
if value == "1" then
|
if value == "1" then
|
||||||
local ca = tls_certificateFile:formvalue(t) or ""
|
local ca = tls_certificateFile:formvalue(t) or ""
|
||||||
local key = tls_keyFile:formvalue(t) or ""
|
local key = tls_keyFile:formvalue(t) or ""
|
||||||
if ca == "" or key == "" then
|
if ca == "" or key == "" then
|
||||||
return nil, translate("Public key and Private key path can not be empty!")
|
return nil, translate("Public key and Private key path can not be empty!")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
tls:depends({ type = "V2ray", protocol = "vmess" })
|
tls:depends({ type = "V2ray", protocol = "vmess" })
|
||||||
tls:depends({ type = "V2ray", protocol = "vless" })
|
tls:depends({ type = "V2ray", protocol = "vless" })
|
||||||
@ -411,14 +411,14 @@ alpn:depends({ type = "Xray", tls = true })
|
|||||||
|
|
||||||
tls_certificateFile = s:option(FileUpload, "tls_certificateFile", translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem")
|
tls_certificateFile = s:option(FileUpload, "tls_certificateFile", translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem")
|
||||||
tls_certificateFile.validate = function(self, value, t)
|
tls_certificateFile.validate = function(self, value, t)
|
||||||
if value and value ~= "" then
|
if value and value ~= "" then
|
||||||
if not nixio.fs.access(value) then
|
if not nixio.fs.access(value) then
|
||||||
return nil, translate("Can't find this file!")
|
return nil, translate("Can't find this file!")
|
||||||
else
|
else
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
tls_certificateFile.default = "/etc/config/ssl/" .. arg[1] .. ".pem"
|
tls_certificateFile.default = "/etc/config/ssl/" .. arg[1] .. ".pem"
|
||||||
tls_certificateFile:depends("tls", true)
|
tls_certificateFile:depends("tls", true)
|
||||||
@ -426,14 +426,14 @@ tls_certificateFile:depends("type", "Hysteria")
|
|||||||
|
|
||||||
tls_keyFile = s:option(FileUpload, "tls_keyFile", translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key")
|
tls_keyFile = s:option(FileUpload, "tls_keyFile", translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key")
|
||||||
tls_keyFile.validate = function(self, value, t)
|
tls_keyFile.validate = function(self, value, t)
|
||||||
if value and value ~= "" then
|
if value and value ~= "" then
|
||||||
if not nixio.fs.access(value) then
|
if not nixio.fs.access(value) then
|
||||||
return nil, translate("Can't find this file!")
|
return nil, translate("Can't find this file!")
|
||||||
else
|
else
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
tls_keyFile.default = "/etc/config/ssl/" .. arg[1] .. ".key"
|
tls_keyFile.default = "/etc/config/ssl/" .. arg[1] .. ".key"
|
||||||
tls_keyFile:depends("tls", true)
|
tls_keyFile:depends("tls", true)
|
||||||
@ -673,12 +673,12 @@ accept_lan:depends("type", "Xray")
|
|||||||
|
|
||||||
local nodes_table = {}
|
local nodes_table = {}
|
||||||
for k, e in ipairs(api.get_valid_nodes()) do
|
for k, e in ipairs(api.get_valid_nodes()) do
|
||||||
if e.node_type == "normal" and (e.type == "V2ray" or e.type == "Xray") then
|
if e.node_type == "normal" and (e.type == "V2ray" or e.type == "Xray") then
|
||||||
nodes_table[#nodes_table + 1] = {
|
nodes_table[#nodes_table + 1] = {
|
||||||
id = e[".name"],
|
id = e[".name"],
|
||||||
remarks = e["remark"]
|
remarks = e["remark"]
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
outbound_node = s:option(ListValue, "outbound_node", translate("outbound node"))
|
outbound_node = s:option(ListValue, "outbound_node", translate("outbound node"))
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1,99 +1,99 @@
|
|||||||
local _M = {}
|
local _M = {}
|
||||||
|
|
||||||
local function gh_release_url(self)
|
local function gh_release_url(self)
|
||||||
return "https://api.github.com/repos/" .. self.repo .. "/releases/latest"
|
return "https://api.github.com/repos/" .. self.repo .. "/releases/latest"
|
||||||
end
|
end
|
||||||
|
|
||||||
local function gh_pre_release_url(self)
|
local function gh_pre_release_url(self)
|
||||||
return "https://api.github.com/repos/" .. self.repo .. "/releases?per_page=1"
|
return "https://api.github.com/repos/" .. self.repo .. "/releases?per_page=1"
|
||||||
end
|
end
|
||||||
|
|
||||||
_M.brook = {
|
_M.brook = {
|
||||||
name = "Brook",
|
name = "Brook",
|
||||||
repo = "txthinking/brook",
|
repo = "txthinking/brook",
|
||||||
get_url = gh_release_url,
|
get_url = gh_release_url,
|
||||||
cmd_version = "-v | awk '{print $3}'",
|
cmd_version = "-v | awk '{print $3}'",
|
||||||
zipped = false,
|
zipped = false,
|
||||||
default_path = "/usr/bin/brook",
|
default_path = "/usr/bin/brook",
|
||||||
match_fmt_str = "linux_%s$",
|
match_fmt_str = "linux_%s$",
|
||||||
file_tree = {}
|
file_tree = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
_M.hysteria = {
|
_M.hysteria = {
|
||||||
name = "Hysteria",
|
name = "Hysteria",
|
||||||
repo = "HyNetwork/hysteria",
|
repo = "HyNetwork/hysteria",
|
||||||
get_url = gh_release_url,
|
get_url = gh_release_url,
|
||||||
cmd_version = "-v | awk '{print $3}'",
|
cmd_version = "-v | awk '{print $3}'",
|
||||||
zipped = false,
|
zipped = false,
|
||||||
default_path = "/usr/bin/hysteria",
|
default_path = "/usr/bin/hysteria",
|
||||||
match_fmt_str = "linux%%-%s$",
|
match_fmt_str = "linux%%-%s$",
|
||||||
file_tree = {
|
file_tree = {
|
||||||
armv6 = "arm",
|
armv6 = "arm",
|
||||||
armv7 = "arm"
|
armv7 = "arm"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_M["trojan-go"] = {
|
_M["trojan-go"] = {
|
||||||
name = "Trojan-Go",
|
name = "Trojan-Go",
|
||||||
repo = "p4gefau1t/trojan-go",
|
repo = "p4gefau1t/trojan-go",
|
||||||
get_url = gh_release_url,
|
get_url = gh_release_url,
|
||||||
cmd_version = "-version | awk '{print $2}' | sed -n 1P",
|
cmd_version = "-version | awk '{print $2}' | sed -n 1P",
|
||||||
zipped = true,
|
zipped = true,
|
||||||
default_path = "/usr/bin/trojan-go",
|
default_path = "/usr/bin/trojan-go",
|
||||||
match_fmt_str = "linux%%-%s%%.zip",
|
match_fmt_str = "linux%%-%s%%.zip",
|
||||||
file_tree = {
|
file_tree = {
|
||||||
aarch64 = "armv8",
|
aarch64 = "armv8",
|
||||||
armv8 = "armv8",
|
armv8 = "armv8",
|
||||||
mips = "mips%-hardfloat",
|
mips = "mips%-hardfloat",
|
||||||
mipsel = "mipsle%-hardfloat"
|
mipsel = "mipsle%-hardfloat"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_M.v2ray = {
|
_M.v2ray = {
|
||||||
name = "V2ray",
|
name = "V2ray",
|
||||||
repo = "v2fly/v2ray-core",
|
repo = "v2fly/v2ray-core",
|
||||||
get_url = gh_pre_release_url,
|
get_url = gh_pre_release_url,
|
||||||
cmd_version = "version | awk '{print $2}' | sed -n 1P",
|
cmd_version = "version | awk '{print $2}' | sed -n 1P",
|
||||||
zipped = true,
|
zipped = true,
|
||||||
default_path = "/usr/bin/v2ray",
|
default_path = "/usr/bin/v2ray",
|
||||||
match_fmt_str = "linux%%-%s",
|
match_fmt_str = "linux%%-%s",
|
||||||
file_tree = {
|
file_tree = {
|
||||||
x86_64 = "64",
|
x86_64 = "64",
|
||||||
x86 = "32",
|
x86 = "32",
|
||||||
mips = "mips32",
|
mips = "mips32",
|
||||||
mipsel = "mips32le"
|
mipsel = "mips32le"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_M.xray = {
|
_M.xray = {
|
||||||
name = "Xray",
|
name = "Xray",
|
||||||
repo = "XTLS/Xray-core",
|
repo = "XTLS/Xray-core",
|
||||||
get_url = gh_pre_release_url,
|
get_url = gh_pre_release_url,
|
||||||
cmd_version = _M.v2ray.cmd_version,
|
cmd_version = _M.v2ray.cmd_version,
|
||||||
zipped = true,
|
zipped = true,
|
||||||
default_path = "/usr/bin/xray",
|
default_path = "/usr/bin/xray",
|
||||||
match_fmt_str = _M.v2ray.match_fmt_str,
|
match_fmt_str = _M.v2ray.match_fmt_str,
|
||||||
file_tree = _M.v2ray.file_tree
|
file_tree = _M.v2ray.file_tree
|
||||||
}
|
}
|
||||||
|
|
||||||
_M["chinadns-ng"] = {
|
_M["chinadns-ng"] = {
|
||||||
name = "ChinaDNS-NG",
|
name = "ChinaDNS-NG",
|
||||||
repo = "zfl9/chinadns-ng",
|
repo = "zfl9/chinadns-ng",
|
||||||
get_url = gh_pre_release_url,
|
get_url = gh_pre_release_url,
|
||||||
cmd_version = "-V | awk '{print $2}'",
|
cmd_version = "-V | awk '{print $2}'",
|
||||||
zipped = false,
|
zipped = false,
|
||||||
default_path = "/usr/bin/chinadns-ng",
|
default_path = "/usr/bin/chinadns-ng",
|
||||||
match_fmt_str = "%s$",
|
match_fmt_str = "%s$",
|
||||||
file_tree = {
|
file_tree = {
|
||||||
x86_64 = "x86_64",
|
x86_64 = "x86_64",
|
||||||
x86 = "i686",
|
x86 = "i686",
|
||||||
mipsel = "mipsel",
|
mipsel = "mipsel",
|
||||||
aarch64 = "aarch64",
|
aarch64 = "aarch64",
|
||||||
armv5 = "arm%-eabi",
|
armv5 = "arm%-eabi",
|
||||||
armv6 = "armv6%-eabihf",
|
armv6 = "armv6%-eabihf",
|
||||||
armv7 = "armv7l%-eabihf",
|
armv7 = "armv7l%-eabihf",
|
||||||
armv8 = "aarch64"
|
armv8 = "aarch64"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _M
|
return _M
|
||||||
|
@ -18,215 +18,215 @@ local ip6t_bin = sys.exec("echo -n $(/usr/share/passwall/iptables.sh get_ip6t_bi
|
|||||||
local nft_flag = api.is_finded("fw4") and "1" or "0"
|
local nft_flag = api.is_finded("fw4") and "1" or "0"
|
||||||
|
|
||||||
local function log(...)
|
local function log(...)
|
||||||
local f, err = io.open(LOG_APP_FILE, "a")
|
local f, err = io.open(LOG_APP_FILE, "a")
|
||||||
if f and err == nil then
|
if f and err == nil then
|
||||||
local str = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
|
local str = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
|
||||||
f:write(str .. "\n")
|
f:write(str .. "\n")
|
||||||
f:close()
|
f:close()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function cmd(cmd)
|
local function cmd(cmd)
|
||||||
sys.call(cmd)
|
sys.call(cmd)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function ipt(arg)
|
local function ipt(arg)
|
||||||
cmd(ipt_bin .. " -w " .. arg)
|
cmd(ipt_bin .. " -w " .. arg)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function ip6t(arg)
|
local function ip6t(arg)
|
||||||
cmd(ip6t_bin .. " -w " .. arg)
|
cmd(ip6t_bin .. " -w " .. arg)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function ln_run(s, d, command, output)
|
local function ln_run(s, d, command, output)
|
||||||
if not output then
|
if not output then
|
||||||
output = "/dev/null"
|
output = "/dev/null"
|
||||||
end
|
end
|
||||||
d = TMP_BIN_PATH .. "/" .. d
|
d = TMP_BIN_PATH .. "/" .. d
|
||||||
cmd(string.format('[ ! -f "%s" ] && ln -s %s %s 2>/dev/null', d, s, d))
|
cmd(string.format('[ ! -f "%s" ] && ln -s %s %s 2>/dev/null', d, s, d))
|
||||||
return string.format("%s >%s 2>&1 &", d .. " " ..command, output)
|
return string.format("%s >%s 2>&1 &", d .. " " ..command, output)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function gen_include()
|
local function gen_include()
|
||||||
cmd(string.format("echo '#!/bin/sh' > /tmp/etc/%s.include", CONFIG))
|
cmd(string.format("echo '#!/bin/sh' > /tmp/etc/%s.include", CONFIG))
|
||||||
if nft_flag == "1" then
|
if nft_flag == "1" then
|
||||||
cmd("echo \"\" > " .. CONFIG_PATH .. "/" .. CONFIG .. ".nft")
|
cmd("echo \"\" > " .. CONFIG_PATH .. "/" .. CONFIG .. ".nft")
|
||||||
local nft_cmd="for chain in $(nft -a list chains |grep -E \"chain PSW-SERVER\" |awk -F ' ' '{print$2}'); do\n nft list chain inet fw4 ${chain} >> " .. CONFIG_PATH .. "/" .. CONFIG .. ".nft\n done"
|
local nft_cmd="for chain in $(nft -a list chains |grep -E \"chain PSW-SERVER\" |awk -F ' ' '{print$2}'); do\n nft list chain inet fw4 ${chain} >> " .. CONFIG_PATH .. "/" .. CONFIG .. ".nft\n done"
|
||||||
cmd(nft_cmd)
|
cmd(nft_cmd)
|
||||||
end
|
end
|
||||||
local function extract_rules(n, a)
|
local function extract_rules(n, a)
|
||||||
local _ipt = ipt_bin
|
local _ipt = ipt_bin
|
||||||
if n == "6" then
|
if n == "6" then
|
||||||
_ipt = ip6t_bin
|
_ipt = ip6t_bin
|
||||||
end
|
end
|
||||||
local result = "*" .. a
|
local result = "*" .. a
|
||||||
result = result .. "\n" .. sys.exec(_ipt .. '-save -t ' .. a .. ' | grep "PSW-SERVER" | sed -e "s/^-A \\(INPUT\\)/-I \\1 1/"')
|
result = result .. "\n" .. sys.exec(_ipt .. '-save -t ' .. a .. ' | grep "PSW-SERVER" | sed -e "s/^-A \\(INPUT\\)/-I \\1 1/"')
|
||||||
result = result .. "COMMIT"
|
result = result .. "COMMIT"
|
||||||
return result
|
return result
|
||||||
end
|
end
|
||||||
local f, err = io.open("/tmp/etc/" .. CONFIG .. ".include", "a")
|
local f, err = io.open("/tmp/etc/" .. CONFIG .. ".include", "a")
|
||||||
if f and err == nil then
|
if f and err == nil then
|
||||||
if nft_flag == "0" then
|
if nft_flag == "0" then
|
||||||
f:write(ipt_bin .. '-save -c | grep -v "PSW-SERVER" | ' .. ipt_bin .. '-restore -c' .. "\n")
|
f:write(ipt_bin .. '-save -c | grep -v "PSW-SERVER" | ' .. ipt_bin .. '-restore -c' .. "\n")
|
||||||
f:write(ipt_bin .. '-restore -n <<-EOT' .. "\n")
|
f:write(ipt_bin .. '-restore -n <<-EOT' .. "\n")
|
||||||
f:write(extract_rules("4", "filter") .. "\n")
|
f:write(extract_rules("4", "filter") .. "\n")
|
||||||
f:write("EOT" .. "\n")
|
f:write("EOT" .. "\n")
|
||||||
f:write(ip6t_bin .. '-save -c | grep -v "PSW-SERVER" | ' .. ip6t_bin .. '-restore -c' .. "\n")
|
f:write(ip6t_bin .. '-save -c | grep -v "PSW-SERVER" | ' .. ip6t_bin .. '-restore -c' .. "\n")
|
||||||
f:write(ip6t_bin .. '-restore -n <<-EOT' .. "\n")
|
f:write(ip6t_bin .. '-restore -n <<-EOT' .. "\n")
|
||||||
f:write(extract_rules("6", "filter") .. "\n")
|
f:write(extract_rules("6", "filter") .. "\n")
|
||||||
f:write("EOT" .. "\n")
|
f:write("EOT" .. "\n")
|
||||||
f:close()
|
f:close()
|
||||||
else
|
else
|
||||||
f:write("nft -f " .. CONFIG_PATH .. "/" .. CONFIG .. ".nft\n")
|
f:write("nft -f " .. CONFIG_PATH .. "/" .. CONFIG .. ".nft\n")
|
||||||
f:write("nft insert rule inet fw4 input position 0 counter jump PSW-SERVER")
|
f:write("nft insert rule inet fw4 input position 0 counter jump PSW-SERVER")
|
||||||
f:close()
|
f:close()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function start()
|
local function start()
|
||||||
local enabled = tonumber(uci:get(CONFIG, "@global[0]", "enable") or 0)
|
local enabled = tonumber(uci:get(CONFIG, "@global[0]", "enable") or 0)
|
||||||
if enabled == nil or enabled == 0 then
|
if enabled == nil or enabled == 0 then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
cmd(string.format("mkdir -p %s %s", CONFIG_PATH, TMP_BIN_PATH))
|
cmd(string.format("mkdir -p %s %s", CONFIG_PATH, TMP_BIN_PATH))
|
||||||
cmd(string.format("touch %s", LOG_APP_FILE))
|
cmd(string.format("touch %s", LOG_APP_FILE))
|
||||||
if nft_flag == "0" then
|
if nft_flag == "0" then
|
||||||
ipt("-N PSW-SERVER")
|
ipt("-N PSW-SERVER")
|
||||||
ipt("-I INPUT -j PSW-SERVER")
|
ipt("-I INPUT -j PSW-SERVER")
|
||||||
ip6t("-N PSW-SERVER")
|
ip6t("-N PSW-SERVER")
|
||||||
ip6t("-I INPUT -j PSW-SERVER")
|
ip6t("-I INPUT -j PSW-SERVER")
|
||||||
else
|
else
|
||||||
cmd("nft add chain inet fw4 PSW-SERVER\n")
|
cmd("nft add chain inet fw4 PSW-SERVER\n")
|
||||||
cmd("nft insert rule inet fw4 input position 0 counter jump PSW-SERVER")
|
cmd("nft insert rule inet fw4 input position 0 counter jump PSW-SERVER")
|
||||||
end
|
end
|
||||||
uci:foreach(CONFIG, "user", function(user)
|
uci:foreach(CONFIG, "user", function(user)
|
||||||
local id = user[".name"]
|
local id = user[".name"]
|
||||||
local enable = user.enable
|
local enable = user.enable
|
||||||
if enable and tonumber(enable) == 1 then
|
if enable and tonumber(enable) == 1 then
|
||||||
local enable_log = user.log
|
local enable_log = user.log
|
||||||
local log_path = nil
|
local log_path = nil
|
||||||
if enable_log and enable_log == "1" then
|
if enable_log and enable_log == "1" then
|
||||||
log_path = CONFIG_PATH .. "/" .. id .. ".log"
|
log_path = CONFIG_PATH .. "/" .. id .. ".log"
|
||||||
else
|
else
|
||||||
log_path = nil
|
log_path = nil
|
||||||
end
|
end
|
||||||
local remarks = user.remarks
|
local remarks = user.remarks
|
||||||
local port = tonumber(user.port)
|
local port = tonumber(user.port)
|
||||||
local bin
|
local bin
|
||||||
local config = {}
|
local config = {}
|
||||||
local config_file = CONFIG_PATH .. "/" .. id .. ".json"
|
local config_file = CONFIG_PATH .. "/" .. id .. ".json"
|
||||||
local udp_forward = 1
|
local udp_forward = 1
|
||||||
local type = user.type or ""
|
local type = user.type or ""
|
||||||
if type == "Socks" then
|
if type == "Socks" then
|
||||||
local auth = ""
|
local auth = ""
|
||||||
if user.auth and user.auth == "1" then
|
if user.auth and user.auth == "1" then
|
||||||
local username = user.username or ""
|
local username = user.username or ""
|
||||||
local password = user.password or ""
|
local password = user.password or ""
|
||||||
if username ~= "" and password ~= "" then
|
if username ~= "" and password ~= "" then
|
||||||
username = "-u " .. username
|
username = "-u " .. username
|
||||||
password = "-P " .. password
|
password = "-P " .. password
|
||||||
auth = username .. " " .. password
|
auth = username .. " " .. password
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
bin = ln_run("/usr/bin/microsocks", "microsocks_" .. id, string.format("-i :: -p %s %s", port, auth), log_path)
|
bin = ln_run("/usr/bin/microsocks", "microsocks_" .. id, string.format("-i :: -p %s %s", port, auth), log_path)
|
||||||
elseif type == "SS" or type == "SSR" then
|
elseif type == "SS" or type == "SSR" then
|
||||||
config = require(require_dir .. "util_shadowsocks").gen_config_server(user)
|
config = require(require_dir .. "util_shadowsocks").gen_config_server(user)
|
||||||
local udp_param = ""
|
local udp_param = ""
|
||||||
udp_forward = tonumber(user.udp_forward) or 1
|
udp_forward = tonumber(user.udp_forward) or 1
|
||||||
if udp_forward == 1 then
|
if udp_forward == 1 then
|
||||||
udp_param = "-u"
|
udp_param = "-u"
|
||||||
end
|
end
|
||||||
type = type:lower()
|
type = type:lower()
|
||||||
bin = ln_run("/usr/bin/" .. type .. "-server", type .. "-server", "-c " .. config_file .. " " .. udp_param, log_path)
|
bin = ln_run("/usr/bin/" .. type .. "-server", type .. "-server", "-c " .. config_file .. " " .. udp_param, log_path)
|
||||||
elseif type == "SS-Rust" then
|
elseif type == "SS-Rust" then
|
||||||
config = require(require_dir .. "util_shadowsocks").gen_config_server(user)
|
config = require(require_dir .. "util_shadowsocks").gen_config_server(user)
|
||||||
bin = ln_run("/usr/bin/ssserver", "ssserver", "-c " .. config_file, log_path)
|
bin = ln_run("/usr/bin/ssserver", "ssserver", "-c " .. config_file, log_path)
|
||||||
elseif type == "V2ray" then
|
elseif type == "V2ray" then
|
||||||
config = require(require_dir .. "util_xray").gen_config_server(user)
|
config = require(require_dir .. "util_xray").gen_config_server(user)
|
||||||
bin = ln_run(api.get_app_path("v2ray"), "v2ray", "run -c " .. config_file, log_path)
|
bin = ln_run(api.get_app_path("v2ray"), "v2ray", "run -c " .. config_file, log_path)
|
||||||
elseif type == "Xray" then
|
elseif type == "Xray" then
|
||||||
config = require(require_dir .. "util_xray").gen_config_server(user)
|
config = require(require_dir .. "util_xray").gen_config_server(user)
|
||||||
bin = ln_run(api.get_app_path("xray"), "xray", "run -c " .. config_file, log_path)
|
bin = ln_run(api.get_app_path("xray"), "xray", "run -c " .. config_file, log_path)
|
||||||
elseif type == "Trojan" then
|
elseif type == "Trojan" then
|
||||||
config = require(require_dir .. "util_trojan").gen_config_server(user)
|
config = require(require_dir .. "util_trojan").gen_config_server(user)
|
||||||
bin = ln_run("/usr/sbin/trojan", "trojan", "-c " .. config_file, log_path)
|
bin = ln_run("/usr/sbin/trojan", "trojan", "-c " .. config_file, log_path)
|
||||||
elseif type == "Trojan-Plus" then
|
elseif type == "Trojan-Plus" then
|
||||||
config = require(require_dir .. "util_trojan").gen_config_server(user)
|
config = require(require_dir .. "util_trojan").gen_config_server(user)
|
||||||
bin = ln_run("/usr/sbin/trojan-plus", "trojan-plus", "-c " .. config_file, log_path)
|
bin = ln_run("/usr/sbin/trojan-plus", "trojan-plus", "-c " .. config_file, log_path)
|
||||||
elseif type == "Trojan-Go" then
|
elseif type == "Trojan-Go" then
|
||||||
config = require(require_dir .. "util_trojan").gen_config_server(user)
|
config = require(require_dir .. "util_trojan").gen_config_server(user)
|
||||||
bin = ln_run(api.get_app_path("trojan-go"), "trojan-go", "-config " .. config_file, log_path)
|
bin = ln_run(api.get_app_path("trojan-go"), "trojan-go", "-config " .. config_file, log_path)
|
||||||
elseif type == "Brook" then
|
elseif type == "Brook" then
|
||||||
local brook_protocol = user.protocol
|
local brook_protocol = user.protocol
|
||||||
local brook_password = user.password
|
local brook_password = user.password
|
||||||
local brook_path = user.ws_path or "/ws"
|
local brook_path = user.ws_path or "/ws"
|
||||||
local brook_path_arg = ""
|
local brook_path_arg = ""
|
||||||
if brook_protocol == "wsserver" and brook_path then
|
if brook_protocol == "wsserver" and brook_path then
|
||||||
brook_path_arg = " --path " .. brook_path
|
brook_path_arg = " --path " .. brook_path
|
||||||
end
|
end
|
||||||
bin = ln_run(api.get_app_path("brook"), "brook_" .. id, string.format("--debug %s -l :%s -p %s%s", brook_protocol, port, brook_password, brook_path_arg), log_path)
|
bin = ln_run(api.get_app_path("brook"), "brook_" .. id, string.format("--debug %s -l :%s -p %s%s", brook_protocol, port, brook_password, brook_path_arg), log_path)
|
||||||
elseif type == "Hysteria" then
|
elseif type == "Hysteria" then
|
||||||
config = require(require_dir .. "util_hysteria").gen_config_server(user)
|
config = require(require_dir .. "util_hysteria").gen_config_server(user)
|
||||||
bin = ln_run(api.get_app_path("hysteria"), "hysteria", "-c " .. config_file .. " server", log_path)
|
bin = ln_run(api.get_app_path("hysteria"), "hysteria", "-c " .. config_file .. " server", log_path)
|
||||||
end
|
end
|
||||||
|
|
||||||
if next(config) then
|
if next(config) then
|
||||||
local f, err = io.open(config_file, "w")
|
local f, err = io.open(config_file, "w")
|
||||||
if f and err == nil then
|
if f and err == nil then
|
||||||
f:write(jsonc.stringify(config, 1))
|
f:write(jsonc.stringify(config, 1))
|
||||||
f:close()
|
f:close()
|
||||||
end
|
end
|
||||||
log(string.format("%s %s 生成配置文件并运行 - %s", remarks, port, config_file))
|
log(string.format("%s %s 生成配置文件并运行 - %s", remarks, port, config_file))
|
||||||
end
|
end
|
||||||
|
|
||||||
if bin then
|
if bin then
|
||||||
cmd(bin)
|
cmd(bin)
|
||||||
end
|
end
|
||||||
|
|
||||||
local bind_local = user.bind_local or 0
|
local bind_local = user.bind_local or 0
|
||||||
if bind_local and tonumber(bind_local) ~= 1 then
|
if bind_local and tonumber(bind_local) ~= 1 then
|
||||||
if nft_flag == "0" then
|
if nft_flag == "0" then
|
||||||
ipt(string.format('-A PSW-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
|
ipt(string.format('-A PSW-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
|
||||||
ip6t(string.format('-A PSW-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
|
ip6t(string.format('-A PSW-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
|
||||||
if udp_forward == 1 then
|
if udp_forward == 1 then
|
||||||
ipt(string.format('-A PSW-SERVER -p udp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
|
ipt(string.format('-A PSW-SERVER -p udp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
|
||||||
ip6t(string.format('-A PSW-SERVER -p udp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
|
ip6t(string.format('-A PSW-SERVER -p udp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
cmd(string.format('nft add rule inet fw4 PSW-SERVER meta l4proto tcp tcp dport {%s} accept', port))
|
cmd(string.format('nft add rule inet fw4 PSW-SERVER meta l4proto tcp tcp dport {%s} accept', port))
|
||||||
if udp_forward == 1 then
|
if udp_forward == 1 then
|
||||||
cmd(string.format('nft add rule inet fw4 PSW-SERVER meta l4proto udp udp dport {%s} accept', port))
|
cmd(string.format('nft add rule inet fw4 PSW-SERVER meta l4proto udp udp dport {%s} accept', port))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
gen_include()
|
gen_include()
|
||||||
end
|
end
|
||||||
|
|
||||||
local function stop()
|
local function stop()
|
||||||
cmd(string.format("/bin/busybox top -bn1 | grep -v 'grep' | grep '%s/' | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1", CONFIG_PATH))
|
cmd(string.format("/bin/busybox top -bn1 | grep -v 'grep' | grep '%s/' | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1", CONFIG_PATH))
|
||||||
if nft_flag == "0" then
|
if nft_flag == "0" then
|
||||||
ipt("-D INPUT -j PSW-SERVER 2>/dev/null")
|
ipt("-D INPUT -j PSW-SERVER 2>/dev/null")
|
||||||
ipt("-F PSW-SERVER 2>/dev/null")
|
ipt("-F PSW-SERVER 2>/dev/null")
|
||||||
ipt("-X PSW-SERVER 2>/dev/null")
|
ipt("-X PSW-SERVER 2>/dev/null")
|
||||||
ip6t("-D INPUT -j PSW-SERVER 2>/dev/null")
|
ip6t("-D INPUT -j PSW-SERVER 2>/dev/null")
|
||||||
ip6t("-F PSW-SERVER 2>/dev/null")
|
ip6t("-F PSW-SERVER 2>/dev/null")
|
||||||
ip6t("-X PSW-SERVER 2>/dev/null")
|
ip6t("-X PSW-SERVER 2>/dev/null")
|
||||||
else
|
else
|
||||||
nft_cmd="handles=$(nft -a list chain inet fw4 input | grep -E \"PSW-SERVER\" | awk -F '# handle ' '{print$2}')\n for handle in $handles; do\n nft delete rule inet fw4 input handle ${handle} 2>/dev/null\n done"
|
nft_cmd="handles=$(nft -a list chain inet fw4 input | grep -E \"PSW-SERVER\" | awk -F '# handle ' '{print$2}')\n for handle in $handles; do\n nft delete rule inet fw4 input handle ${handle} 2>/dev/null\n done"
|
||||||
cmd(nft_cmd)
|
cmd(nft_cmd)
|
||||||
cmd("nft flush chain inet fw4 PSW-SERVER 2>/dev/null")
|
cmd("nft flush chain inet fw4 PSW-SERVER 2>/dev/null")
|
||||||
cmd("nft delete chain inet fw4 PSW-SERVER 2>/dev/null")
|
cmd("nft delete chain inet fw4 PSW-SERVER 2>/dev/null")
|
||||||
end
|
end
|
||||||
cmd(string.format("rm -rf %s %s /tmp/etc/%s.include", CONFIG_PATH, LOG_APP_FILE, CONFIG))
|
cmd(string.format("rm -rf %s %s /tmp/etc/%s.include", CONFIG_PATH, LOG_APP_FILE, CONFIG))
|
||||||
end
|
end
|
||||||
|
|
||||||
if action then
|
if action then
|
||||||
if action == "start" then
|
if action == "start" then
|
||||||
start()
|
start()
|
||||||
elseif action == "stop" then
|
elseif action == "stop" then
|
||||||
stop()
|
stop()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -4,116 +4,115 @@ local uci = api.uci
|
|||||||
local jsonc = api.jsonc
|
local jsonc = api.jsonc
|
||||||
|
|
||||||
function gen_config_server(node)
|
function gen_config_server(node)
|
||||||
local config = {
|
local config = {
|
||||||
listen = ":" .. node.port,
|
listen = ":" .. node.port,
|
||||||
protocol = node.protocol or "udp",
|
protocol = node.protocol or "udp",
|
||||||
obfs = node.hysteria_obfs,
|
obfs = node.hysteria_obfs,
|
||||||
cert = node.tls_certificateFile,
|
cert = node.tls_certificateFile,
|
||||||
key = node.tls_keyFile,
|
key = node.tls_keyFile,
|
||||||
auth = (node.hysteria_auth_type == "string") and {
|
auth = (node.hysteria_auth_type == "string") and {
|
||||||
mode = "password",
|
mode = "password",
|
||||||
config = {
|
config = {
|
||||||
password = node.hysteria_auth_password
|
password = node.hysteria_auth_password
|
||||||
}
|
}
|
||||||
} or nil,
|
} or nil,
|
||||||
disable_udp = (node.hysteria_udp == "0") and true or false,
|
disable_udp = (node.hysteria_udp == "0") and true or false,
|
||||||
alpn = node.hysteria_alpn or nil,
|
alpn = node.hysteria_alpn or nil,
|
||||||
up_mbps = tonumber(node.hysteria_up_mbps) or 10,
|
up_mbps = tonumber(node.hysteria_up_mbps) or 10,
|
||||||
down_mbps = tonumber(node.hysteria_down_mbps) or 50,
|
down_mbps = tonumber(node.hysteria_down_mbps) or 50,
|
||||||
recv_window_conn = (node.hysteria_recv_window_conn) and tonumber(node.hysteria_recv_window_conn) or nil,
|
recv_window_conn = (node.hysteria_recv_window_conn) and tonumber(node.hysteria_recv_window_conn) or nil,
|
||||||
recv_window = (node.hysteria_recv_window) and tonumber(node.hysteria_recv_window) or nil,
|
recv_window = (node.hysteria_recv_window) and tonumber(node.hysteria_recv_window) or nil,
|
||||||
disable_mtu_discovery = (node.hysteria_disable_mtu_discovery) and true or false
|
disable_mtu_discovery = (node.hysteria_disable_mtu_discovery) and true or false
|
||||||
}
|
}
|
||||||
return config
|
return config
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function gen_config(var)
|
function gen_config(var)
|
||||||
local node_id = var["-node"]
|
local node_id = var["-node"]
|
||||||
if not node_id then
|
if not node_id then
|
||||||
print("-node 不能为空")
|
print("-node 不能为空")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local node = uci:get_all("passwall", node_id)
|
local node = uci:get_all("passwall", node_id)
|
||||||
local local_tcp_redir_port = var["-local_tcp_redir_port"]
|
local local_tcp_redir_port = var["-local_tcp_redir_port"]
|
||||||
local local_udp_redir_port = var["-local_udp_redir_port"]
|
local local_udp_redir_port = var["-local_udp_redir_port"]
|
||||||
local local_socks_address = var["-local_socks_address"] or "0.0.0.0"
|
local local_socks_address = var["-local_socks_address"] or "0.0.0.0"
|
||||||
local local_socks_port = var["-local_socks_port"]
|
local local_socks_port = var["-local_socks_port"]
|
||||||
local local_socks_username = var["-local_socks_username"]
|
local local_socks_username = var["-local_socks_username"]
|
||||||
local local_socks_password = var["-local_socks_password"]
|
local local_socks_password = var["-local_socks_password"]
|
||||||
local local_http_address = var["-local_http_address"] or "0.0.0.0"
|
local local_http_address = var["-local_http_address"] or "0.0.0.0"
|
||||||
local local_http_port = var["-local_http_port"]
|
local local_http_port = var["-local_http_port"]
|
||||||
local local_http_username = var["-local_http_username"]
|
local local_http_username = var["-local_http_username"]
|
||||||
local local_http_password = var["-local_http_password"]
|
local local_http_password = var["-local_http_password"]
|
||||||
local tcp_proxy_way = var["-tcp_proxy_way"]
|
local tcp_proxy_way = var["-tcp_proxy_way"]
|
||||||
local server_host = var["-server_host"] or node.address
|
local server_host = var["-server_host"] or node.address
|
||||||
local server_port = var["-server_port"] or node.port
|
local server_port = var["-server_port"] or node.port
|
||||||
|
|
||||||
if api.is_ipv6(server_host) then
|
if api.is_ipv6(server_host) then
|
||||||
server_host = api.get_ipv6_full(server_host)
|
server_host = api.get_ipv6_full(server_host)
|
||||||
end
|
end
|
||||||
local server = server_host .. ":" .. server_port
|
local server = server_host .. ":" .. server_port
|
||||||
|
|
||||||
if (node.hysteria_hop) then
|
if (node.hysteria_hop) then
|
||||||
server = server .. "," .. node.hysteria_hop
|
server = server .. "," .. node.hysteria_hop
|
||||||
end
|
end
|
||||||
|
|
||||||
local config = {
|
local config = {
|
||||||
server = server,
|
server = server,
|
||||||
protocol = node.protocol or "udp",
|
protocol = node.protocol or "udp",
|
||||||
obfs = node.hysteria_obfs,
|
obfs = node.hysteria_obfs,
|
||||||
auth = (node.hysteria_auth_type == "base64") and node.hysteria_auth_password or nil,
|
auth = (node.hysteria_auth_type == "base64") and node.hysteria_auth_password or nil,
|
||||||
auth_str = (node.hysteria_auth_type == "string") and node.hysteria_auth_password or nil,
|
auth_str = (node.hysteria_auth_type == "string") and node.hysteria_auth_password or nil,
|
||||||
alpn = node.hysteria_alpn or nil,
|
alpn = node.hysteria_alpn or nil,
|
||||||
server_name = node.tls_serverName,
|
server_name = node.tls_serverName,
|
||||||
insecure = (node.tls_allowInsecure == "1") and true or false,
|
insecure = (node.tls_allowInsecure == "1") and true or false,
|
||||||
up_mbps = tonumber(node.hysteria_up_mbps) or 10,
|
up_mbps = tonumber(node.hysteria_up_mbps) or 10,
|
||||||
down_mbps = tonumber(node.hysteria_down_mbps) or 50,
|
down_mbps = tonumber(node.hysteria_down_mbps) or 50,
|
||||||
retry = -1,
|
retry = -1,
|
||||||
retry_interval = 5,
|
retry_interval = 5,
|
||||||
recv_window_conn = (node.hysteria_recv_window_conn) and tonumber(node.hysteria_recv_window_conn) or nil,
|
recv_window_conn = (node.hysteria_recv_window_conn) and tonumber(node.hysteria_recv_window_conn) or nil,
|
||||||
recv_window = (node.hysteria_recv_window) and tonumber(node.hysteria_recv_window) or nil,
|
recv_window = (node.hysteria_recv_window) and tonumber(node.hysteria_recv_window) or nil,
|
||||||
handshake_timeout = (node.hysteria_handshake_timeout) and tonumber(node.hysteria_handshake_timeout) or nil,
|
handshake_timeout = (node.hysteria_handshake_timeout) and tonumber(node.hysteria_handshake_timeout) or nil,
|
||||||
idle_timeout = (node.hysteria_idle_timeout) and tonumber(node.hysteria_idle_timeout) or nil,
|
idle_timeout = (node.hysteria_idle_timeout) and tonumber(node.hysteria_idle_timeout) or nil,
|
||||||
hop_interval = (node.hysteria_hop_interval) and tonumber(node.hysteria_hop_interval) or nil,
|
hop_interval = (node.hysteria_hop_interval) and tonumber(node.hysteria_hop_interval) or nil,
|
||||||
disable_mtu_discovery = (node.hysteria_disable_mtu_discovery) and true or false,
|
disable_mtu_discovery = (node.hysteria_disable_mtu_discovery) and true or false,
|
||||||
fast_open = (node.fast_open == "1") and true or false,
|
fast_open = (node.fast_open == "1") and true or false,
|
||||||
socks5 = (local_socks_address and local_socks_port) and {
|
socks5 = (local_socks_address and local_socks_port) and {
|
||||||
listen = local_socks_address .. ":" .. local_socks_port,
|
listen = local_socks_address .. ":" .. local_socks_port,
|
||||||
timeout = 300,
|
timeout = 300,
|
||||||
disable_udp = false,
|
disable_udp = false,
|
||||||
user = (local_socks_username and local_socks_password) and local_socks_username,
|
user = (local_socks_username and local_socks_password) and local_socks_username,
|
||||||
password = (local_socks_username and local_socks_password) and local_socks_password,
|
password = (local_socks_username and local_socks_password) and local_socks_password,
|
||||||
} or nil,
|
} or nil,
|
||||||
http = (local_http_address and local_http_port) and {
|
http = (local_http_address and local_http_port) and {
|
||||||
listen = local_http_address .. ":" .. local_http_port,
|
listen = local_http_address .. ":" .. local_http_port,
|
||||||
timeout = 300,
|
timeout = 300,
|
||||||
disable_udp = false,
|
disable_udp = false,
|
||||||
user = (local_http_username and local_http_password) and local_http_username,
|
user = (local_http_username and local_http_password) and local_http_username,
|
||||||
password = (local_http_username and local_http_password) and local_http_password,
|
password = (local_http_username and local_http_password) and local_http_password,
|
||||||
} or nil,
|
} or nil,
|
||||||
redirect_tcp = ("redirect" == tcp_proxy_way and local_tcp_redir_port) and {
|
redirect_tcp = ("redirect" == tcp_proxy_way and local_tcp_redir_port) and {
|
||||||
listen = "0.0.0.0:" .. local_tcp_redir_port,
|
listen = "0.0.0.0:" .. local_tcp_redir_port,
|
||||||
timeout = 300
|
timeout = 300
|
||||||
} or nil,
|
} or nil,
|
||||||
tproxy_tcp = ("tproxy" == tcp_proxy_way and local_tcp_redir_port) and {
|
tproxy_tcp = ("tproxy" == tcp_proxy_way and local_tcp_redir_port) and {
|
||||||
listen = "0.0.0.0:" .. local_tcp_redir_port,
|
listen = "0.0.0.0:" .. local_tcp_redir_port,
|
||||||
timeout = 300
|
timeout = 300
|
||||||
} or nil,
|
} or nil,
|
||||||
tproxy_udp = (local_udp_redir_port) and {
|
tproxy_udp = (local_udp_redir_port) and {
|
||||||
listen = "0.0.0.0:" .. local_udp_redir_port,
|
listen = "0.0.0.0:" .. local_udp_redir_port,
|
||||||
timeout = 60
|
timeout = 60
|
||||||
} or nil
|
} or nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return jsonc.stringify(config, 1)
|
return jsonc.stringify(config, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
_G.gen_config = gen_config
|
_G.gen_config = gen_config
|
||||||
|
|
||||||
if arg[1] then
|
if arg[1] then
|
||||||
local func =_G[arg[1]]
|
local func =_G[arg[1]]
|
||||||
if func then
|
if func then
|
||||||
print(func(api.get_function_args(arg)))
|
print(func(api.get_function_args(arg)))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -4,36 +4,36 @@ local uci = api.uci
|
|||||||
local jsonc = api.jsonc
|
local jsonc = api.jsonc
|
||||||
|
|
||||||
function gen_config(var)
|
function gen_config(var)
|
||||||
local node_id = var["-node"]
|
local node_id = var["-node"]
|
||||||
if not node_id then
|
if not node_id then
|
||||||
print("-node 不能为空")
|
print("-node 不能为空")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local node = uci:get_all("passwall", node_id)
|
local node = uci:get_all("passwall", node_id)
|
||||||
local run_type = var["-run_type"]
|
local run_type = var["-run_type"]
|
||||||
local local_addr = var["-local_addr"]
|
local local_addr = var["-local_addr"]
|
||||||
local local_port = var["-local_port"]
|
local local_port = var["-local_port"]
|
||||||
local server_host = var["-server_host"] or node.address
|
local server_host = var["-server_host"] or node.address
|
||||||
local server_port = var["-server_port"] or node.port
|
local server_port = var["-server_port"] or node.port
|
||||||
|
|
||||||
if api.is_ipv6(server_host) then
|
if api.is_ipv6(server_host) then
|
||||||
server_host = api.get_ipv6_full(server_host)
|
server_host = api.get_ipv6_full(server_host)
|
||||||
end
|
end
|
||||||
local server = server_host .. ":" .. server_port
|
local server = server_host .. ":" .. server_port
|
||||||
|
|
||||||
local config = {
|
local config = {
|
||||||
listen = run_type .. "://" .. local_addr .. ":" .. local_port,
|
listen = run_type .. "://" .. local_addr .. ":" .. local_port,
|
||||||
proxy = node.protocol .. "://" .. node.username .. ":" .. node.password .. "@" .. server
|
proxy = node.protocol .. "://" .. node.username .. ":" .. node.password .. "@" .. server
|
||||||
}
|
}
|
||||||
|
|
||||||
return jsonc.stringify(config, 1)
|
return jsonc.stringify(config, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
_G.gen_config = gen_config
|
_G.gen_config = gen_config
|
||||||
|
|
||||||
if arg[1] then
|
if arg[1] then
|
||||||
local func =_G[arg[1]]
|
local func =_G[arg[1]]
|
||||||
if func then
|
if func then
|
||||||
print(func(api.get_function_args(arg)))
|
print(func(api.get_function_args(arg)))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -4,141 +4,141 @@ local uci = api.uci
|
|||||||
local jsonc = api.jsonc
|
local jsonc = api.jsonc
|
||||||
|
|
||||||
function gen_config_server(node)
|
function gen_config_server(node)
|
||||||
local config = {}
|
local config = {}
|
||||||
config.server_port = tonumber(node.port)
|
config.server_port = tonumber(node.port)
|
||||||
config.password = node.password
|
config.password = node.password
|
||||||
config.timeout = tonumber(node.timeout)
|
config.timeout = tonumber(node.timeout)
|
||||||
config.fast_open = (node.tcp_fast_open and node.tcp_fast_open == "1") and true or false
|
config.fast_open = (node.tcp_fast_open and node.tcp_fast_open == "1") and true or false
|
||||||
config.method = node.method
|
config.method = node.method
|
||||||
|
|
||||||
if node.type == "SS-Rust" then
|
if node.type == "SS-Rust" then
|
||||||
config.server = "::"
|
config.server = "::"
|
||||||
config.mode = "tcp_and_udp"
|
config.mode = "tcp_and_udp"
|
||||||
else
|
else
|
||||||
config.server = {"[::0]", "0.0.0.0"}
|
config.server = {"[::0]", "0.0.0.0"}
|
||||||
end
|
end
|
||||||
|
|
||||||
if node.type == "SSR" then
|
if node.type == "SSR" then
|
||||||
config.protocol = node.protocol
|
config.protocol = node.protocol
|
||||||
config.protocol_param = node.protocol_param
|
config.protocol_param = node.protocol_param
|
||||||
config.obfs = node.obfs
|
config.obfs = node.obfs
|
||||||
config.obfs_param = node.obfs_param
|
config.obfs_param = node.obfs_param
|
||||||
end
|
end
|
||||||
|
|
||||||
return config
|
return config
|
||||||
end
|
end
|
||||||
|
|
||||||
function gen_config(var)
|
function gen_config(var)
|
||||||
local node_id = var["-node"]
|
local node_id = var["-node"]
|
||||||
if not node_id then
|
if not node_id then
|
||||||
print("-node 不能为空")
|
print("-node 不能为空")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local node = uci:get_all("passwall", node_id)
|
local node = uci:get_all("passwall", node_id)
|
||||||
local server_host = var["-server_host"] or node.address
|
local server_host = var["-server_host"] or node.address
|
||||||
local server_port = var["-server_port"] or node.port
|
local server_port = var["-server_port"] or node.port
|
||||||
local local_addr = var["-local_addr"]
|
local local_addr = var["-local_addr"]
|
||||||
local local_port = var["-local_port"]
|
local local_port = var["-local_port"]
|
||||||
local mode = var["-mode"]
|
local mode = var["-mode"]
|
||||||
local local_socks_address = var["-local_socks_address"] or "0.0.0.0"
|
local local_socks_address = var["-local_socks_address"] or "0.0.0.0"
|
||||||
local local_socks_port = var["-local_socks_port"]
|
local local_socks_port = var["-local_socks_port"]
|
||||||
local local_socks_username = var["-local_socks_username"]
|
local local_socks_username = var["-local_socks_username"]
|
||||||
local local_socks_password = var["-local_socks_password"]
|
local local_socks_password = var["-local_socks_password"]
|
||||||
local local_http_address = var["-local_http_address"] or "0.0.0.0"
|
local local_http_address = var["-local_http_address"] or "0.0.0.0"
|
||||||
local local_http_port = var["-local_http_port"]
|
local local_http_port = var["-local_http_port"]
|
||||||
local local_http_username = var["-local_http_username"]
|
local local_http_username = var["-local_http_username"]
|
||||||
local local_http_password = var["-local_http_password"]
|
local local_http_password = var["-local_http_password"]
|
||||||
local local_tcp_redir_port = var["-local_tcp_redir_port"]
|
local local_tcp_redir_port = var["-local_tcp_redir_port"]
|
||||||
local local_tcp_redir_address = var["-local_tcp_redir_address"] or "0.0.0.0"
|
local local_tcp_redir_address = var["-local_tcp_redir_address"] or "0.0.0.0"
|
||||||
local local_udp_redir_port = var["-local_udp_redir_port"]
|
local local_udp_redir_port = var["-local_udp_redir_port"]
|
||||||
local local_udp_redir_address = var["-local_udp_redir_address"] or "0.0.0.0"
|
local local_udp_redir_address = var["-local_udp_redir_address"] or "0.0.0.0"
|
||||||
|
|
||||||
if api.is_ipv6(server_host) then
|
if api.is_ipv6(server_host) then
|
||||||
server_host = api.get_ipv6_only(server_host)
|
server_host = api.get_ipv6_only(server_host)
|
||||||
end
|
end
|
||||||
local server = server_host
|
local server = server_host
|
||||||
|
|
||||||
local config = {
|
local config = {
|
||||||
server = server,
|
server = server,
|
||||||
server_port = tonumber(server_port),
|
server_port = tonumber(server_port),
|
||||||
local_address = local_addr,
|
local_address = local_addr,
|
||||||
local_port = tonumber(local_port),
|
local_port = tonumber(local_port),
|
||||||
password = node.password,
|
password = node.password,
|
||||||
method = node.method,
|
method = node.method,
|
||||||
timeout = tonumber(node.timeout),
|
timeout = tonumber(node.timeout),
|
||||||
fast_open = (node.tcp_fast_open and node.tcp_fast_open == "true") and true or false,
|
fast_open = (node.tcp_fast_open and node.tcp_fast_open == "true") and true or false,
|
||||||
reuse_port = true,
|
reuse_port = true,
|
||||||
tcp_tproxy = var["-tcp_tproxy"] and true or nil
|
tcp_tproxy = var["-tcp_tproxy"] and true or nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if node.type == "SS" then
|
if node.type == "SS" then
|
||||||
if node.plugin and node.plugin ~= "none" then
|
if node.plugin and node.plugin ~= "none" then
|
||||||
config.plugin = node.plugin
|
config.plugin = node.plugin
|
||||||
config.plugin_opts = node.plugin_opts or nil
|
config.plugin_opts = node.plugin_opts or nil
|
||||||
end
|
end
|
||||||
config.mode = mode
|
config.mode = mode
|
||||||
elseif node.type == "SSR" then
|
elseif node.type == "SSR" then
|
||||||
config.protocol = node.protocol
|
config.protocol = node.protocol
|
||||||
config.protocol_param = node.protocol_param
|
config.protocol_param = node.protocol_param
|
||||||
config.obfs = node.obfs
|
config.obfs = node.obfs
|
||||||
config.obfs_param = node.obfs_param
|
config.obfs_param = node.obfs_param
|
||||||
elseif node.type == "SS-Rust" then
|
elseif node.type == "SS-Rust" then
|
||||||
config = {
|
config = {
|
||||||
servers = {
|
servers = {
|
||||||
{
|
{
|
||||||
address = server,
|
address = server,
|
||||||
port = tonumber(server_port),
|
port = tonumber(server_port),
|
||||||
method = node.method,
|
method = node.method,
|
||||||
password = node.password,
|
password = node.password,
|
||||||
timeout = tonumber(node.timeout),
|
timeout = tonumber(node.timeout),
|
||||||
plugin = (node.plugin and node.plugin ~= "none") and node.plugin or nil,
|
plugin = (node.plugin and node.plugin ~= "none") and node.plugin or nil,
|
||||||
plugin_opts = (node.plugin and node.plugin ~= "none") and node.plugin_opts or nil
|
plugin_opts = (node.plugin and node.plugin ~= "none") and node.plugin_opts or nil
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
locals = {},
|
locals = {},
|
||||||
fast_open = (node.tcp_fast_open and node.tcp_fast_open == "true") and true or false
|
fast_open = (node.tcp_fast_open and node.tcp_fast_open == "true") and true or false
|
||||||
}
|
}
|
||||||
if local_socks_address and local_socks_port then
|
if local_socks_address and local_socks_port then
|
||||||
table.insert(config.locals, {
|
table.insert(config.locals, {
|
||||||
local_address = local_socks_address,
|
local_address = local_socks_address,
|
||||||
local_port = tonumber(local_socks_port),
|
local_port = tonumber(local_socks_port),
|
||||||
mode = "tcp_and_udp"
|
mode = "tcp_and_udp"
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
if local_http_address and local_http_port then
|
if local_http_address and local_http_port then
|
||||||
table.insert(config.locals, {
|
table.insert(config.locals, {
|
||||||
protocol = "http",
|
protocol = "http",
|
||||||
local_address = local_http_address,
|
local_address = local_http_address,
|
||||||
local_port = tonumber(local_http_port)
|
local_port = tonumber(local_http_port)
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
if local_tcp_redir_address and local_tcp_redir_port then
|
if local_tcp_redir_address and local_tcp_redir_port then
|
||||||
table.insert(config.locals, {
|
table.insert(config.locals, {
|
||||||
protocol = "redir",
|
protocol = "redir",
|
||||||
mode = "tcp_only",
|
mode = "tcp_only",
|
||||||
tcp_redir = var["-tcp_tproxy"] and "tproxy" or nil,
|
tcp_redir = var["-tcp_tproxy"] and "tproxy" or nil,
|
||||||
local_address = local_tcp_redir_address,
|
local_address = local_tcp_redir_address,
|
||||||
local_port = tonumber(local_tcp_redir_port)
|
local_port = tonumber(local_tcp_redir_port)
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
if local_udp_redir_address and local_udp_redir_port then
|
if local_udp_redir_address and local_udp_redir_port then
|
||||||
table.insert(config.locals, {
|
table.insert(config.locals, {
|
||||||
protocol = "redir",
|
protocol = "redir",
|
||||||
mode = "udp_only",
|
mode = "udp_only",
|
||||||
local_address = local_udp_redir_address,
|
local_address = local_udp_redir_address,
|
||||||
local_port = tonumber(local_udp_redir_port)
|
local_port = tonumber(local_udp_redir_port)
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
return jsonc.stringify(config, 1)
|
return jsonc.stringify(config, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
_G.gen_config = gen_config
|
_G.gen_config = gen_config
|
||||||
|
|
||||||
if arg[1] then
|
if arg[1] then
|
||||||
local func =_G[arg[1]]
|
local func =_G[arg[1]]
|
||||||
if func then
|
if func then
|
||||||
print(func(api.get_function_args(arg)))
|
print(func(api.get_function_args(arg)))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -4,155 +4,155 @@ local uci = api.uci
|
|||||||
local json = api.jsonc
|
local json = api.jsonc
|
||||||
|
|
||||||
function gen_config_server(node)
|
function gen_config_server(node)
|
||||||
local cipher = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA"
|
local cipher = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA"
|
||||||
local cipher13 = "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384"
|
local cipher13 = "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384"
|
||||||
local config = {
|
local config = {
|
||||||
run_type = "server",
|
run_type = "server",
|
||||||
local_addr = "::",
|
local_addr = "::",
|
||||||
local_port = tonumber(node.port),
|
local_port = tonumber(node.port),
|
||||||
remote_addr = (node.remote_enable == "1" and node.remote_address) and node.remote_address or nil,
|
remote_addr = (node.remote_enable == "1" and node.remote_address) and node.remote_address or nil,
|
||||||
remote_port = (node.remote_enable == "1" and node.remote_port) and tonumber(node.remote_port) or nil,
|
remote_port = (node.remote_enable == "1" and node.remote_port) and tonumber(node.remote_port) or nil,
|
||||||
password = node.uuid,
|
password = node.uuid,
|
||||||
log_level = (node.log and node.log == "1") and tonumber(node.loglevel) or 5,
|
log_level = (node.log and node.log == "1") and tonumber(node.loglevel) or 5,
|
||||||
ssl = {
|
ssl = {
|
||||||
cert = node.tls_certificateFile,
|
cert = node.tls_certificateFile,
|
||||||
key = node.tls_keyFile,
|
key = node.tls_keyFile,
|
||||||
key_password = "",
|
key_password = "",
|
||||||
cipher = cipher,
|
cipher = cipher,
|
||||||
cipher_tls13 = cipher13,
|
cipher_tls13 = cipher13,
|
||||||
prefer_server_cipher = true,
|
prefer_server_cipher = true,
|
||||||
reuse_session = true,
|
reuse_session = true,
|
||||||
session_ticket = (node.tls_sessionTicket == "1") and true or false,
|
session_ticket = (node.tls_sessionTicket == "1") and true or false,
|
||||||
session_timeout = 600,
|
session_timeout = 600,
|
||||||
plain_http_response = "",
|
plain_http_response = "",
|
||||||
curves = "",
|
curves = "",
|
||||||
dhparam = ""
|
dhparam = ""
|
||||||
},
|
},
|
||||||
tcp = {
|
tcp = {
|
||||||
prefer_ipv4 = false,
|
prefer_ipv4 = false,
|
||||||
no_delay = true,
|
no_delay = true,
|
||||||
keep_alive = true,
|
keep_alive = true,
|
||||||
reuse_port = false,
|
reuse_port = false,
|
||||||
fast_open = (node.tcp_fast_open and node.tcp_fast_open == "1") and true or false,
|
fast_open = (node.tcp_fast_open and node.tcp_fast_open == "1") and true or false,
|
||||||
fast_open_qlen = 20
|
fast_open_qlen = 20
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if node.type == "Trojan-Go" then
|
if node.type == "Trojan-Go" then
|
||||||
config.ssl.cipher = nil
|
config.ssl.cipher = nil
|
||||||
config.ssl.cipher_tls13 = nil
|
config.ssl.cipher_tls13 = nil
|
||||||
config.udp_timeout = 60
|
config.udp_timeout = 60
|
||||||
config.disable_http_check = true
|
config.disable_http_check = true
|
||||||
config.transport_plugin = ((node.tls == nil or node.tls ~= "1") and node.trojan_transport == "original") and {
|
config.transport_plugin = ((node.tls == nil or node.tls ~= "1") and node.trojan_transport == "original") and {
|
||||||
enabled = node.plugin_type ~= nil,
|
enabled = node.plugin_type ~= nil,
|
||||||
type = node.plugin_type or "plaintext",
|
type = node.plugin_type or "plaintext",
|
||||||
command = node.plugin_type ~= "plaintext" and node.plugin_cmd or nil,
|
command = node.plugin_type ~= "plaintext" and node.plugin_cmd or nil,
|
||||||
option = node.plugin_type ~= "plaintext" and node.plugin_option or nil,
|
option = node.plugin_type ~= "plaintext" and node.plugin_option or nil,
|
||||||
arg = node.plugin_type ~= "plaintext" and { node.plugin_arg } or nil,
|
arg = node.plugin_type ~= "plaintext" and { node.plugin_arg } or nil,
|
||||||
env = {}
|
env = {}
|
||||||
} or nil
|
} or nil
|
||||||
config.websocket = (node.trojan_transport == 'ws') and {
|
config.websocket = (node.trojan_transport == 'ws') and {
|
||||||
enabled = true,
|
enabled = true,
|
||||||
path = node.ws_path or "/",
|
path = node.ws_path or "/",
|
||||||
host = node.ws_host or ""
|
host = node.ws_host or ""
|
||||||
} or nil
|
} or nil
|
||||||
config.shadowsocks = (node.ss_aead == "1") and {
|
config.shadowsocks = (node.ss_aead == "1") and {
|
||||||
enabled = true,
|
enabled = true,
|
||||||
method = node.ss_aead_method or "aes_128_gcm",
|
method = node.ss_aead_method or "aes_128_gcm",
|
||||||
password = node.ss_aead_pwd or ""
|
password = node.ss_aead_pwd or ""
|
||||||
} or nil
|
} or nil
|
||||||
end
|
end
|
||||||
return config
|
return config
|
||||||
end
|
end
|
||||||
|
|
||||||
function gen_config(var)
|
function gen_config(var)
|
||||||
local node_id = var["-node"]
|
local node_id = var["-node"]
|
||||||
if not node_id then
|
if not node_id then
|
||||||
print("-node 不能为空")
|
print("-node 不能为空")
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local node = uci:get_all("passwall", node_id)
|
local node = uci:get_all("passwall", node_id)
|
||||||
local run_type = var["-run_type"]
|
local run_type = var["-run_type"]
|
||||||
local local_addr = var["-local_addr"]
|
local local_addr = var["-local_addr"]
|
||||||
local local_port = var["-local_port"]
|
local local_port = var["-local_port"]
|
||||||
local server_host = var["-server_host"] or node.address
|
local server_host = var["-server_host"] or node.address
|
||||||
local server_port = var["-server_port"] or node.port
|
local server_port = var["-server_port"] or node.port
|
||||||
local loglevel = var["-loglevel"] or 2
|
local loglevel = var["-loglevel"] or 2
|
||||||
local cipher = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA"
|
local cipher = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA:AES128-SHA:AES256-SHA:DES-CBC3-SHA"
|
||||||
local cipher13 = "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384"
|
local cipher13 = "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384"
|
||||||
|
|
||||||
if api.is_ipv6(server_host) then
|
if api.is_ipv6(server_host) then
|
||||||
server_host = api.get_ipv6_only(server_host)
|
server_host = api.get_ipv6_only(server_host)
|
||||||
end
|
end
|
||||||
local server = server_host
|
local server = server_host
|
||||||
|
|
||||||
local trojan = {
|
local trojan = {
|
||||||
run_type = run_type,
|
run_type = run_type,
|
||||||
local_addr = local_addr,
|
local_addr = local_addr,
|
||||||
local_port = tonumber(local_port),
|
local_port = tonumber(local_port),
|
||||||
remote_addr = server,
|
remote_addr = server,
|
||||||
remote_port = tonumber(server_port),
|
remote_port = tonumber(server_port),
|
||||||
password = {node.password},
|
password = {node.password},
|
||||||
log_level = tonumber(loglevel),
|
log_level = tonumber(loglevel),
|
||||||
ssl = {
|
ssl = {
|
||||||
verify = (node.tls_allowInsecure ~= "1") and true or false,
|
verify = (node.tls_allowInsecure ~= "1") and true or false,
|
||||||
verify_hostname = true,
|
verify_hostname = true,
|
||||||
cert = nil,
|
cert = nil,
|
||||||
cipher = cipher,
|
cipher = cipher,
|
||||||
cipher_tls13 = cipher13,
|
cipher_tls13 = cipher13,
|
||||||
sni = node.tls_serverName or server,
|
sni = node.tls_serverName or server,
|
||||||
alpn = {"h2", "http/1.1"},
|
alpn = {"h2", "http/1.1"},
|
||||||
reuse_session = true,
|
reuse_session = true,
|
||||||
session_ticket = (node.tls_sessionTicket and node.tls_sessionTicket == "1") and true or false,
|
session_ticket = (node.tls_sessionTicket and node.tls_sessionTicket == "1") and true or false,
|
||||||
curves = ""
|
curves = ""
|
||||||
},
|
},
|
||||||
udp_timeout = 60,
|
udp_timeout = 60,
|
||||||
tcp = {
|
tcp = {
|
||||||
use_tproxy = (node.type == "Trojan-Plus" and var["-use_tproxy"]) and true or nil,
|
use_tproxy = (node.type == "Trojan-Plus" and var["-use_tproxy"]) and true or nil,
|
||||||
no_delay = true,
|
no_delay = true,
|
||||||
keep_alive = true,
|
keep_alive = true,
|
||||||
reuse_port = true,
|
reuse_port = true,
|
||||||
fast_open = (node.tcp_fast_open == "true") and true or false,
|
fast_open = (node.tcp_fast_open == "true") and true or false,
|
||||||
fast_open_qlen = 20
|
fast_open_qlen = 20
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if node.type == "Trojan-Go" then
|
if node.type == "Trojan-Go" then
|
||||||
trojan.ssl.cipher = nil
|
trojan.ssl.cipher = nil
|
||||||
trojan.ssl.cipher_tls13 = nil
|
trojan.ssl.cipher_tls13 = nil
|
||||||
trojan.ssl.fingerprint = (node.fingerprint ~= "disable") and node.fingerprint or ""
|
trojan.ssl.fingerprint = (node.fingerprint ~= "disable") and node.fingerprint or ""
|
||||||
trojan.ssl.alpn = (node.trojan_transport == 'ws') and {} or {"h2", "http/1.1"}
|
trojan.ssl.alpn = (node.trojan_transport == 'ws') and {} or {"h2", "http/1.1"}
|
||||||
if node.tls ~= "1" and node.trojan_transport == "original" then trojan.ssl = nil end
|
if node.tls ~= "1" and node.trojan_transport == "original" then trojan.ssl = nil end
|
||||||
trojan.transport_plugin = ((not node.tls or node.tls ~= "1") and node.trojan_transport == "original") and {
|
trojan.transport_plugin = ((not node.tls or node.tls ~= "1") and node.trojan_transport == "original") and {
|
||||||
enabled = node.plugin_type ~= nil,
|
enabled = node.plugin_type ~= nil,
|
||||||
type = node.plugin_type or "plaintext",
|
type = node.plugin_type or "plaintext",
|
||||||
command = node.plugin_type ~= "plaintext" and node.plugin_cmd or nil,
|
command = node.plugin_type ~= "plaintext" and node.plugin_cmd or nil,
|
||||||
option = node.plugin_type ~= "plaintext" and node.plugin_option or nil,
|
option = node.plugin_type ~= "plaintext" and node.plugin_option or nil,
|
||||||
arg = node.plugin_type ~= "plaintext" and { node.plugin_arg } or nil,
|
arg = node.plugin_type ~= "plaintext" and { node.plugin_arg } or nil,
|
||||||
env = {}
|
env = {}
|
||||||
} or nil
|
} or nil
|
||||||
trojan.websocket = (node.trojan_transport == 'ws') and {
|
trojan.websocket = (node.trojan_transport == 'ws') and {
|
||||||
enabled = true,
|
enabled = true,
|
||||||
path = node.ws_path or "/",
|
path = node.ws_path or "/",
|
||||||
host = node.ws_host or (node.tls_serverName or server)
|
host = node.ws_host or (node.tls_serverName or server)
|
||||||
} or nil
|
} or nil
|
||||||
trojan.shadowsocks = (node.ss_aead == "1") and {
|
trojan.shadowsocks = (node.ss_aead == "1") and {
|
||||||
enabled = true,
|
enabled = true,
|
||||||
method = node.ss_aead_method or "aes_128_gcm",
|
method = node.ss_aead_method or "aes_128_gcm",
|
||||||
password = node.ss_aead_pwd or ""
|
password = node.ss_aead_pwd or ""
|
||||||
} or nil
|
} or nil
|
||||||
trojan.mux = (node.smux == "1") and {
|
trojan.mux = (node.smux == "1") and {
|
||||||
enabled = true,
|
enabled = true,
|
||||||
concurrency = tonumber(node.mux_concurrency),
|
concurrency = tonumber(node.mux_concurrency),
|
||||||
idle_timeout = tonumber(node.smux_idle_timeout)
|
idle_timeout = tonumber(node.smux_idle_timeout)
|
||||||
} or nil
|
} or nil
|
||||||
end
|
end
|
||||||
return json.stringify(trojan, 1)
|
return json.stringify(trojan, 1)
|
||||||
end
|
end
|
||||||
|
|
||||||
_G.gen_config = gen_config
|
_G.gen_config = gen_config
|
||||||
|
|
||||||
if arg[1] then
|
if arg[1] then
|
||||||
local func =_G[arg[1]]
|
local func =_G[arg[1]]
|
||||||
if func then
|
if func then
|
||||||
print(func(api.get_function_args(arg)))
|
print(func(api.get_function_args(arg)))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -37,7 +37,6 @@ local version = {}
|
|||||||
if (inProgressCount === 0) {
|
if (inProgressCount === 0) {
|
||||||
window.onbeforeunload = undefined;
|
window.onbeforeunload = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onUpdateSuccess(btn) {
|
function onUpdateSuccess(btn) {
|
||||||
|
@ -10,6 +10,7 @@ local api = require "luci.passwall.api"
|
|||||||
window.location.href = '<%=api.url("autoswitch_add_node")%>' + "?key=" + key;
|
window.location.href = '<%=api.url("autoswitch_add_node")%>' + "?key=" + key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function remove_node_by_key() {
|
function remove_node_by_key() {
|
||||||
var key = prompt("<%:Please enter the node keyword, pay attention to distinguish between spaces, uppercase and lowercase.%>", "");
|
var key = prompt("<%:Please enter the node keyword, pay attention to distinguish between spaces, uppercase and lowercase.%>", "");
|
||||||
if (key) {
|
if (key) {
|
||||||
|
@ -14,6 +14,7 @@ local api = require "luci.passwall.api"
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
XHR.poll(5, '<%=api.url("get_log")%>', null,
|
XHR.poll(5, '<%=api.url("get_log")%>', null,
|
||||||
function(x, data) {
|
function(x, data) {
|
||||||
if(x && x.status == 200) {
|
if(x && x.status == 200) {
|
||||||
|
@ -13,7 +13,7 @@ local api = require "luci.passwall.api"
|
|||||||
z-index: 99;
|
z-index: 99;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background: white;
|
background: white;
|
||||||
box-shadow: darkgrey 10px 10px 30px 5px;
|
box-shadow: darkgrey 10px 10px 30px 5px;
|
||||||
padding: 30px 15px;
|
padding: 30px 15px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -55,6 +55,7 @@ local has_xray = api.is_finded("xray")
|
|||||||
return '';
|
return '';
|
||||||
return b64decsafe(v);
|
return b64decsafe(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
function parseNodeUrl(url) {
|
function parseNodeUrl(url) {
|
||||||
var m = url.match(/^(([^:\/?#]+:)?(?:\/\/((?:([^\/?#:]*)([^\/?#:]*)@)?([^\/?#:]*)(?::([^\/?#:]*))?)))?([^?#]*)(\?[^#]*)?(#.*)?$/),
|
var m = url.match(/^(([^:\/?#]+:)?(?:\/\/((?:([^\/?#:]*)([^\/?#:]*)@)?([^\/?#:]*)(?::([^\/?#:]*))?)))?([^?#]*)(\?[^#]*)?(#.*)?$/),
|
||||||
r = {
|
r = {
|
||||||
|
@ -9,8 +9,8 @@ table th, .table .th {
|
|||||||
|
|
||||||
table td, .table .td {
|
table td, .table .td {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
/* white-space: nowrap; */
|
/* white-space: nowrap; */
|
||||||
word-break: keep-all;
|
word-break: keep-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
#set_node_div {
|
#set_node_div {
|
||||||
@ -22,7 +22,7 @@ table td, .table .td {
|
|||||||
z-index: 99;
|
z-index: 99;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background: white;
|
background: white;
|
||||||
box-shadow: darkgrey 10px 10px 30px 5px;
|
box-shadow: darkgrey 10px 10px 30px 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
._now_use {
|
._now_use {
|
||||||
|
@ -14,6 +14,7 @@ local api = require "luci.passwall.api"
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
XHR.poll(3, '<%=api.url("server_get_log")%>', null,
|
XHR.poll(3, '<%=api.url("server_get_log")%>', null,
|
||||||
function(x, data) {
|
function(x, data) {
|
||||||
if(x && x.status == 200) {
|
if(x && x.status == 200) {
|
||||||
|
@ -33,133 +33,133 @@ local excluded_domain = {}
|
|||||||
local excluded_domain_str = "!"
|
local excluded_domain_str = "!"
|
||||||
|
|
||||||
local function log(...)
|
local function log(...)
|
||||||
if NO_LOGIC_LOG == "1" then
|
if NO_LOGIC_LOG == "1" then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
local f, err = io.open(LOG_FILE, "a")
|
local f, err = io.open(LOG_FILE, "a")
|
||||||
if f and err == nil then
|
if f and err == nil then
|
||||||
local str = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
|
local str = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
|
||||||
f:write(str .. "\n")
|
f:write(str .. "\n")
|
||||||
f:close()
|
f:close()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function check_dns(domain, dns)
|
local function check_dns(domain, dns)
|
||||||
if domain == "" or domain:find("#") then
|
if domain == "" or domain:find("#") then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
if not dns then
|
if not dns then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
for k,v in ipairs(list1[domain].dns) do
|
for k,v in ipairs(list1[domain].dns) do
|
||||||
if dns == v then
|
if dns == v then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
local function check_ipset(domain, ipset)
|
local function check_ipset(domain, ipset)
|
||||||
if domain == "" or domain:find("#") then
|
if domain == "" or domain:find("#") then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
if not ipset then
|
if not ipset then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
for k,v in ipairs(list1[domain].ipsets) do
|
for k,v in ipairs(list1[domain].ipsets) do
|
||||||
if ipset == v then
|
if ipset == v then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
local function set_domain_address(domain, address)
|
local function set_domain_address(domain, address)
|
||||||
if domain == "" or domain:find("#") then
|
if domain == "" or domain:find("#") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if not list1[domain] then
|
if not list1[domain] then
|
||||||
list1[domain] = {
|
list1[domain] = {
|
||||||
dns = {},
|
dns = {},
|
||||||
ipsets = {}
|
ipsets = {}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
if not list1[domain].address then
|
if not list1[domain].address then
|
||||||
list1[domain].address = address
|
list1[domain].address = address
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function set_domain_dns(domain, dns)
|
local function set_domain_dns(domain, dns)
|
||||||
if domain == "" or domain:find("#") then
|
if domain == "" or domain:find("#") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if not dns then
|
if not dns then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if not list1[domain] then
|
if not list1[domain] then
|
||||||
list1[domain] = {
|
list1[domain] = {
|
||||||
dns = {},
|
dns = {},
|
||||||
ipsets = {}
|
ipsets = {}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
for line in string.gmatch(dns, '[^' .. "," .. ']+') do
|
for line in string.gmatch(dns, '[^' .. "," .. ']+') do
|
||||||
if not check_dns(domain, line) then
|
if not check_dns(domain, line) then
|
||||||
table.insert(list1[domain].dns, line)
|
table.insert(list1[domain].dns, line)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function set_domain_ipset(domain, ipset)
|
local function set_domain_ipset(domain, ipset)
|
||||||
if domain == "" or domain:find("#") then
|
if domain == "" or domain:find("#") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if not ipset then
|
if not ipset then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if not list1[domain] then
|
if not list1[domain] then
|
||||||
list1[domain] = {
|
list1[domain] = {
|
||||||
dns = {},
|
dns = {},
|
||||||
ipsets = {}
|
ipsets = {}
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
for line in string.gmatch(ipset, '[^' .. "," .. ']+') do
|
for line in string.gmatch(ipset, '[^' .. "," .. ']+') do
|
||||||
if not check_ipset(domain, line) then
|
if not check_ipset(domain, line) then
|
||||||
table.insert(list1[domain].ipsets, line)
|
table.insert(list1[domain].ipsets, line)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function add_excluded_domain(domain)
|
local function add_excluded_domain(domain)
|
||||||
if domain == "" or domain:find("#") then
|
if domain == "" or domain:find("#") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
table.insert(excluded_domain, domain)
|
table.insert(excluded_domain, domain)
|
||||||
excluded_domain_str = excluded_domain_str .. "|" .. domain
|
excluded_domain_str = excluded_domain_str .. "|" .. domain
|
||||||
end
|
end
|
||||||
|
|
||||||
local function check_excluded_domain(domain)
|
local function check_excluded_domain(domain)
|
||||||
if domain == "" or domain:find("#") then
|
if domain == "" or domain:find("#") then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
for k,v in ipairs(excluded_domain) do
|
for k,v in ipairs(excluded_domain) do
|
||||||
if domain:find(v) then
|
if domain:find(v) then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
local cache_text = ""
|
local cache_text = ""
|
||||||
local new_rules = luci.sys.exec("echo -n $(find /usr/share/passwall/rules -type f | xargs md5sum)")
|
local new_rules = luci.sys.exec("echo -n $(find /usr/share/passwall/rules -type f | xargs md5sum)")
|
||||||
local new_text = TMP_DNSMASQ_PATH .. DNSMASQ_CONF_FILE .. DEFAULT_DNS .. LOCAL_DNS .. TUN_DNS .. REMOTE_FAKEDNS .. CHNROUTE_MODE_DEFAULT_DNS .. CHINADNS_DNS .. PROXY_MODE .. NO_PROXY_IPV6 .. new_rules .. NFTFLAG
|
local new_text = TMP_DNSMASQ_PATH .. DNSMASQ_CONF_FILE .. DEFAULT_DNS .. LOCAL_DNS .. TUN_DNS .. REMOTE_FAKEDNS .. CHNROUTE_MODE_DEFAULT_DNS .. CHINADNS_DNS .. PROXY_MODE .. NO_PROXY_IPV6 .. new_rules .. NFTFLAG
|
||||||
if fs.access(CACHE_TEXT_FILE) then
|
if fs.access(CACHE_TEXT_FILE) then
|
||||||
for line in io.lines(CACHE_TEXT_FILE) do
|
for line in io.lines(CACHE_TEXT_FILE) do
|
||||||
cache_text = line
|
cache_text = line
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if cache_text ~= new_text then
|
if cache_text ~= new_text then
|
||||||
api.remove(CACHE_DNS_PATH .. "*")
|
api.remove(CACHE_DNS_PATH .. "*")
|
||||||
end
|
end
|
||||||
|
|
||||||
local global = PROXY_MODE:find("global")
|
local global = PROXY_MODE:find("global")
|
||||||
@ -170,252 +170,252 @@ local only_global
|
|||||||
|
|
||||||
local dnsmasq_default_dns
|
local dnsmasq_default_dns
|
||||||
if CHNROUTE_MODE_DEFAULT_DNS ~= "nil" and chnlist then
|
if CHNROUTE_MODE_DEFAULT_DNS ~= "nil" and chnlist then
|
||||||
if CHNROUTE_MODE_DEFAULT_DNS == "remote" then
|
if CHNROUTE_MODE_DEFAULT_DNS == "remote" then
|
||||||
dnsmasq_default_dns = TUN_DNS
|
dnsmasq_default_dns = TUN_DNS
|
||||||
end
|
end
|
||||||
if CHNROUTE_MODE_DEFAULT_DNS == "chinadns_ng" and CHINADNS_DNS ~= "0" then
|
if CHNROUTE_MODE_DEFAULT_DNS == "chinadns_ng" and CHINADNS_DNS ~= "0" then
|
||||||
dnsmasq_default_dns = CHINADNS_DNS
|
dnsmasq_default_dns = CHINADNS_DNS
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if global and (not returnhome and not chnlist and not gfwlist) then
|
if global and (not returnhome and not chnlist and not gfwlist) then
|
||||||
--只有全局模式时
|
--只有全局模式时
|
||||||
dnsmasq_default_dns = TUN_DNS
|
dnsmasq_default_dns = TUN_DNS
|
||||||
only_global = 1
|
only_global = 1
|
||||||
end
|
end
|
||||||
|
|
||||||
local setflag_4= (NFTFLAG == "1") and "4#inet#fw4#" or ""
|
local setflag_4= (NFTFLAG == "1") and "4#inet#fw4#" or ""
|
||||||
local setflag_6= (NFTFLAG == "1") and "6#inet#fw4#" or ""
|
local setflag_6= (NFTFLAG == "1") and "6#inet#fw4#" or ""
|
||||||
|
|
||||||
if not fs.access(CACHE_DNS_PATH) then
|
if not fs.access(CACHE_DNS_PATH) then
|
||||||
fs.mkdir("/tmp/dnsmasq.d")
|
fs.mkdir("/tmp/dnsmasq.d")
|
||||||
fs.mkdir(CACHE_DNS_PATH)
|
fs.mkdir(CACHE_DNS_PATH)
|
||||||
|
|
||||||
--屏蔽列表
|
--屏蔽列表
|
||||||
for line in io.lines("/usr/share/passwall/rules/block_host") do
|
for line in io.lines("/usr/share/passwall/rules/block_host") do
|
||||||
if line ~= "" and not line:find("#") then
|
if line ~= "" and not line:find("#") then
|
||||||
set_domain_address(line, "0.0.0.0")
|
set_domain_address(line, "0.0.0.0")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
--始终用国内DNS解析节点域名
|
--始终用国内DNS解析节点域名
|
||||||
uci:foreach(appname, "nodes", function(t)
|
uci:foreach(appname, "nodes", function(t)
|
||||||
local address = t.address
|
local address = t.address
|
||||||
if datatypes.hostname(address) then
|
if datatypes.hostname(address) then
|
||||||
set_domain_dns(address, LOCAL_DNS)
|
set_domain_dns(address, LOCAL_DNS)
|
||||||
set_domain_ipset(address, setflag_4 .. "vpsiplist," .. setflag_6 .. "vpsiplist6")
|
set_domain_ipset(address, setflag_4 .. "vpsiplist," .. setflag_6 .. "vpsiplist6")
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
log(string.format(" - 节点列表中的域名(vpsiplist):%s", LOCAL_DNS or "默认"))
|
log(string.format(" - 节点列表中的域名(vpsiplist):%s", LOCAL_DNS or "默认"))
|
||||||
|
|
||||||
--始终用国内DNS解析直连(白名单)列表
|
--始终用国内DNS解析直连(白名单)列表
|
||||||
for line in io.lines("/usr/share/passwall/rules/direct_host") do
|
for line in io.lines("/usr/share/passwall/rules/direct_host") do
|
||||||
if line ~= "" and not line:find("#") then
|
if line ~= "" and not line:find("#") then
|
||||||
add_excluded_domain(line)
|
add_excluded_domain(line)
|
||||||
set_domain_dns(line, LOCAL_DNS)
|
set_domain_dns(line, LOCAL_DNS)
|
||||||
set_domain_ipset(line, setflag_4 .. "whitelist," .. setflag_6 .. "whitelist6")
|
set_domain_ipset(line, setflag_4 .. "whitelist," .. setflag_6 .. "whitelist6")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
log(string.format(" - 域名白名单(whitelist):%s", LOCAL_DNS or "默认"))
|
log(string.format(" - 域名白名单(whitelist):%s", LOCAL_DNS or "默认"))
|
||||||
|
|
||||||
local fwd_dns
|
local fwd_dns
|
||||||
local ipset_flag
|
local ipset_flag
|
||||||
local no_ipv6
|
local no_ipv6
|
||||||
|
|
||||||
--始终使用远程DNS解析代理(黑名单)列表
|
--始终使用远程DNS解析代理(黑名单)列表
|
||||||
for line in io.lines("/usr/share/passwall/rules/proxy_host") do
|
for line in io.lines("/usr/share/passwall/rules/proxy_host") do
|
||||||
if line ~= "" and not line:find("#") then
|
if line ~= "" and not line:find("#") then
|
||||||
add_excluded_domain(line)
|
add_excluded_domain(line)
|
||||||
local ipset_flag = setflag_4 .. "blacklist," .. setflag_6 .. "blacklist6"
|
local ipset_flag = setflag_4 .. "blacklist," .. setflag_6 .. "blacklist6"
|
||||||
if NO_PROXY_IPV6 == "1" then
|
if NO_PROXY_IPV6 == "1" then
|
||||||
set_domain_address(line, "::")
|
set_domain_address(line, "::")
|
||||||
ipset_flag = setflag_4 .. "blacklist"
|
ipset_flag = setflag_4 .. "blacklist"
|
||||||
end
|
end
|
||||||
if REMOTE_FAKEDNS == "1" then
|
if REMOTE_FAKEDNS == "1" then
|
||||||
ipset_flag = nil
|
ipset_flag = nil
|
||||||
end
|
end
|
||||||
set_domain_dns(line, TUN_DNS)
|
set_domain_dns(line, TUN_DNS)
|
||||||
set_domain_ipset(line, ipset_flag)
|
set_domain_ipset(line, ipset_flag)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
log(string.format(" - 代理域名表(blacklist):%s", TUN_DNS or "默认"))
|
log(string.format(" - 代理域名表(blacklist):%s", TUN_DNS or "默认"))
|
||||||
|
|
||||||
--分流规则
|
--分流规则
|
||||||
if uci:get(appname, TCP_NODE, "protocol") == "_shunt" then
|
if uci:get(appname, TCP_NODE, "protocol") == "_shunt" then
|
||||||
local t = uci:get_all(appname, TCP_NODE)
|
local t = uci:get_all(appname, TCP_NODE)
|
||||||
local default_node_id = t["default_node"] or "_direct"
|
local default_node_id = t["default_node"] or "_direct"
|
||||||
uci:foreach(appname, "shunt_rules", function(s)
|
uci:foreach(appname, "shunt_rules", function(s)
|
||||||
local _node_id = t[s[".name"]] or "nil"
|
local _node_id = t[s[".name"]] or "nil"
|
||||||
if _node_id ~= "nil" and _node_id ~= "_blackhole" then
|
if _node_id ~= "nil" and _node_id ~= "_blackhole" then
|
||||||
if _node_id == "_default" then
|
if _node_id == "_default" then
|
||||||
_node_id = default_node_id
|
_node_id = default_node_id
|
||||||
end
|
end
|
||||||
|
|
||||||
fwd_dns = nil
|
fwd_dns = nil
|
||||||
ipset_flag = nil
|
ipset_flag = nil
|
||||||
no_ipv6 = nil
|
no_ipv6 = nil
|
||||||
|
|
||||||
if _node_id == "_direct" then
|
if _node_id == "_direct" then
|
||||||
fwd_dns = LOCAL_DNS
|
fwd_dns = LOCAL_DNS
|
||||||
ipset_flag = setflag_4 .. "whitelist," .. setflag_6 .. "whitelist6"
|
ipset_flag = setflag_4 .. "whitelist," .. setflag_6 .. "whitelist6"
|
||||||
else
|
else
|
||||||
fwd_dns = TUN_DNS
|
fwd_dns = TUN_DNS
|
||||||
ipset_flag = setflag_4 .. "shuntlist," .. setflag_6 .. "shuntlist6"
|
ipset_flag = setflag_4 .. "shuntlist," .. setflag_6 .. "shuntlist6"
|
||||||
if NO_PROXY_IPV6 == "1" then
|
if NO_PROXY_IPV6 == "1" then
|
||||||
ipset_flag = setflag_4 .. "shuntlist"
|
ipset_flag = setflag_4 .. "shuntlist"
|
||||||
no_ipv6 = true
|
no_ipv6 = true
|
||||||
end
|
end
|
||||||
if not only_global then
|
if not only_global then
|
||||||
if REMOTE_FAKEDNS == "1" then
|
if REMOTE_FAKEDNS == "1" then
|
||||||
ipset_flag = nil
|
ipset_flag = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local domain_list = s.domain_list or ""
|
local domain_list = s.domain_list or ""
|
||||||
for line in string.gmatch(domain_list, "[^\r\n]+") do
|
for line in string.gmatch(domain_list, "[^\r\n]+") do
|
||||||
if line ~= "" and not line:find("#") and not line:find("regexp:") and not line:find("geosite:") and not line:find("ext:") then
|
if line ~= "" and not line:find("#") and not line:find("regexp:") and not line:find("geosite:") and not line:find("ext:") then
|
||||||
if line:find("domain:") or line:find("full:") then
|
if line:find("domain:") or line:find("full:") then
|
||||||
line = string.match(line, ":([^:]+)$")
|
line = string.match(line, ":([^:]+)$")
|
||||||
end
|
end
|
||||||
add_excluded_domain(line)
|
add_excluded_domain(line)
|
||||||
|
|
||||||
if no_ipv6 then
|
if no_ipv6 then
|
||||||
set_domain_address(line, "::")
|
set_domain_address(line, "::")
|
||||||
end
|
end
|
||||||
set_domain_dns(line, fwd_dns)
|
set_domain_dns(line, fwd_dns)
|
||||||
set_domain_ipset(line, ipset_flag)
|
set_domain_ipset(line, ipset_flag)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if _node_id ~= "_direct" then
|
if _node_id ~= "_direct" then
|
||||||
log(string.format(" - V2ray/Xray分流规则(%s):%s", s.remarks, fwd_dns or "默认"))
|
log(string.format(" - V2ray/Xray分流规则(%s):%s", s.remarks, fwd_dns or "默认"))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
end
|
end
|
||||||
|
|
||||||
--如果没有使用回国模式
|
--如果没有使用回国模式
|
||||||
if not returnhome then
|
if not returnhome then
|
||||||
if fs.access("/usr/share/passwall/rules/gfwlist") then
|
if fs.access("/usr/share/passwall/rules/gfwlist") then
|
||||||
local gfwlist_str = sys.exec('cat /usr/share/passwall/rules/gfwlist | grep -v -E "^#" | grep -v -E "' .. excluded_domain_str .. '"')
|
local gfwlist_str = sys.exec('cat /usr/share/passwall/rules/gfwlist | grep -v -E "^#" | grep -v -E "' .. excluded_domain_str .. '"')
|
||||||
for line in string.gmatch(gfwlist_str, "[^\r\n]+") do
|
for line in string.gmatch(gfwlist_str, "[^\r\n]+") do
|
||||||
if line ~= "" then
|
if line ~= "" then
|
||||||
local ipset_flag = setflag_4 .. "gfwlist," .. setflag_6 .. "gfwlist6"
|
local ipset_flag = setflag_4 .. "gfwlist," .. setflag_6 .. "gfwlist6"
|
||||||
if NO_PROXY_IPV6 == "1" then
|
if NO_PROXY_IPV6 == "1" then
|
||||||
ipset_flag = setflag_4 .. "gfwlist"
|
ipset_flag = setflag_4 .. "gfwlist"
|
||||||
set_domain_address(line, "::")
|
set_domain_address(line, "::")
|
||||||
end
|
end
|
||||||
if not only_global then
|
if not only_global then
|
||||||
fwd_dns = TUN_DNS
|
fwd_dns = TUN_DNS
|
||||||
if CHNROUTE_MODE_DEFAULT_DNS == "chinadns_ng" and CHINADNS_DNS ~= "0" then
|
if CHNROUTE_MODE_DEFAULT_DNS == "chinadns_ng" and CHINADNS_DNS ~= "0" then
|
||||||
fwd_dns = nil
|
fwd_dns = nil
|
||||||
end
|
end
|
||||||
if REMOTE_FAKEDNS == "1" then
|
if REMOTE_FAKEDNS == "1" then
|
||||||
ipset_flag = nil
|
ipset_flag = nil
|
||||||
end
|
end
|
||||||
set_domain_dns(line, fwd_dns)
|
set_domain_dns(line, fwd_dns)
|
||||||
set_domain_ipset(line, ipset_flag)
|
set_domain_ipset(line, ipset_flag)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
log(string.format(" - 防火墙域名表(gfwlist):%s", fwd_dns or "默认"))
|
log(string.format(" - 防火墙域名表(gfwlist):%s", fwd_dns or "默认"))
|
||||||
end
|
end
|
||||||
|
|
||||||
if chnlist and fs.access("/usr/share/passwall/rules/chnlist") and (CHNROUTE_MODE_DEFAULT_DNS == "remote" or (CHNROUTE_MODE_DEFAULT_DNS == "chinadns_ng" and CHINADNS_DNS ~= "0")) then
|
if chnlist and fs.access("/usr/share/passwall/rules/chnlist") and (CHNROUTE_MODE_DEFAULT_DNS == "remote" or (CHNROUTE_MODE_DEFAULT_DNS == "chinadns_ng" and CHINADNS_DNS ~= "0")) then
|
||||||
fwd_dns = LOCAL_DNS
|
fwd_dns = LOCAL_DNS
|
||||||
local chnlist_str = sys.exec('cat /usr/share/passwall/rules/chnlist | grep -v -E "^#" | grep -v -E "' .. excluded_domain_str .. '"')
|
local chnlist_str = sys.exec('cat /usr/share/passwall/rules/chnlist | grep -v -E "^#" | grep -v -E "' .. excluded_domain_str .. '"')
|
||||||
for line in string.gmatch(chnlist_str, "[^\r\n]+") do
|
for line in string.gmatch(chnlist_str, "[^\r\n]+") do
|
||||||
if line ~= "" then
|
if line ~= "" then
|
||||||
if CHNROUTE_MODE_DEFAULT_DNS == "chinadns_ng" and CHINADNS_DNS ~= "0" then
|
if CHNROUTE_MODE_DEFAULT_DNS == "chinadns_ng" and CHINADNS_DNS ~= "0" then
|
||||||
fwd_dns = nil
|
fwd_dns = nil
|
||||||
end
|
end
|
||||||
set_domain_dns(line, fwd_dns)
|
set_domain_dns(line, fwd_dns)
|
||||||
set_domain_ipset(line, setflag_4 .. "chnroute," .. setflag_6 .. "chnroute6")
|
set_domain_ipset(line, setflag_4 .. "chnroute," .. setflag_6 .. "chnroute6")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
log(string.format(" - 中国域名表(chnroute):%s", fwd_dns or "默认"))
|
log(string.format(" - 中国域名表(chnroute):%s", fwd_dns or "默认"))
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if fs.access("/usr/share/passwall/rules/chnlist") then
|
if fs.access("/usr/share/passwall/rules/chnlist") then
|
||||||
local chnlist_str = sys.exec('cat /usr/share/passwall/rules/chnlist | grep -v -E "^#" | grep -v -E "' .. excluded_domain_str .. '"')
|
local chnlist_str = sys.exec('cat /usr/share/passwall/rules/chnlist | grep -v -E "^#" | grep -v -E "' .. excluded_domain_str .. '"')
|
||||||
for line in string.gmatch(chnlist_str, "[^\r\n]+") do
|
for line in string.gmatch(chnlist_str, "[^\r\n]+") do
|
||||||
if line ~= "" then
|
if line ~= "" then
|
||||||
local ipset_flag = setflag_4 .. "chnroute," .. setflag_6 .. "chnroute6"
|
local ipset_flag = setflag_4 .. "chnroute," .. setflag_6 .. "chnroute6"
|
||||||
if NO_PROXY_IPV6 == "1" then
|
if NO_PROXY_IPV6 == "1" then
|
||||||
ipset_flag = setflag_4 .. "chnroute"
|
ipset_flag = setflag_4 .. "chnroute"
|
||||||
set_domain_address(line, "::")
|
set_domain_address(line, "::")
|
||||||
end
|
end
|
||||||
if not only_global then
|
if not only_global then
|
||||||
set_domain_dns(line, TUN_DNS)
|
set_domain_dns(line, TUN_DNS)
|
||||||
if REMOTE_FAKEDNS == "1" then
|
if REMOTE_FAKEDNS == "1" then
|
||||||
ipset_flag = nil
|
ipset_flag = nil
|
||||||
end
|
end
|
||||||
set_domain_ipset(line, ipset_flag)
|
set_domain_ipset(line, ipset_flag)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
log(string.format(" - 中国域名表(chnroute):%s", TUN_DNS or "默认"))
|
log(string.format(" - 中国域名表(chnroute):%s", TUN_DNS or "默认"))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local address_out = io.open(CACHE_DNS_PATH .. "/000-address.conf", "a")
|
local address_out = io.open(CACHE_DNS_PATH .. "/000-address.conf", "a")
|
||||||
local server_out = io.open(CACHE_DNS_PATH .. "/001-server.conf", "a")
|
local server_out = io.open(CACHE_DNS_PATH .. "/001-server.conf", "a")
|
||||||
local ipset_out = io.open(CACHE_DNS_PATH .. "/ipset.conf", "a")
|
local ipset_out = io.open(CACHE_DNS_PATH .. "/ipset.conf", "a")
|
||||||
local set_name = "ipset"
|
local set_name = "ipset"
|
||||||
if NFTFLAG == "1" then
|
if NFTFLAG == "1" then
|
||||||
set_name = "nftset"
|
set_name = "nftset"
|
||||||
end
|
end
|
||||||
for key, value in pairs(list1) do
|
for key, value in pairs(list1) do
|
||||||
if value.address and #value.address > 0 then
|
if value.address and #value.address > 0 then
|
||||||
address_out:write(string.format("address=/.%s/%s\n", key, value.address))
|
address_out:write(string.format("address=/.%s/%s\n", key, value.address))
|
||||||
end
|
end
|
||||||
if value.dns and #value.dns > 0 then
|
if value.dns and #value.dns > 0 then
|
||||||
for i, dns in ipairs(value.dns) do
|
for i, dns in ipairs(value.dns) do
|
||||||
server_out:write(string.format("server=/.%s/%s\n", key, dns))
|
server_out:write(string.format("server=/.%s/%s\n", key, dns))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if value.ipsets and #value.ipsets > 0 then
|
if value.ipsets and #value.ipsets > 0 then
|
||||||
local ipsets_str = ""
|
local ipsets_str = ""
|
||||||
for i, ipset in ipairs(value.ipsets) do
|
for i, ipset in ipairs(value.ipsets) do
|
||||||
ipsets_str = ipsets_str .. ipset .. ","
|
ipsets_str = ipsets_str .. ipset .. ","
|
||||||
end
|
end
|
||||||
ipsets_str = ipsets_str:sub(1, #ipsets_str - 1)
|
ipsets_str = ipsets_str:sub(1, #ipsets_str - 1)
|
||||||
ipset_out:write(string.format("%s=/.%s/%s\n", set_name, key, ipsets_str))
|
ipset_out:write(string.format("%s=/.%s/%s\n", set_name, key, ipsets_str))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
address_out:close()
|
address_out:close()
|
||||||
server_out:close()
|
server_out:close()
|
||||||
ipset_out:close()
|
ipset_out:close()
|
||||||
|
|
||||||
local f_out = io.open(CACHE_TEXT_FILE, "a")
|
local f_out = io.open(CACHE_TEXT_FILE, "a")
|
||||||
f_out:write(new_text)
|
f_out:write(new_text)
|
||||||
f_out:close()
|
f_out:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
if api.is_install("procd\\-ujail") then
|
if api.is_install("procd\\-ujail") then
|
||||||
fs.copyr(CACHE_DNS_PATH, TMP_DNSMASQ_PATH)
|
fs.copyr(CACHE_DNS_PATH, TMP_DNSMASQ_PATH)
|
||||||
else
|
else
|
||||||
api.remove(TMP_DNSMASQ_PATH)
|
api.remove(TMP_DNSMASQ_PATH)
|
||||||
fs.symlink(CACHE_DNS_PATH, TMP_DNSMASQ_PATH)
|
fs.symlink(CACHE_DNS_PATH, TMP_DNSMASQ_PATH)
|
||||||
end
|
end
|
||||||
|
|
||||||
if DNSMASQ_CONF_FILE ~= "nil" then
|
if DNSMASQ_CONF_FILE ~= "nil" then
|
||||||
local conf_out = io.open(DNSMASQ_CONF_FILE, "a")
|
local conf_out = io.open(DNSMASQ_CONF_FILE, "a")
|
||||||
conf_out:write(string.format("conf-dir=%s\n", TMP_DNSMASQ_PATH))
|
conf_out:write(string.format("conf-dir=%s\n", TMP_DNSMASQ_PATH))
|
||||||
if dnsmasq_default_dns then
|
if dnsmasq_default_dns then
|
||||||
conf_out:write(string.format("server=%s\n", dnsmasq_default_dns))
|
conf_out:write(string.format("server=%s\n", dnsmasq_default_dns))
|
||||||
conf_out:write("all-servers\n")
|
conf_out:write("all-servers\n")
|
||||||
conf_out:write("no-poll\n")
|
conf_out:write("no-poll\n")
|
||||||
conf_out:write("no-resolv\n")
|
conf_out:write("no-resolv\n")
|
||||||
conf_out:close()
|
conf_out:close()
|
||||||
log(string.format(" - 以上所列以外及默认:%s", dnsmasq_default_dns))
|
log(string.format(" - 以上所列以外及默认:%s", dnsmasq_default_dns))
|
||||||
|
|
||||||
if FLAG == "default" then
|
if FLAG == "default" then
|
||||||
local f_out = io.open("/tmp/etc/passwall/default_DNS", "a")
|
local f_out = io.open("/tmp/etc/passwall/default_DNS", "a")
|
||||||
f_out:write(DEFAULT_DNS)
|
f_out:write(DEFAULT_DNS)
|
||||||
f_out:close()
|
f_out:close()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
log(" - PassWall必须依赖于Dnsmasq,如果你自行配置了错误的DNS流程,将会导致域名(直连/代理域名)分流失效!!!")
|
log(" - PassWall必须依赖于Dnsmasq,如果你自行配置了错误的DNS流程,将会导致域名(直连/代理域名)分流失效!!!")
|
||||||
|
@ -35,18 +35,18 @@ local geosite_api = "https://api.github.com/repos/Loyalsoldier/v2ray-rules-dat/
|
|||||||
local v2ray_asset_location = ucic:get_first(name, 'global_rules', "v2ray_location_asset", "/usr/share/v2ray/")
|
local v2ray_asset_location = ucic:get_first(name, 'global_rules', "v2ray_location_asset", "/usr/share/v2ray/")
|
||||||
|
|
||||||
local log = function(...)
|
local log = function(...)
|
||||||
if arg1 then
|
if arg1 then
|
||||||
local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
|
local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
|
||||||
if arg1 == "log" then
|
if arg1 == "log" then
|
||||||
local f, err = io.open("/tmp/log/passwall.log", "a")
|
local f, err = io.open("/tmp/log/passwall.log", "a")
|
||||||
if f and err == nil then
|
if f and err == nil then
|
||||||
f:write(result .. "\n")
|
f:write(result .. "\n")
|
||||||
f:close()
|
f:close()
|
||||||
end
|
end
|
||||||
elseif arg1 == "print" then
|
elseif arg1 == "print" then
|
||||||
print(result)
|
print(result)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
-- curl
|
-- curl
|
||||||
|
Loading…
Reference in New Issue
Block a user