From e96a344a612e5cac82f1ee678ab1a3eb7ccfc58f Mon Sep 17 00:00:00 2001
From: pover0k <171932393+pover0k@users.noreply.github.com>
Date: Sat, 31 Jan 2026 11:32:11 +0000
Subject: [PATCH] luci-app-passwall: bump to 26.1.30
---
applications/luci-app-passwall/Makefile | 2 +-
.../luasrc/controller/passwall.lua | 80 +++-
.../model/cbi/passwall/client/acl_config.lua | 30 +-
.../model/cbi/passwall/client/global.lua | 251 +++----------
.../luasrc/model/cbi/passwall/client/rule.lua | 4 +-
.../cbi/passwall/client/shunt_config.lua | 265 +++++++++++++
.../model/cbi/passwall/client/type/ray.lua | 175 ++-------
.../cbi/passwall/client/type/sing-box.lua | 153 ++------
.../model/cbi/passwall/server/type/ray.lua | 2 +-
.../luasrc/passwall/util_hysteria2.lua | 36 +-
.../luasrc/passwall/util_naiveproxy.lua | 20 +-
.../luasrc/passwall/util_shadowsocks.lua | 50 +--
.../luasrc/passwall/util_sing-box.lua | 112 +++---
.../luasrc/passwall/util_trojan.lua | 28 +-
.../luasrc/passwall/util_tuic.lua | 24 +-
.../luasrc/passwall/util_xray.lua | 106 +++---
.../view/passwall/cbi/nodes_listvalue.htm | 4 +-
.../view/passwall/cbi/nodes_listvalue_com.htm | 20 +
.../view/passwall/cbi/nodes_multivalue.htm | 3 +-
.../luasrc/view/passwall/cbi/nodes_value.htm | 4 +-
.../view/passwall/cbi/nodes_value_com.htm | 20 +
.../luasrc/view/passwall/global/footer.htm | 71 ++--
.../view/passwall/node_config/footer.htm | 22 +-
.../view/passwall/node_list/link_add_node.htm | 1 +
.../view/passwall/node_list/node_list.htm | 10 +-
.../view/passwall/rule/rule_version.htm | 52 ++-
.../luci-app-passwall/po/zh_Hans/passwall.po | 44 ++-
.../root/usr/share/passwall/app.sh | 347 ++++++++++++------
.../share/passwall/helper_chinadns_add.lua | 9 +-
.../usr/share/passwall/helper_dnsmasq.lua | 7 +-
.../share/passwall/helper_smartdns_add.lua | 9 +-
.../root/usr/share/passwall/rule_update.lua | 69 ++--
32 files changed, 1156 insertions(+), 874 deletions(-)
create mode 100644 applications/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_config.lua
diff --git a/applications/luci-app-passwall/Makefile b/applications/luci-app-passwall/Makefile
index 44ae9427058..19079f4fa3c 100644
--- a/applications/luci-app-passwall/Makefile
+++ b/applications/luci-app-passwall/Makefile
@@ -7,7 +7,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
-PKG_VERSION:=26.1.25
+PKG_VERSION:=26.1.30
PKG_RELEASE:=1
PKG_CONFIG_DEPENDS:= \
diff --git a/applications/luci-app-passwall/luasrc/controller/passwall.lua b/applications/luci-app-passwall/luasrc/controller/passwall.lua
index cc50ae8c9e1..33af58ba0ca 100644
--- a/applications/luci-app-passwall/luasrc/controller/passwall.lua
+++ b/applications/luci-app-passwall/luasrc/controller/passwall.lua
@@ -49,6 +49,7 @@ function index()
entry({"admin", "services", appname, "node_subscribe_config"}, cbi(appname .. "/client/node_subscribe_config")).leaf = true
entry({"admin", "services", appname, "node_config"}, cbi(appname .. "/client/node_config")).leaf = true
entry({"admin", "services", appname, "shunt_rules"}, cbi(appname .. "/client/shunt_rules")).leaf = true
+ entry({"admin", "services", appname, "shunt_config"}, cbi(appname .. "/client/shunt_config")).leaf = true
entry({"admin", "services", appname, "socks_config"}, cbi(appname .. "/client/socks_config")).leaf = true
entry({"admin", "services", appname, "acl"}, cbi(appname .. "/client/acl"), _("Access control"), 98).leaf = true
entry({"admin", "services", appname, "acl_config"}, cbi(appname .. "/client/acl_config")).leaf = true
@@ -83,6 +84,7 @@ function index()
entry({"admin", "services", appname, "update_node"}, call("update_node")).leaf = true
entry({"admin", "services", appname, "set_node"}, call("set_node")).leaf = true
entry({"admin", "services", appname, "copy_node"}, call("copy_node")).leaf = true
+ entry({"admin", "services", appname, "edit_node"}, call("edit_node")).leaf = true
entry({"admin", "services", appname, "clear_all_nodes"}, call("clear_all_nodes")).leaf = true
entry({"admin", "services", appname, "delete_select_nodes"}, call("delete_select_nodes")).leaf = true
entry({"admin", "services", appname, "reassign_group"}, call("reassign_group")).leaf = true
@@ -90,6 +92,7 @@ function index()
entry({"admin", "services", appname, "save_node_order"}, call("save_node_order")).leaf = true
entry({"admin", "services", appname, "save_node_list_opt"}, call("save_node_list_opt")).leaf = true
entry({"admin", "services", appname, "update_rules"}, call("update_rules")).leaf = true
+ entry({"admin", "services", appname, "rollback_rules"}, call("rollback_rules")).leaf = true
entry({"admin", "services", appname, "subscribe_del_node"}, call("subscribe_del_node")).leaf = true
entry({"admin", "services", appname, "subscribe_del_all"}, call("subscribe_del_all")).leaf = true
entry({"admin", "services", appname, "subscribe_manual"}, call("subscribe_manual")).leaf = true
@@ -414,6 +417,7 @@ function urltest_node()
end
function add_node()
+ local protocol = http.formvalue("protocol") or ""
local redirect = http.formvalue("redirect")
local uuid = api.gen_short_uuid()
@@ -424,11 +428,19 @@ function add_node()
uci:set(appname, uuid, "group", group)
end
- uci:set(appname, uuid, "type", "Xray")
+ if protocol == "shunt" then
+ uci:set(appname, uuid, "protocol", "_shunt")
+ else
+ uci:set(appname, uuid, "type", "Socks")
+ end
if redirect == "1" then
api.uci_save(uci, appname)
- http.redirect(api.url("node_config", uuid))
+ if protocol == "shunt" then
+ http.redirect(api.url("shunt_config", uuid))
+ else
+ http.redirect(api.url("node_config", uuid))
+ end
else
api.uci_save(uci, appname, true, true)
http_write_json({result = uuid})
@@ -495,6 +507,16 @@ function copy_node()
http.redirect(api.url("node_config", uuid))
end
+function edit_node()
+ local section = http.formvalue("section")
+ local protocol = uci:get(appname, section, "protocol")
+ if protocol == "_shunt" then
+ http.redirect(api.url("shunt_config", section))
+ else
+ http.redirect(api.url("node_config", section))
+ end
+end
+
function clear_all_nodes()
uci:set(appname, '@global[0]', "enabled", "0")
uci:set(appname, '@global[0]', "socks_enabled", "0")
@@ -702,6 +724,24 @@ function update_rules()
http_write_json()
end
+function rollback_rules()
+ local arg_type = http.formvalue("type")
+ local rules = http.formvalue("rules") or ""
+ if arg_type ~= "geoip" and arg_type ~= "geosite" then
+ http_write_json_error()
+ return
+ end
+ local bak_dir = "/tmp/bak_v2ray/"
+ local geo_dir = (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/")
+ local geo2rule = uci:get(appname, "@global_rules[0]", "geo2rule") or "0"
+ fs.move(bak_dir .. arg_type .. ".dat", geo_dir .. arg_type .. ".dat")
+ fs.rmdir(bak_dir)
+ if geo2rule == "1" and rules ~= "" then
+ luci.sys.call("lua /usr/share/passwall/rule_update.lua log '" .. rules .. "' rollback > /dev/null")
+ end
+ http_write_json_ok()
+end
+
function server_user_status()
local e = {}
e.index = http.formvalue("index")
@@ -864,6 +904,25 @@ function geo_view()
http.write(i18n.translate("Please enter query content!"))
return
end
+ local function get_rules(str, type)
+ local remarks = {}
+ uci:foreach(appname, "shunt_rules", function(s)
+ local list
+ if type == "geoip" then list = s.ip_list else list = s.domain_list end
+ for line in string.gmatch((list or ""), "[^\r\n]+") do
+ if line ~= "" and not line:find("#") then
+ local prefix, main = line:match("^(.-):(.*)")
+ if not main then main = line end
+ if type == "geoip" and (api.datatypes.ipaddr(str) or api.datatypes.ip6addr(str)) then
+ if main:find(str, 1, true) and s.remarks then remarks[#remarks + 1] = s.remarks end
+ else
+ if main == str and s.remarks then remarks[#remarks + 1] = s.remarks end
+ end
+ end
+ end
+ end)
+ return remarks
+ end
local geo_dir = (uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"):match("^(.*)/")
local geosite_path = geo_dir .. "/geosite.dat"
local geoip_path = geo_dir .. "/geoip.dat"
@@ -878,13 +937,22 @@ function geo_view()
cmd = string.format("geoview -type %s -action lookup -input '%s' -value '%s' -lowmem=true", geo_type, file_path, value)
geo_string = luci.sys.exec(cmd):lower()
if geo_string ~= "" then
- local lines = {}
- for line in geo_string:gmatch("([^\n]*)\n?") do
- if line ~= "" then
- table.insert(lines, geo_type .. ":" .. line)
+ local lines, rules, seen = {}, {}, {}
+ for line in geo_string:gmatch("([^\n]+)") do
+ lines[#lines + 1] = geo_type .. ":" .. line
+ for _, r in ipairs(get_rules(line, geo_type) or {}) do
+ if not seen[r] then seen[r] = true; rules[#rules + 1] = r end
end
end
+ for _, r in ipairs(get_rules(value, geo_type) or {}) do
+ if not seen[r] then seen[r] = true; rules[#rules + 1] = r end
+ end
geo_string = table.concat(lines, "\n")
+ if #rules > 0 then
+ geo_string = geo_string .. "\n--------------------\n"
+ geo_string = geo_string .. i18n.translate("Rules containing this value:") .. "\n"
+ geo_string = geo_string .. table.concat(rules, "\n")
+ end
end
elseif action == "extract" then
local prefix, list = value:match("^(geoip:)(.*)$")
diff --git a/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua b/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua
index 435390ce041..78ec4683d93 100644
--- a/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua
+++ b/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/acl_config.lua
@@ -209,6 +209,10 @@ o.default = ""
o:depends({ _hide_node_option = false, use_global_config = false })
o.template = appname .. "/cbi/nodes_listvalue"
o.group = {}
+o.remove = function(self, section)
+ m:del(section, self.option)
+ m:del(section, "udp_node")
+end
o = s:option(DummyValue, "_tcp_node_bool", "")
o.template = "passwall/cbi/hidevalue"
@@ -219,14 +223,36 @@ o = s:option(ListValue, "udp_node", "" .. translate("UDP N
o.default = ""
o:value("", translate("Close"))
o:value("tcp", translate("Same as the tcp node"))
-o:depends({ _tcp_node_bool = "1" })
+o:depends({ _tcp_node_bool = "1", _node_sel_other = "1" })
o.template = appname .. "/cbi/nodes_listvalue"
o.group = {"",""}
+o.remove = function(self, section)
+ local v = s.fields["shunt_udp_node"]:formvalue(section)
+ if not f then
+ return m:del(section, self.option)
+ end
+end
+
+o = s:option(ListValue, "shunt_udp_node", "" .. translate("UDP Node") .. "")
+o:value("close", translate("Close"))
+o:value("tcp", translate("Same as the tcp node"))
+o:depends({ _tcp_node_bool = "1", _node_sel_shunt = "1" })
+o.cfgvalue = function(self, section)
+ local v = m:get(section, "udp_node") or ""
+ if v == "" then v = "close" end
+ if v ~= "close" and v ~= "tcp" then v = "tcp" end
+ return v
+end
+o.write = function(self, section, value)
+ if value == "close" then value = "" end
+ return m:set(section, "udp_node", value)
+end
o = s:option(DummyValue, "_udp_node_bool", "")
o.template = "passwall/cbi/hidevalue"
o.value = "1"
o:depends({ udp_node = "", ['!reverse'] = true })
+o:depends({ shunt_udp_node = "tcp" })
---- TCP Proxy Drop Ports
local TCP_PROXY_DROP_PORTS = m:get("@global_forwarding[0]", "tcp_proxy_drop_ports")
@@ -471,7 +497,7 @@ o:depends({dns_mode = "sing-box"})
o:depends({dns_mode = "xray"})
o:depends({_node_sel_shunt = "1"})
-o = s:option(Flag, "remote_fakedns", "FakeDNS", translate("Use FakeDNS work in the shunt domain that proxy."))
+o = s:option(Flag, "remote_fakedns", "FakeDNS", translate("Use FakeDNS work in the domain that proxy."))
o.default = "0"
o.rmempty = false
o:depends({dns_mode = "sing-box"})
diff --git a/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua b/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua
index 181688f7207..bb840acea35 100644
--- a/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua
+++ b/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua
@@ -95,8 +95,6 @@ end
m:append(Template(appname .. "/global/status"))
-local global_cfgid = m:get("@global[0]")[".name"]
-
s = m:section(TypedSection, "global")
s.anonymous = true
s.addremove = false
@@ -119,208 +117,36 @@ o.template = appname .. "/cbi/nodes_listvalue"
o:value("", translate("Close"))
o:value("tcp", translate("Same as the tcp node"))
o.group = {"",""}
+o:depends("_node_sel_other", "1")
+o.remove = function(self, section)
+ local v = s.fields["shunt_udp_node"]:formvalue(section)
+ if not f then
+ return m:del(section, self.option)
+ end
+end
-local tcp_node_id = m.uci:get(appname, global_cfgid, "tcp_node")
-local tcp_node = tcp_node_id and m.uci:get_all(appname, tcp_node_id) or {}
-
--- 分流
-if (has_singbox or has_xray) and #nodes_table > 0 then
- if #normal_list > 0 and tcp_node.protocol == "_shunt" then
- local v = tcp_node
- if v then
- local function get_cfgvalue(shunt_node_id, option)
- return function(self, section)
- return m:get(shunt_node_id, option)
- end
- end
- local function get_write(shunt_node_id, option)
- return function(self, section, value)
- if s.fields["tcp_node"]:formvalue(section) == shunt_node_id then
- m:set(shunt_node_id, option, value)
- end
- end
- end
- local function get_remove(shunt_node_id, option)
- return function(self, section)
- if s.fields["tcp_node"]:formvalue(section) == shunt_node_id then
- m:del(shunt_node_id, option)
- end
- end
- end
- v.id = v[".name"]
- local vid = v.id
- -- shunt node type, Sing-Box or Xray
- o = s:taboption("Main", ListValue, vid .. "-type", translate("Type"))
- if has_xray then
- o:value("Xray", translate("Xray"))
- end
- if has_singbox then
- o:value("sing-box", "Sing-Box")
- end
- o:depends("tcp_node", v.id)
- o.cfgvalue = get_cfgvalue(v.id, "type")
- o.write = get_write(v.id, "type")
-
- -- pre-proxy
- o = s:taboption("Main", Flag, vid .. "-preproxy_enabled", translate("Preproxy"))
- o:depends("tcp_node", v.id)
- o.rmempty = false
- o.cfgvalue = get_cfgvalue(v.id, "preproxy_enabled")
- o.write = get_write(v.id, "preproxy_enabled")
-
- o = s:taboption("Main", ListValue, vid .. "-main_node", string.format('%s', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including Default) has a separate switch that controls whether this rule uses the pre-proxy or not."))
- o:depends(vid .. "-preproxy_enabled", "1")
- o.template = appname .. "/cbi/nodes_listvalue"
- o.group = {}
- for k1, v1 in pairs(socks_list) do
- o:value(v1.id, v1.remark)
- o.group[#o.group+1] = (v1.group and v1.group ~= "") and v1.group or translate("default")
- end
- for k1, v1 in pairs(balancing_list) do
- o:value(v1.id, v1.remark)
- o.group[#o.group+1] = (v1.group and v1.group ~= "") and v1.group or translate("default")
- end
- for k1, v1 in pairs(urltest_list) do
- o:value(v1.id, v1.remark)
- o.group[#o.group+1] = (v1.group and v1.group ~= "") and v1.group or translate("default")
- end
- for k1, v1 in pairs(iface_list) do
- o:value(v1.id, v1.remark)
- o.group[#o.group+1] = (v1.group and v1.group ~= "") and v1.group or translate("default")
- end
- for k1, v1 in pairs(normal_list) do
- o:value(v1.id, v1.remark)
- o.group[#o.group+1] = (v1.group and v1.group ~= "") and v1.group or translate("default")
- end
- o.cfgvalue = get_cfgvalue(v.id, "main_node")
- o.write = get_write(v.id, "main_node")
-
- o = s:taboption("Main", Flag, vid .. "-fakedns", "FakeDNS", translate("Use FakeDNS work in the shunt domain that proxy."))
- o:depends("tcp_node", v.id)
- o.cfgvalue = get_cfgvalue(v.id, "fakedns")
- o.write = get_write(v.id, "fakedns")
- o.remove = get_remove(v.id, "fakedns")
-
- m.uci:foreach(appname, "shunt_rules", function(e)
- local id = e[".name"]
- local node_option = vid .. "-" .. id .. "_node"
- if id and e.remarks then
- o = s:taboption("Main", ListValue, node_option, string.format('* %s', api.url("shunt_rules", id), e.remarks))
- o.cfgvalue = get_cfgvalue(v.id, id)
- o.write = get_write(v.id, id)
- o.remove = get_remove(v.id, id)
- o:depends("tcp_node", v.id)
- o:value("", translate("Close"))
- o:value("_default", translate("Default"))
- o:value("_direct", translate("Direct Connection"))
- o:value("_blackhole", translate("Blackhole"))
- o.template = appname .. "/cbi/nodes_listvalue"
- o.group = {"","","",""}
-
- local pt = s:taboption("Main", ListValue, vid .. "-".. id .. "_proxy_tag", string.format('* %s', e.remarks .. " " .. translate("Preproxy")))
- pt.cfgvalue = get_cfgvalue(v.id, id .. "_proxy_tag")
- pt.write = get_write(v.id, id .. "_proxy_tag")
- pt.remove = get_remove(v.id, id .. "_proxy_tag")
- pt:value("", translate("Close"))
- pt:value("main", translate("Preproxy Node"))
- pt:depends("__hide__", "1")
-
- local fakedns_tag = s:taboption("Main", Flag, vid .. "-".. id .. "_fakedns", string.format('* %s', e.remarks .. " " .. "FakeDNS"))
- fakedns_tag.cfgvalue = get_cfgvalue(v.id, id .. "_fakedns")
- fakedns_tag.write = get_write(v.id, id .. "_fakedns")
- fakedns_tag.remove = get_remove(v.id, id .. "_fakedns")
-
- for k1, v1 in pairs(socks_list) do
- o:value(v1.id, v1.remark)
- o.group[#o.group+1] = (v1.group and v1.group ~= "") and v1.group or translate("default")
- fakedns_tag:depends({ [node_option] = v1.id, [vid .. "-fakedns"] = "1" })
- end
- for k1, v1 in pairs(balancing_list) do
- o:value(v1.id, v1.remark)
- o.group[#o.group+1] = (v1.group and v1.group ~= "") and v1.group or translate("default")
- end
- for k1, v1 in pairs(urltest_list) do
- o:value(v1.id, v1.remark)
- o.group[#o.group+1] = (v1.group and v1.group ~= "") and v1.group or translate("default")
- end
- for k1, v1 in pairs(iface_list) do
- o:value(v1.id, v1.remark)
- o.group[#o.group+1] = (v1.group and v1.group ~= "") and v1.group or translate("default")
- end
- for k1, v1 in pairs(normal_list) do
- o:value(v1.id, v1.remark)
- o.group[#o.group+1] = (v1.group and v1.group ~= "") and v1.group or translate("default")
- if not api.is_local_ip(v1.address) then --本地节点禁止使用前置
- pt:depends({ [node_option] = v1.id, [vid .. "-preproxy_enabled"] = "1" })
- end
- fakedns_tag:depends({ [node_option] = v1.id, [vid .. "-fakedns"] = "1" })
- end
- if v.default_node ~= "_direct" or v.default_node ~= "_blackhole" then
- fakedns_tag:depends({ [node_option] = "_default", [vid .. "-fakedns"] = "1" })
- end
- end
- end)
-
- local id = "default_node"
- o = s:taboption("Main", ListValue, vid .. "-" .. id, string.format('* %s', translate("Default")))
- o.cfgvalue = get_cfgvalue(v.id, id)
- o.write = get_write(v.id, id)
- o.remove = get_remove(v.id, id)
- o:depends("tcp_node", v.id)
- o:value("_direct", translate("Direct Connection"))
- o:value("_blackhole", translate("Blackhole"))
- o.template = appname .. "/cbi/nodes_listvalue"
- o.group = {"",""}
- for k1, v1 in pairs(socks_list) do
- o:value(v1.id, v1.remark)
- o.group[#o.group+1] = (v1.group and v1.group ~= "") and v1.group or translate("default")
- end
- for k1, v1 in pairs(balancing_list) do
- o:value(v1.id, v1.remark)
- o.group[#o.group+1] = (v1.group and v1.group ~= "") and v1.group or translate("default")
- end
- for k1, v1 in pairs(urltest_list) do
- o:value(v1.id, v1.remark)
- o.group[#o.group+1] = (v1.group and v1.group ~= "") and v1.group or translate("default")
- end
- for k1, v1 in pairs(iface_list) do
- o:value(v1.id, v1.remark)
- o.group[#o.group+1] = (v1.group and v1.group ~= "") and v1.group or translate("default")
- end
- for k1, v1 in pairs(normal_list) do
- o:value(v1.id, v1.remark)
- o.group[#o.group+1] = (v1.group and v1.group ~= "") and v1.group or translate("default")
- end
+o = s:taboption("Main", ListValue, "shunt_udp_node", "" .. translate("UDP Node") .. "")
+o:value("close", translate("Close"))
+o:value("tcp", translate("Same as the tcp node"))
+o:depends("_node_sel_shunt", "1")
+o.cfgvalue = function(self, section)
+ local v = m:get(section, "udp_node") or ""
+ if v == "" then v = "close" end
+ if v ~= "close" and v ~= "tcp" then v = "tcp" end
+ return v
+end
+o.write = function(self, section, value)
+ if value == "close" then value = "" end
+ return m:set(section, "udp_node", value)
+end
- local id = "default_proxy_tag"
- o = s:taboption("Main", ListValue, vid .. "-" .. id, string.format('* %s', translate("Default Preproxy")), translate("When using, localhost will connect this node first and then use this node to connect the default node."))
- o.cfgvalue = get_cfgvalue(v.id, id)
- o.write = get_write(v.id, id)
- o.remove = get_remove(v.id, id)
- o:value("", translate("Close"))
- o:value("main", translate("Preproxy Node"))
- o:depends("__hide__", "1")
- for k1, v1 in pairs(normal_list) do
- if v1.protocol ~= "_balancing" and v1.protocol ~= "_urltest" and not api.is_local_ip(v1.address) then
- o:depends({ [vid .. "-default_node"] = v1.id, [vid .. "-preproxy_enabled"] = "1" })
- end
- end
- end
- else
- local tips = s:taboption("Main", DummyValue, "tips", " ")
- tips.rawhtml = true
- tips.cfgvalue = function(t, n)
- return string.format('%s', translate("There are no available nodes, please add or subscribe nodes first."))
- end
- tips:depends({ tcp_node = "", ["!reverse"] = true })
- for k, v in pairs(shunt_list) do
- tips:depends("udp_node", v.id)
- end
- for k, v in pairs(balancing_list) do
- tips:depends("udp_node", v.id)
- end
- end
+o = s:taboption("Main", DummyValue, "shunt_tips", " ")
+o.rawhtml = true
+o.cfgvalue = function(t, n)
+ return string.format('%s',
+ translate("To modify the shunt policy, click the Edit button."))
end
+o:depends("_node_sel_shunt", "1")
o = s:taboption("Main", Value, "tcp_node_socks_port", translate("TCP Node") .. " Socks " .. translate("Listen Port"))
o.default = 1070
@@ -387,10 +213,14 @@ o.default = "0"
-- TCP分流时dns过滤模式保存逻辑
function dns_mode_save(section)
- for k, v in pairs(shunt_list) do
- local f = s.fields[v.id .. "-type"]
- if f then
- local type_val = f:formvalue(section)
+ local f = s.fields["tcp_node"]
+ local id_val = f and f:formvalue(section) or ""
+ if id_val == "" then
+ return
+ end
+ for _, v in pairs(shunt_list) do
+ if v.id == id_val then
+ local type_val = v.type
if type_val and (type_val == "Xray" or type_val == "sing-box") then
local dns_shunt_val = s.fields["dns_shunt"]:formvalue(section)
local dns_mode_val = (dns_shunt_val ~= "smartdns") and "dns_mode" or "smartdns_dns_mode"
@@ -590,7 +420,7 @@ o:depends({dns_mode = "xray"})
o:depends("dns_shunt", "smartdns")
o:depends("_node_sel_shunt", "1")
-o = s:taboption("DNS", Flag, "remote_fakedns", "FakeDNS", translate("Use FakeDNS work in the shunt domain that proxy."))
+o = s:taboption("DNS", Flag, "remote_fakedns", "FakeDNS", translate("Use FakeDNS work in the domain that proxy."))
o.default = "0"
o:depends({dns_mode = "sing-box", dns_shunt = "dnsmasq"})
o:depends({dns_mode = "sing-box", dns_shunt = "chinadns-ng"})
@@ -928,8 +758,11 @@ for k, v in pairs(nodes_table) do
udp.group[#udp.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
s.fields["_node_sel_shunt"]:depends({ tcp_node = v.id })
- s.fields["xray_dns_mode"]:depends({ [v.id .. "-type"] = "Xray", _node_sel_shunt = "1" })
- s.fields["singbox_dns_mode"]:depends({ [v.id .. "-type"] = "sing-box", _node_sel_shunt = "1" })
+ if m:get(v.id, "type") == "Xray" then
+ s.fields["xray_dns_mode"]:depends({ tcp_node = v.id })
+ else
+ s.fields["singbox_dns_mode"]:depends({ tcp_node = v.id })
+ end
end
else
tcp:value(v.id, v["remark"])
@@ -950,8 +783,6 @@ end
local footer = Template(appname .. "/global/footer")
footer.api = api
-footer.global_cfgid = global_cfgid
-footer.shunt_list = api.jsonc.stringify(shunt_list)
m:append(footer)
return m
diff --git a/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua b/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua
index 9bdf13292fc..fa5d6d87fbf 100644
--- a/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua
+++ b/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua
@@ -52,14 +52,14 @@ o:value("https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/google
o:value("https://cdn.jsdelivr.net/gh/blackmatrix7/ios_rule_script@master/rule/Clash/ChinaMax/ChinaMax_Domain.txt", translate("ios_rule_script/ChinaMax_Domain"))
if has_xray or has_singbox then
- o = s:option(ListValue, "geoip_url", translate("GeoIP Update URL"))
+ o = s:option(Value, "geoip_url", translate("GeoIP Update URL"))
o:value("https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip.dat", translate("Loyalsoldier/geoip"))
o:value("https://github.com/MetaCubeX/meta-rules-dat/releases/latest/download/geoip.dat", translate("MetaCubeX/geoip"))
o:value("https://cdn.jsdelivr.net/gh/Loyalsoldier/geoip@release/geoip.dat", translate("Loyalsoldier/geoip (CDN)"))
o:value("https://cdn.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.dat", translate("MetaCubeX/geoip (CDN)"))
o.default = o.keylist[1]
- o = s:option(ListValue, "geosite_url", translate("Geosite Update URL"))
+ o = s:option(Value, "geosite_url", translate("Geosite Update URL"))
o:value("https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat", translate("Loyalsoldier/geosite"))
o:value("https://github.com/MetaCubeX/meta-rules-dat/releases/latest/download/geosite.dat", translate("MetaCubeX/geosite"))
o:value("https://cdn.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/geosite.dat", translate("Loyalsoldier/geosite (CDN)"))
diff --git a/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_config.lua b/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_config.lua
new file mode 100644
index 00000000000..b810f5e74e5
--- /dev/null
+++ b/applications/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_config.lua
@@ -0,0 +1,265 @@
+local api = require "luci.passwall.api"
+local appname = api.appname
+local has_singbox = api.finded_com("sing-box")
+local has_xray = api.finded_com("xray")
+
+m = Map(appname, translate("Shunt Policy Config"))
+m.redirect = api.url("node_list")
+api.set_apply_on_parse(m)
+
+if not arg[1] or not m:get(arg[1]) then
+ luci.http.redirect(m.redirect)
+end
+
+m:append(Template(appname .. "/cbi/nodes_listvalue_com"))
+
+s = m:section(NamedSection, arg[1], "nodes", "")
+s.addremove = false
+s.dynamic = false
+
+local nodes_table = {}
+local iface_table = {}
+local balancers_table = {}
+local urltest_table = {}
+for k, e in ipairs(api.get_valid_nodes()) do
+ if e.node_type == "normal" then
+ nodes_table[#nodes_table + 1] = {
+ id = e[".name"],
+ remark = e["remark"],
+ type = e["type"],
+ address = e["address"],
+ chain_proxy = e["chain_proxy"],
+ group = e["group"]
+ }
+ end
+ if e.protocol == "_iface" then
+ iface_table[#iface_table + 1] = {
+ id = e[".name"],
+ remark = e["remark"],
+ group = e["group"]
+ }
+ end
+ if e.protocol == "_balancing" then
+ balancers_table[#balancers_table + 1] = {
+ id = e[".name"],
+ remark = e["remark"],
+ group = e["group"]
+ }
+ end
+ if e.protocol == "_urltest" then
+ urltest_table[#urltest_table + 1] = {
+ id = e[".name"],
+ remark = e["remark"],
+ group = e["group"]
+ }
+ end
+end
+
+local socks_list = {}
+m.uci:foreach(appname, "socks", function(s)
+ if s.enabled == "1" and s.node then
+ socks_list[#socks_list + 1] = {
+ id = "Socks_" .. s[".name"],
+ remark = translate("Socks Config") .. " " .. string.format("[%s %s]", s.port, translate("Port")),
+ group = "Socks"
+ }
+ end
+end)
+
+o = s:option(Value, "remarks", translate("Node Remarks"))
+o.default = translate("Remarks")
+o.rmempty = false
+
+o = s:option(Value, "group", translate("Group Name"))
+o.default = ""
+o:value("", translate("default"))
+local groups = {}
+m.uci:foreach(appname, "nodes", function(s)
+ if s[".name"] ~= arg[1] then
+ if s.group and s.group ~= "" then
+ groups[s.group] = true
+ end
+ end
+end)
+for k, v in pairs(groups) do
+ o:value(k)
+end
+o.write = function(self, section, value)
+ value = api.trim(value)
+ local lower = value:lower()
+
+ if lower == "" or lower == "default" then
+ return m:del(section, self.option)
+ end
+
+ for _, v in ipairs(self.keylist or {}) do
+ if v:lower() == lower then
+ return m:set(section, self.option, v)
+ end
+ end
+ m:set(section, self.option, value)
+end
+
+local default_node = m.uci:get(appname, arg[1], "default_node") or "_direct"
+-- [[ 分流模块 ]]
+if #nodes_table > 0 then
+ local type = s:option(ListValue, "type", translate("Type"))
+ if has_xray then
+ type:value("Xray", translate("Xray"))
+ end
+ if has_singbox then
+ type:value("sing-box", translate("Sing-Box"))
+ end
+
+ o = s:option(Flag, "preproxy_enabled", translate("Preproxy"))
+
+ o = s:option(ListValue, "main_node", translate("Preproxy Node"), translate("Set the node to be used as a pre-proxy. Each rule (including Default) has a separate switch that controls whether this rule uses the pre-proxy or not."))
+ o:depends({ ["preproxy_enabled"] = true })
+ o.template = appname .. "/cbi/nodes_listvalue"
+ o.group = {}
+ for k, v in pairs(socks_list) do
+ o:value(v.id, v.remark)
+ o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
+ end
+ for k, v in pairs(balancers_table) do
+ o:value(v.id, v.remark)
+ o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
+ end
+ for k, v in pairs(urltest_table) do
+ o:value(v.id, v.remark)
+ o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
+ end
+ for k, v in pairs(iface_table) do
+ o:value(v.id, v.remark)
+ o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
+ end
+ for k, v in pairs(nodes_table) do
+ o:value(v.id, v.remark)
+ o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
+ end
+
+ o = s:option(Flag, "fakedns", 'FakeDNS', translate("Use FakeDNS work in the domain that proxy.") .. "
" ..
+ translate("Suitable scenarios for let the node servers get the target domain names.") .. "
" ..
+ translate("Such as: DNS unlocking of streaming media, reducing DNS query latency, etc."))
+end
+m.uci:foreach(appname, "shunt_rules", function(e)
+ if e[".name"] and e.remarks then
+ o = s:option(ListValue, e[".name"], string.format('* %s', api.url("shunt_rules", e[".name"]), e.remarks))
+ o:value("", translate("Close (Not use)"))
+ o:value("_default", translate("Use default node"))
+ o:value("_direct", translate("Direct Connection"))
+ o:value("_blackhole", translate("Blackhole (Block)"))
+ o.template = appname .. "/cbi/nodes_listvalue"
+ o.group = {"","","",""}
+
+ if #nodes_table > 0 then
+ local pt = s:option(ListValue, e[".name"] .. "_proxy_tag", e.remarks .. " " .. translate("Preproxy"))
+ pt:value("", translate("Close (Not use)"))
+ pt:value("main", translate("Use preproxy node"))
+ pt:depends("__hide__", "1")
+
+ local fakedns_tag = s:option(Flag, e[".name"] .. "_fakedns", string.format('* %s', e.remarks .. " " .. "FakeDNS"))
+
+ for k, v in pairs(socks_list) do
+ o:value(v.id, v.remark)
+ o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
+ fakedns_tag:depends({ ["fakedns"] = true, [e[".name"]] = v.id })
+ end
+ for k, v in pairs(balancers_table) do
+ o:value(v.id, v.remark)
+ o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
+ fakedns_tag:depends({ ["fakedns"] = true, [e[".name"]] = v.id })
+ end
+ for k, v in pairs(urltest_table) do
+ o:value(v.id, v.remark)
+ o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
+ fakedns_tag:depends({ ["fakedns"] = true, [e[".name"]] = v.id })
+ end
+ for k, v in pairs(iface_table) do
+ o:value(v.id, v.remark)
+ o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
+ end
+ for k, v in pairs(nodes_table) do
+ o:value(v.id, v.remark)
+ o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
+ if not api.is_local_ip(v.address) then --本地节点禁止使用前置
+ pt:depends({ ["preproxy_enabled"] = true, [e[".name"]] = v.id })
+ end
+ fakedns_tag:depends({ ["fakedns"] = true, [e[".name"]] = v.id })
+ end
+ if default_node ~= "_direct" or default_node ~= "_blackhole" then
+ fakedns_tag:depends({ ["fakedns"] = true, [e[".name"]] = "_default" })
+ end
+ end
+ end
+end)
+
+o = s:option(DummyValue, "shunt_tips", " ")
+o.not_rewrite = true
+o.rawhtml = true
+o.cfgvalue = function(t, n)
+ return string.format('%s', translate("No shunt rules? Click me to go to add."))
+end
+
+local o = s:option(ListValue, "default_node", string.format('* %s', translate("Default")))
+o:value("_direct", translate("Direct Connection"))
+o:value("_blackhole", translate("Blackhole (Block)"))
+o.template = appname .. "/cbi/nodes_listvalue"
+o.group = {"",""}
+
+if #nodes_table > 0 then
+ for k, v in pairs(socks_list) do
+ o:value(v.id, v.remark)
+ o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
+ end
+ for k, v in pairs(balancers_table) do
+ o:value(v.id, v.remark)
+ o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
+ end
+ for k, v in pairs(urltest_table) do
+ o:value(v.id, v.remark)
+ o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
+ end
+ for k, v in pairs(iface_table) do
+ o:value(v.id, v.remark)
+ o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
+ end
+ local dpt = s:option(ListValue, "default_proxy_tag", translate("Default Preproxy"), translate("When using, localhost will connect this node first and then use this node to connect the default node."))
+ dpt:value("", translate("Close (Not use)"))
+ dpt:value("main", translate("Use preproxy node"))
+ dpt:depends("__hide__", "1")
+ for k, v in pairs(nodes_table) do
+ o:value(v.id, v.remark)
+ o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
+ if not api.is_local_ip(v.address) then
+ dpt:depends({ ["preproxy_enabled"] = true, ["default_node"] = v.id })
+ end
+ end
+end
+
+o = s:option(ListValue, "domainStrategy", translate("Domain Strategy"))
+o:value("AsIs")
+o:value("IPIfNonMatch")
+o:value("IPOnDemand")
+o.default = "IPOnDemand"
+o.description = "
Default) has a separate switch that controls whether this rule uses the pre-proxy or not."))
- o:depends({ [_n("protocol")] = "_shunt", [_n("preproxy_enabled")] = true })
- o.template = appname .. "/cbi/nodes_listvalue"
- o.group = {}
- for k, v in pairs(socks_list) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- end
- for k, v in pairs(balancers_table) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- end
- for k, v in pairs(iface_table) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- end
- for k, v in pairs(nodes_table) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- end
-
- o = s:option(Flag, _n("fakedns"), "FakeDNS", translate("Use FakeDNS work in the shunt domain that proxy."))
- o:depends({ [_n("protocol")] = "_shunt" })
- end
- m.uci:foreach(appname, "shunt_rules", function(e)
- if e[".name"] and e.remarks then
- o = s:option(ListValue, _n(e[".name"]), string.format('* %s', api.url("shunt_rules", e[".name"]), e.remarks))
- o:value("", translate("Close"))
- o:value("_default", translate("Default"))
- o:value("_direct", translate("Direct Connection"))
- o:value("_blackhole", translate("Blackhole"))
- o:depends({ [_n("protocol")] = "_shunt" })
- o.template = appname .. "/cbi/nodes_listvalue"
- o.group = {"","","",""}
-
- if #nodes_table > 0 then
- local pt = s:option(ListValue, _n(e[".name"] .. "_proxy_tag"), string.format('* %s', e.remarks .. " " .. translate("Preproxy")))
- pt:value("", translate("Close"))
- pt:value("main", translate("Preproxy Node"))
- pt:depends("__hide__", "1")
-
- local fakedns_tag = s:option(Flag, _n(e[".name"] .. "_fakedns"), string.format('* %s', e.remarks .. " " .. "FakeDNS"))
-
- for k, v in pairs(socks_list) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- fakedns_tag:depends({ [_n("protocol")] = "_shunt", [_n("fakedns")] = true, [_n(e[".name"])] = v.id })
- end
- for k, v in pairs(balancers_table) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- end
- for k, v in pairs(iface_table) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- end
- for k, v in pairs(nodes_table) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- if not api.is_local_ip(v.address) then --本地节点禁止使用前置
- pt:depends({ [_n("protocol")] = "_shunt", [_n("preproxy_enabled")] = true, [_n(e[".name"])] = v.id })
- end
- fakedns_tag:depends({ [_n("protocol")] = "_shunt", [_n("fakedns")] = true, [_n(e[".name"])] = v.id })
- end
- if default_node ~= "_direct" or default_node ~= "_blackhole" then
- fakedns_tag:depends({ [_n("protocol")] = "_shunt", [_n("fakedns")] = true, [_n(e[".name"])] = "_default" })
- end
- end
- end
- end)
-
- o = s:option(DummyValue, _n("shunt_tips"), " ")
- o.not_rewrite = true
- o.rawhtml = true
- o.cfgvalue = function(t, n)
- return string.format('%s', translate("No shunt rules? Click me to go to add."))
- end
- o:depends({ [_n("protocol")] = "_shunt" })
-
- local o = s:option(ListValue, _n("default_node"), string.format('* %s', translate("Default")))
- o:depends({ [_n("protocol")] = "_shunt" })
- o:value("_direct", translate("Direct Connection"))
- o:value("_blackhole", translate("Blackhole"))
- o.template = appname .. "/cbi/nodes_listvalue"
- o.group = {"",""}
+if load_iface_options then -- [[ 自定义接口 Start ]]
+ o = s:option(Value, _n("iface"), translate("Interface"))
+ o.default = "eth1"
+ o:depends({ [_n("protocol")] = "_iface" })
+end -- [[ 自定义接口 End ]]
- if #nodes_table > 0 then
- for k, v in pairs(socks_list) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- end
- for k, v in pairs(balancers_table) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- end
- for k, v in pairs(iface_table) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- end
- local dpt = s:option(ListValue, _n("default_proxy_tag"), string.format('* %s', translate("Default Preproxy")), translate("When using, localhost will connect this node first and then use this node to connect the default node."))
- dpt:value("", translate("Close"))
- dpt:value("main", translate("Preproxy Node"))
- dpt:depends("__hide__", "1")
- for k, v in pairs(nodes_table) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- if not api.is_local_ip(v.address) then
- dpt:depends({ [_n("protocol")] = "_shunt", [_n("preproxy_enabled")] = true, [_n("default_node")] = v.id })
- end
- end
- end
- o = s:option(ListValue, _n("domainStrategy"), translate("Domain Strategy"))
- o:value("AsIs")
- o:value("IPIfNonMatch")
- o:value("IPOnDemand")
- o.default = "IPOnDemand"
- o.description = "Default) has a separate switch that controls whether this rule uses the pre-proxy or not."))
- o:depends({ [_n("protocol")] = "_shunt", [_n("preproxy_enabled")] = true })
- o.template = appname .. "/cbi/nodes_listvalue"
- o.group = {}
- for k, v in pairs(socks_list) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- end
- for k, v in pairs(urltest_table) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- end
- for k, v in pairs(iface_table) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- end
- for k, v in pairs(nodes_table) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- end
-
- o = s:option(Flag, _n("fakedns"), "FakeDNS", translate("Use FakeDNS work in the shunt domain that proxy."))
- o:depends({ [_n("protocol")] = "_shunt" })
- end
- m.uci:foreach(appname, "shunt_rules", function(e)
- if e[".name"] and e.remarks then
- o = s:option(ListValue, _n(e[".name"]), string.format('* %s', api.url("shunt_rules", e[".name"]), e.remarks))
- o:value("", translate("Close"))
- o:value("_default", translate("Default"))
- o:value("_direct", translate("Direct Connection"))
- o:value("_blackhole", translate("Blackhole"))
- o:depends({ [_n("protocol")] = "_shunt" })
- o.template = appname .. "/cbi/nodes_listvalue"
- o.group = {"","","",""}
-
- if #nodes_table > 0 then
- local pt = s:option(ListValue, _n(e[".name"] .. "_proxy_tag"), string.format('* %s', e.remarks .. " " .. translate("Preproxy")))
- pt:value("", translate("Close"))
- pt:value("main", translate("Preproxy Node"))
- pt:depends("__hide__", "1")
-
- local fakedns_tag = s:option(Flag, _n(e[".name"] .. "_fakedns"), string.format('* %s', e.remarks .. " " .. "FakeDNS"))
-
- for k, v in pairs(socks_list) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- fakedns_tag:depends({ [_n("protocol")] = "_shunt", [_n("fakedns")] = true, [_n(e[".name"])] = v.id })
- end
- for k, v in pairs(urltest_table) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- end
- for k, v in pairs(iface_table) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- end
- for k, v in pairs(nodes_table) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- if not api.is_local_ip(v.address) then --本地节点禁止使用前置
- pt:depends({ [_n("protocol")] = "_shunt", [_n("preproxy_enabled")] = true, [_n(e[".name"])] = v.id })
- end
- fakedns_tag:depends({ [_n("protocol")] = "_shunt", [_n("fakedns")] = true, [_n(e[".name"])] = v.id })
- end
- if default_node ~= "_direct" or default_node ~= "_blackhole" then
- fakedns_tag:depends({ [_n("protocol")] = "_shunt", [_n("fakedns")] = true, [_n(e[".name"])] = "_default" })
- end
- end
- end
- end)
-
- o = s:option(DummyValue, _n("shunt_tips"), " ")
- o.not_rewrite = true
- o.rawhtml = true
- o.cfgvalue = function(t, n)
- return string.format('%s', translate("No shunt rules? Click me to go to add."))
- end
- o:depends({ [_n("protocol")] = "_shunt" })
-
- local o = s:option(ListValue, _n("default_node"), string.format('* %s', translate("Default")))
- o:depends({ [_n("protocol")] = "_shunt" })
- o:value("_direct", translate("Direct Connection"))
- o:value("_blackhole", translate("Blackhole"))
- o.template = appname .. "/cbi/nodes_listvalue"
- o.group = {"",""}
-
- if #nodes_table > 0 then
- for k, v in pairs(socks_list) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- end
- for k, v in pairs(urltest_table) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- end
- for k, v in pairs(iface_table) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- end
- local dpt = s:option(ListValue, _n("default_proxy_tag"), string.format('* %s', translate("Default Preproxy")), translate("When using, localhost will connect this node first and then use this node to connect the default node."))
- dpt:value("", translate("Close"))
- dpt:value("main", translate("Preproxy Node"))
- dpt:depends("__hide__", "1")
- for k, v in pairs(nodes_table) do
- o:value(v.id, v.remark)
- o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
- if not api.is_local_ip(v.address) then
- dpt:depends({ [_n("protocol")] = "_shunt", [_n("preproxy_enabled")] = true, [_n("default_node")] = v.id })
- end
- end
- end
-end -- [[ 分流模块 End ]]
-
-if s.val["protocol"] == "_iface" then -- [[ 自定义接口 Start ]]
+if load_iface_options then -- [[ 自定义接口 Start ]]
o = s:option(Value, _n("iface"), translate("Interface"))
o.default = "eth1"
o:depends({ [_n("protocol")] = "_iface" })
end
+
+if load_normal_options then
+
o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))
o = s:option(Value, _n("port"), translate("Port"))
@@ -877,4 +784,6 @@ for k, v in pairs(nodes_table) do
end
end
+end
+
api.luci_types(arg[1], m, s, type_name, option_prefix)
diff --git a/applications/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ray.lua b/applications/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ray.lua
index d42e2e3c57f..7d0a2769b69 100644
--- a/applications/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ray.lua
+++ b/applications/luci-app-passwall/luasrc/model/cbi/passwall/server/type/ray.lua
@@ -243,7 +243,7 @@ end
o = s:option(Flag, _n("ech"), translate("ECH"))
o.default = "0"
-o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false })
+o:depends({ [_n("tls")] = true, [_n("reality")] = false })
o = s:option(TextValue, _n("ech_key"), translate("ECH Key"))
o.default = ""
diff --git a/applications/luci-app-passwall/luasrc/passwall/util_hysteria2.lua b/applications/luci-app-passwall/luasrc/passwall/util_hysteria2.lua
index f2668e47322..4053bc91f4d 100644
--- a/applications/luci-app-passwall/luasrc/passwall/util_hysteria2.lua
+++ b/applications/luci-app-passwall/luasrc/passwall/util_hysteria2.lua
@@ -31,25 +31,25 @@ function gen_config_server(node)
end
function gen_config(var)
- local node_id = var["-node"]
+ local node_id = var["node"]
if not node_id then
- print("-node 不能为空")
+ print("node 不能为空")
return
end
local node = uci:get_all("passwall", node_id)
- local local_tcp_redir_port = var["-local_tcp_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_port = var["-local_socks_port"]
- local local_socks_username = var["-local_socks_username"]
- local local_socks_password = var["-local_socks_password"]
- local local_http_address = var["-local_http_address"] or "0.0.0.0"
- local local_http_port = var["-local_http_port"]
- local local_http_username = var["-local_http_username"]
- local local_http_password = var["-local_http_password"]
- local tcp_proxy_way = var["-tcp_proxy_way"]
- local server_host = var["-server_host"] or node.address
- local server_port = var["-server_port"] or node.port
+ local local_tcp_redir_port = var["local_tcp_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_port = var["local_socks_port"]
+ local local_socks_username = var["local_socks_username"]
+ local local_socks_password = var["local_socks_password"]
+ local local_http_address = var["local_http_address"] or "0.0.0.0"
+ local local_http_port = var["local_http_port"]
+ local local_http_username = var["local_http_username"]
+ local local_http_password = var["local_http_password"]
+ local tcp_proxy_way = var["tcp_proxy_way"]
+ local server_host = var["server_host"] or node.address
+ local server_port = var["server_port"] or node.port
if api.is_ipv6(server_host) then
server_host = api.get_ipv6_full(server_host)
@@ -136,6 +136,10 @@ _G.gen_config = gen_config
if arg[1] then
local func =_G[arg[1]]
if func then
- print(func(api.get_function_args(arg)))
+ local var = nil
+ if arg[2] then
+ var = jsonc.parse(arg[2])
+ end
+ print(func(var))
end
end
diff --git a/applications/luci-app-passwall/luasrc/passwall/util_naiveproxy.lua b/applications/luci-app-passwall/luasrc/passwall/util_naiveproxy.lua
index ee095c1e6c1..194a87ef7f5 100644
--- a/applications/luci-app-passwall/luasrc/passwall/util_naiveproxy.lua
+++ b/applications/luci-app-passwall/luasrc/passwall/util_naiveproxy.lua
@@ -4,17 +4,17 @@ local uci = api.uci
local jsonc = api.jsonc
function gen_config(var)
- local node_id = var["-node"]
+ local node_id = var["node"]
if not node_id then
- print("-node 不能为空")
+ print("node 不能为空")
return
end
local node = uci:get_all("passwall", node_id)
- local run_type = var["-run_type"]
- local local_addr = var["-local_addr"]
- local local_port = var["-local_port"]
- local server_host = var["-server_host"] or node.address
- local server_port = var["-server_port"] or node.port
+ local run_type = var["run_type"]
+ local local_addr = var["local_addr"]
+ local local_port = var["local_port"]
+ local server_host = var["server_host"] or node.address
+ local server_port = var["server_port"] or node.port
if api.is_ipv6(server_host) then
server_host = api.get_ipv6_full(server_host)
@@ -34,6 +34,10 @@ _G.gen_config = gen_config
if arg[1] then
local func =_G[arg[1]]
if func then
- print(func(api.get_function_args(arg)))
+ local var = nil
+ if arg[2] then
+ var = jsonc.parse(arg[2])
+ end
+ print(func(var))
end
end
diff --git a/applications/luci-app-passwall/luasrc/passwall/util_shadowsocks.lua b/applications/luci-app-passwall/luasrc/passwall/util_shadowsocks.lua
index 4b70f06a98b..d17e91e0d66 100644
--- a/applications/luci-app-passwall/luasrc/passwall/util_shadowsocks.lua
+++ b/applications/luci-app-passwall/luasrc/passwall/util_shadowsocks.lua
@@ -31,29 +31,29 @@ end
local plugin_sh, plugin_bin
function gen_config(var)
- local node_id = var["-node"]
+ local node_id = var["node"]
if not node_id then
- print("-node 不能为空")
+ print("node 不能为空")
return
end
local node = uci:get_all("passwall", node_id)
- local server_host = var["-server_host"] or node.address
- local server_port = var["-server_port"] or node.port
- local local_addr = var["-local_addr"]
- local local_port = var["-local_port"]
- local mode = var["-mode"]
- local local_socks_address = var["-local_socks_address"] or "0.0.0.0"
- local local_socks_port = var["-local_socks_port"]
- local local_socks_username = var["-local_socks_username"]
- local local_socks_password = var["-local_socks_password"]
- local local_http_address = var["-local_http_address"] or "0.0.0.0"
- local local_http_port = var["-local_http_port"]
- local local_http_username = var["-local_http_username"]
- local local_http_password = var["-local_http_password"]
- 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_udp_redir_port = var["-local_udp_redir_port"]
- local local_udp_redir_address = var["-local_udp_redir_address"] or "0.0.0.0"
+ local server_host = var["server_host"] or node.address
+ local server_port = var["server_port"] or node.port
+ local local_addr = var["local_addr"]
+ local local_port = var["local_port"]
+ local mode = var["mode"]
+ local local_socks_address = var["local_socks_address"] or "0.0.0.0"
+ local local_socks_port = var["local_socks_port"]
+ local local_socks_username = var["local_socks_username"]
+ local local_socks_password = var["local_socks_password"]
+ local local_http_address = var["local_http_address"] or "0.0.0.0"
+ local local_http_port = var["local_http_port"]
+ local local_http_username = var["local_http_username"]
+ local local_http_password = var["local_http_password"]
+ 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_udp_redir_port = var["local_udp_redir_port"]
+ local local_udp_redir_address = var["local_udp_redir_address"] or "0.0.0.0"
if api.is_ipv6(server_host) then
server_host = api.get_ipv6_only(server_host)
@@ -62,7 +62,7 @@ function gen_config(var)
local plugin_file
if node.plugin and node.plugin ~= "" and node.plugin ~= "none" then
- plugin_sh = var["-plugin_sh"] or ""
+ plugin_sh = var["plugin_sh"] or ""
plugin_file = (plugin_sh ~="") and plugin_sh or node.plugin
plugin_bin = node.plugin
end
@@ -77,7 +77,7 @@ function gen_config(var)
timeout = tonumber(node.timeout),
fast_open = (node.tcp_fast_open and node.tcp_fast_open == "true") and true or false,
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
@@ -123,7 +123,7 @@ function gen_config(var)
table.insert(config.locals, {
protocol = "redir",
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_port = tonumber(local_tcp_redir_port)
})
@@ -146,7 +146,11 @@ _G.gen_config = gen_config
if arg[1] then
local func =_G[arg[1]]
if func then
- print(func(api.get_function_args(arg)))
+ local var = nil
+ if arg[2] then
+ var = jsonc.parse(arg[2])
+ end
+ print(func(var))
if plugin_sh and plugin_sh ~="" and plugin_bin then
local f = io.open(plugin_sh, "w")
f:write("#!/bin/sh\n")
diff --git a/applications/luci-app-passwall/luasrc/passwall/util_sing-box.lua b/applications/luci-app-passwall/luasrc/passwall/util_sing-box.lua
index 9f18299e8c1..ba09924b9a8 100644
--- a/applications/luci-app-passwall/luasrc/passwall/util_sing-box.lua
+++ b/applications/luci-app-passwall/luasrc/passwall/util_sing-box.lua
@@ -43,9 +43,9 @@ function geo_convert_srs(var)
if check_geoview() ~= 1 then
return
end
- local geo_path = var["-geo_path"]
- local prefix = var["-prefix"]
- local rule_name = var["-rule_name"]
+ local geo_path = var["geo_path"]
+ local prefix = var["prefix"]
+ local rule_name = var["rule_name"]
local output_srs_file = GEO_VAR.TO_SRS_PATH .. prefix .. "-" .. rule_name .. ".srs"
if not fs.access(output_srs_file) then
local cmd = string.format("geoview -type %s -action convert -input '%s' -list '%s' -output '%s' -lowmem=true",
@@ -72,7 +72,7 @@ local function convert_geofile()
sys.call("rm -rf " .. GEO_VAR.TO_SRS_PATH .. prefix .. "-*.srs" )
end
for k in pairs(tags) do
- geo_convert_srs({["-geo_path"] = file_path, ["-prefix"] = prefix, ["-rule_name"] = k})
+ geo_convert_srs({["geo_path"] = file_path, ["prefix"] = prefix, ["rule_name"] = k})
end
end
end
@@ -892,42 +892,42 @@ function gen_config_server(node)
end
function gen_config(var)
- local flag = var["-flag"]
- local log = var["-log"] or "0"
- local loglevel = var["-loglevel"] or "warn"
- local logfile = var["-logfile"] or "/dev/null"
- local node_id = var["-node"]
- local server_host = var["-server_host"]
- local server_port = var["-server_port"]
- local tcp_proxy_way = var["-tcp_proxy_way"]
- local tcp_redir_port = var["-tcp_redir_port"]
- local udp_redir_port = var["-udp_redir_port"]
- local local_socks_address = var["-local_socks_address"] or "0.0.0.0"
- local local_socks_port = var["-local_socks_port"]
- local local_socks_username = var["-local_socks_username"]
- local local_socks_password = var["-local_socks_password"]
- local local_http_address = var["-local_http_address"] or "0.0.0.0"
- local local_http_port = var["-local_http_port"]
- local local_http_username = var["-local_http_username"]
- local local_http_password = var["-local_http_password"]
- local dns_listen_port = var["-dns_listen_port"]
- local direct_dns_port = var["-direct_dns_port"]
- local direct_dns_udp_server = var["-direct_dns_udp_server"]
- local direct_dns_tcp_server = var["-direct_dns_tcp_server"]
- local direct_dns_query_strategy = var["-direct_dns_query_strategy"]
- local remote_dns_server = var["-remote_dns_server"]
- local remote_dns_port = var["-remote_dns_port"]
- local remote_dns_udp_server = var["-remote_dns_udp_server"]
- local remote_dns_tcp_server = var["-remote_dns_tcp_server"]
- local remote_dns_doh_url = var["-remote_dns_doh_url"]
- local remote_dns_doh_host = var["-remote_dns_doh_host"]
- local remote_dns_client_ip = var["-remote_dns_client_ip"]
- local remote_dns_query_strategy = var["-remote_dns_query_strategy"]
- local remote_dns_fake = var["-remote_dns_fake"]
- local dns_cache = var["-dns_cache"]
- local dns_socks_address = var["-dns_socks_address"]
- local dns_socks_port = var["-dns_socks_port"]
- local no_run = var["-no_run"]
+ local flag = var["flag"]
+ local log = var["log"] or "0"
+ local loglevel = var["loglevel"] or "warn"
+ local logfile = var["logfile"] or "/dev/null"
+ local node_id = var["node"]
+ local server_host = var["server_host"]
+ local server_port = var["server_port"]
+ local tcp_proxy_way = var["tcp_proxy_way"]
+ local tcp_redir_port = var["tcp_redir_port"]
+ local udp_redir_port = var["udp_redir_port"]
+ local local_socks_address = var["local_socks_address"] or "0.0.0.0"
+ local local_socks_port = var["local_socks_port"]
+ local local_socks_username = var["local_socks_username"]
+ local local_socks_password = var["local_socks_password"]
+ local local_http_address = var["local_http_address"] or "0.0.0.0"
+ local local_http_port = var["local_http_port"]
+ local local_http_username = var["local_http_username"]
+ local local_http_password = var["local_http_password"]
+ local dns_listen_port = var["dns_listen_port"]
+ local direct_dns_port = var["direct_dns_port"]
+ local direct_dns_udp_server = var["direct_dns_udp_server"]
+ local direct_dns_tcp_server = var["direct_dns_tcp_server"]
+ local direct_dns_query_strategy = var["direct_dns_query_strategy"]
+ local remote_dns_server = var["remote_dns_server"]
+ local remote_dns_port = var["remote_dns_port"]
+ local remote_dns_udp_server = var["remote_dns_udp_server"]
+ local remote_dns_tcp_server = var["remote_dns_tcp_server"]
+ local remote_dns_doh_url = var["remote_dns_doh_url"]
+ local remote_dns_doh_host = var["remote_dns_doh_host"]
+ local remote_dns_client_ip = var["remote_dns_client_ip"]
+ local remote_dns_query_strategy = var["remote_dns_query_strategy"]
+ local remote_dns_fake = var["remote_dns_fake"]
+ local dns_cache = var["dns_cache"]
+ local dns_socks_address = var["dns_socks_address"]
+ local dns_socks_port = var["dns_socks_port"]
+ local no_run = var["no_run"]
local dns_domain_rules = {}
local dns = nil
@@ -2050,19 +2050,19 @@ function gen_config(var)
end
function gen_proto_config(var)
- local local_socks_address = var["-local_socks_address"] or "0.0.0.0"
- local local_socks_port = var["-local_socks_port"]
- local local_socks_username = var["-local_socks_username"]
- local local_socks_password = var["-local_socks_password"]
- local local_http_address = var["-local_http_address"] or "0.0.0.0"
- local local_http_port = var["-local_http_port"]
- local local_http_username = var["-local_http_username"]
- local local_http_password = var["-local_http_password"]
- local server_proto = var["-server_proto"]
- local server_address = var["-server_address"]
- local server_port = var["-server_port"]
- local server_username = var["-server_username"]
- local server_password = var["-server_password"]
+ local local_socks_address = var["local_socks_address"] or "0.0.0.0"
+ local local_socks_port = var["local_socks_port"]
+ local local_socks_username = var["local_socks_username"]
+ local local_socks_password = var["local_socks_password"]
+ local local_http_address = var["local_http_address"] or "0.0.0.0"
+ local local_http_port = var["local_http_port"]
+ local local_http_username = var["local_http_username"]
+ local local_http_password = var["local_http_password"]
+ local server_proto = var["server_proto"]
+ local server_address = var["server_address"]
+ local server_port = var["server_port"]
+ local server_username = var["server_username"]
+ local server_password = var["server_password"]
local inbounds = {}
local outbounds = {}
@@ -2135,7 +2135,11 @@ _G.geo_convert_srs = geo_convert_srs
if arg[1] then
local func =_G[arg[1]]
if func then
- print(func(api.get_function_args(arg)))
+ local var = nil
+ if arg[2] then
+ var = jsonc.parse(arg[2])
+ end
+ print(func(var))
if (next(GEO_VAR.SITE_TAGS) or next(GEO_VAR.IP_TAGS)) and not no_run then
convert_geofile()
end
diff --git a/applications/luci-app-passwall/luasrc/passwall/util_trojan.lua b/applications/luci-app-passwall/luasrc/passwall/util_trojan.lua
index 848b689a560..29cb467d8d8 100644
--- a/applications/luci-app-passwall/luasrc/passwall/util_trojan.lua
+++ b/applications/luci-app-passwall/luasrc/passwall/util_trojan.lua
@@ -1,7 +1,7 @@
module("luci.passwall.util_trojan", package.seeall)
local api = require "luci.passwall.api"
local uci = api.uci
-local json = api.jsonc
+local jsonc = api.jsonc
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"
@@ -41,18 +41,18 @@ function gen_config_server(node)
end
function gen_config(var)
- local node_id = var["-node"]
+ local node_id = var["node"]
if not node_id then
- print("-node 不能为空")
+ print("node 不能为空")
return
end
local node = uci:get_all("passwall", node_id)
- local run_type = var["-run_type"]
- local local_addr = var["-local_addr"]
- local local_port = var["-local_port"]
- local server_host = var["-server_host"] or node.address
- local server_port = var["-server_port"] or node.port
- local loglevel = var["-loglevel"] or 2
+ local run_type = var["run_type"]
+ local local_addr = var["local_addr"]
+ local local_port = var["local_port"]
+ local server_host = var["server_host"] or node.address
+ local server_port = var["server_port"] or node.port
+ 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 cipher13 = "TLS_AES_128_GCM_SHA256:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_256_GCM_SHA384"
@@ -83,7 +83,7 @@ function gen_config(var)
},
udp_timeout = 60,
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,
keep_alive = true,
reuse_port = true,
@@ -91,7 +91,7 @@ function gen_config(var)
fast_open_qlen = 20
}
}
- return json.stringify(trojan, 1)
+ return jsonc.stringify(trojan, 1)
end
_G.gen_config = gen_config
@@ -99,6 +99,10 @@ _G.gen_config = gen_config
if arg[1] then
local func =_G[arg[1]]
if func then
- print(func(api.get_function_args(arg)))
+ local var = nil
+ if arg[2] then
+ var = jsonc.parse(arg[2])
+ end
+ print(func(var))
end
end
diff --git a/applications/luci-app-passwall/luasrc/passwall/util_tuic.lua b/applications/luci-app-passwall/luasrc/passwall/util_tuic.lua
index e138b6da56b..94853943ccd 100644
--- a/applications/luci-app-passwall/luasrc/passwall/util_tuic.lua
+++ b/applications/luci-app-passwall/luasrc/passwall/util_tuic.lua
@@ -1,20 +1,20 @@
module("luci.passwall.util_tuic", package.seeall)
local api = require "luci.passwall.api"
local uci = api.uci
-local json = api.jsonc
+local jsonc = api.jsonc
function gen_config(var)
- local node_id = var["-node"]
+ local node_id = var["node"]
if not node_id then
- print("-node 不能为空")
+ print("node 不能为空")
return
end
local node = uci:get_all("passwall", node_id)
- local local_addr = var["-local_addr"]
- local local_port = var["-local_port"]
- local server_host = var["-server_host"] or node.address
- local server_port = var["-server_port"] or node.port
- local loglevel = var["-loglevel"] or "warn"
+ local local_addr = var["local_addr"]
+ local local_port = var["local_port"]
+ local server_host = var["server_host"] or node.address
+ local server_port = var["server_port"] or node.port
+ local loglevel = var["loglevel"] or "warn"
local tuic= {
relay = {
@@ -44,7 +44,7 @@ function gen_config(var)
},
log_level = loglevel
}
- return json.stringify(tuic, 1)
+ return jsonc.stringify(tuic, 1)
end
_G.gen_config = gen_config
@@ -52,6 +52,10 @@ _G.gen_config = gen_config
if arg[1] then
local func =_G[arg[1]]
if func then
- print(func(api.get_function_args(arg)))
+ local var = nil
+ if arg[2] then
+ var = jsonc.parse(arg[2])
+ end
+ print(func(var))
end
end
diff --git a/applications/luci-app-passwall/luasrc/passwall/util_xray.lua b/applications/luci-app-passwall/luasrc/passwall/util_xray.lua
index a09af5d945c..17beaf7253b 100644
--- a/applications/luci-app-passwall/luasrc/passwall/util_xray.lua
+++ b/applications/luci-app-passwall/luasrc/passwall/util_xray.lua
@@ -151,7 +151,7 @@ function gen_outbound(flag, node, tag, proxy_table)
serverName = node.tls_serverName,
allowInsecure = (node.tls_allowInsecure == "1") and true or false,
fingerprint = (node.type == "Xray" and node.utls == "1" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or nil,
- pinnedPeerCertificateChainSha256 = node.tls_chain_fingerprint and { node.tls_chain_fingerprint } or nil,
+ pinnedPeerCertSha256 = node.tls_chain_fingerprint or nil,
echConfigList = (node.ech == "1") and node.ech_config or nil,
echForceQuery = (node.ech == "1") and (node.ech_ForceQuery or "none") or nil
} or nil,
@@ -614,42 +614,42 @@ function gen_config_server(node)
end
function gen_config(var)
- local flag = var["-flag"]
- local node_id = var["-node"]
- local server_host = var["-server_host"]
- local server_port = var["-server_port"]
- local tcp_proxy_way = var["-tcp_proxy_way"] or "redirect"
- local tcp_redir_port = var["-tcp_redir_port"]
- local udp_redir_port = var["-udp_redir_port"]
- local local_socks_address = var["-local_socks_address"] or "0.0.0.0"
- local local_socks_port = var["-local_socks_port"]
- local local_socks_username = var["-local_socks_username"]
- local local_socks_password = var["-local_socks_password"]
- local local_http_address = var["-local_http_address"] or "0.0.0.0"
- local local_http_port = var["-local_http_port"]
- local local_http_username = var["-local_http_username"]
- local local_http_password = var["-local_http_password"]
- local dns_listen_port = var["-dns_listen_port"]
- local dns_cache = var["-dns_cache"]
- local direct_dns_port = var["-direct_dns_port"]
- local direct_dns_udp_server = var["-direct_dns_udp_server"]
- local direct_dns_tcp_server = var["-direct_dns_tcp_server"]
- local direct_dns_query_strategy = var["-direct_dns_query_strategy"]
- local remote_dns_udp_server = var["-remote_dns_udp_server"]
- local remote_dns_udp_port = var["-remote_dns_udp_port"]
- local remote_dns_tcp_server = var["-remote_dns_tcp_server"]
- local remote_dns_tcp_port = var["-remote_dns_tcp_port"]
- local remote_dns_doh_url = var["-remote_dns_doh_url"]
- local remote_dns_doh_host = var["-remote_dns_doh_host"]
- local remote_dns_doh_ip = var["-remote_dns_doh_ip"]
- local remote_dns_doh_port = var["-remote_dns_doh_port"]
- local remote_dns_client_ip = var["-remote_dns_client_ip"]
- local remote_dns_fake = var["-remote_dns_fake"]
- local remote_dns_query_strategy = var["-remote_dns_query_strategy"]
- local dns_socks_address = var["-dns_socks_address"]
- local dns_socks_port = var["-dns_socks_port"]
- local loglevel = var["-loglevel"] or "warning"
- local no_run = var["-no_run"]
+ local flag = var["flag"]
+ local node_id = var["node"]
+ local server_host = var["server_host"]
+ local server_port = var["server_port"]
+ local tcp_proxy_way = var["tcp_proxy_way"] or "redirect"
+ local tcp_redir_port = var["tcp_redir_port"]
+ local udp_redir_port = var["udp_redir_port"]
+ local local_socks_address = var["local_socks_address"] or "0.0.0.0"
+ local local_socks_port = var["local_socks_port"]
+ local local_socks_username = var["local_socks_username"]
+ local local_socks_password = var["local_socks_password"]
+ local local_http_address = var["local_http_address"] or "0.0.0.0"
+ local local_http_port = var["local_http_port"]
+ local local_http_username = var["local_http_username"]
+ local local_http_password = var["local_http_password"]
+ local dns_listen_port = var["dns_listen_port"]
+ local dns_cache = var["dns_cache"]
+ local direct_dns_port = var["direct_dns_port"]
+ local direct_dns_udp_server = var["direct_dns_udp_server"]
+ local direct_dns_tcp_server = var["direct_dns_tcp_server"]
+ local direct_dns_query_strategy = var["direct_dns_query_strategy"]
+ local remote_dns_udp_server = var["remote_dns_udp_server"]
+ local remote_dns_udp_port = var["remote_dns_udp_port"]
+ local remote_dns_tcp_server = var["remote_dns_tcp_server"]
+ local remote_dns_tcp_port = var["remote_dns_tcp_port"]
+ local remote_dns_doh_url = var["remote_dns_doh_url"]
+ local remote_dns_doh_host = var["remote_dns_doh_host"]
+ local remote_dns_doh_ip = var["remote_dns_doh_ip"]
+ local remote_dns_doh_port = var["remote_dns_doh_port"]
+ local remote_dns_client_ip = var["remote_dns_client_ip"]
+ local remote_dns_fake = var["remote_dns_fake"]
+ local remote_dns_query_strategy = var["remote_dns_query_strategy"]
+ local dns_socks_address = var["dns_socks_address"]
+ local dns_socks_port = var["dns_socks_port"]
+ local loglevel = var["loglevel"] or "warning"
+ local no_run = var["no_run"]
local dns_domain_rules = {}
local dns = nil
@@ -1686,19 +1686,19 @@ function gen_config(var)
end
function gen_proto_config(var)
- local local_socks_address = var["-local_socks_address"] or "0.0.0.0"
- local local_socks_port = var["-local_socks_port"]
- local local_socks_username = var["-local_socks_username"]
- local local_socks_password = var["-local_socks_password"]
- local local_http_address = var["-local_http_address"] or "0.0.0.0"
- local local_http_port = var["-local_http_port"]
- local local_http_username = var["-local_http_username"]
- local local_http_password = var["-local_http_password"]
- local server_proto = var["-server_proto"]
- local server_address = var["-server_address"]
- local server_port = var["-server_port"]
- local server_username = var["-server_username"]
- local server_password = var["-server_password"]
+ local local_socks_address = var["local_socks_address"] or "0.0.0.0"
+ local local_socks_port = var["local_socks_port"]
+ local local_socks_username = var["local_socks_username"]
+ local local_socks_password = var["local_socks_password"]
+ local local_http_address = var["local_http_address"] or "0.0.0.0"
+ local local_http_port = var["local_http_port"]
+ local local_http_username = var["local_http_username"]
+ local local_http_password = var["local_http_password"]
+ local server_proto = var["server_proto"]
+ local server_address = var["server_address"]
+ local server_port = var["server_port"]
+ local server_username = var["server_username"]
+ local server_password = var["server_password"]
local inbounds = {}
local outbounds = {}
@@ -1796,6 +1796,10 @@ _G.gen_proto_config = gen_proto_config
if arg[1] then
local func =_G[arg[1]]
if func then
- print(func(api.get_function_args(arg)))
+ local var = nil
+ if arg[2] then
+ var = jsonc.parse(arg[2])
+ end
+ print(func(var))
end
end
diff --git a/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue.htm b/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue.htm
index 2081a531b90..9ba659c4fb2 100644
--- a/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue.htm
+++ b/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue.htm
@@ -113,8 +113,6 @@
-<%+cbi/valuefooter%>
-
+
+<%+cbi/valuefooter%>
diff --git a/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue_com.htm b/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue_com.htm
index 84acd5a7608..6e6951c08ce 100644
--- a/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue_com.htm
+++ b/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_listvalue_com.htm
@@ -104,6 +104,7 @@
box-shadow: 0 6px 18px rgba(0,0,0,0.08);
max-height: 50vh;
overflow: auto;
+ overscroll-behavior: contain;
}
.lv-dropdown-search {
width: 100%;
@@ -669,6 +670,25 @@
}
});
});
+
+ // 防止 panel 惯性滚动穿透
+ panel.addEventListener('wheel', function (e) {
+ const deltaY = e.deltaY;
+ const scrollTop = panel.scrollTop;
+ const scrollHeight = panel.scrollHeight;
+ const clientHeight = panel.clientHeight;
+ const isAtTop = scrollTop === 0;
+ const isAtBottom = scrollTop + clientHeight >= scrollHeight;
+ if (deltaY < 0 && isAtTop) {
+ e.preventDefault();
+ return;
+ }
+ if (deltaY > 0 && isAtBottom) {
+ e.preventDefault();
+ return;
+ }
+ e.stopPropagation();
+ }, { passive: false });
}
const lv_adaptiveControls = new Set();
diff --git a/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_multivalue.htm b/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_multivalue.htm
index 88920275ffa..fde96d7deb0 100644
--- a/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_multivalue.htm
+++ b/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_multivalue.htm
@@ -108,7 +108,6 @@
<%:Selected:%> <%=selected_count%>/<%=total_count%>
-<%+cbi/valuefooter%>
+
+<%+cbi/valuefooter%>
diff --git a/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_value.htm b/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_value.htm
index 9745dd83486..76893ec7a66 100644
--- a/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_value.htm
+++ b/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_value.htm
@@ -126,8 +126,6 @@
-<%+cbi/valuefooter%>
-
+
+<%+cbi/valuefooter%>
diff --git a/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_value_com.htm b/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_value_com.htm
index 9386e914177..95b3f532bb5 100644
--- a/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_value_com.htm
+++ b/applications/luci-app-passwall/luasrc/view/passwall/cbi/nodes_value_com.htm
@@ -91,6 +91,7 @@
box-shadow: 0 6px 18px rgba(0,0,0,0.08);
max-height: 50vh;
overflow: auto;
+ overscroll-behavior: contain;
}
.v-dropdown-search, .v-dropdown-custom {
width: 100%;
@@ -701,6 +702,25 @@
e.preventDefault();
v_customEnter(cbid, labelSpan, hiddenInput, searchInput, panel, listContainer, customInput);
});
+
+ // 防止 panel 惯性滚动穿透
+ panel.addEventListener('wheel', function (e) {
+ const deltaY = e.deltaY;
+ const scrollTop = panel.scrollTop;
+ const scrollHeight = panel.scrollHeight;
+ const clientHeight = panel.clientHeight;
+ const isAtTop = scrollTop === 0;
+ const isAtBottom = scrollTop + clientHeight >= scrollHeight;
+ if (deltaY < 0 && isAtTop) {
+ e.preventDefault();
+ return;
+ }
+ if (deltaY > 0 && isAtBottom) {
+ e.preventDefault();
+ return;
+ }
+ e.stopPropagation();
+ }, { passive: false });
}
const v_adaptiveControls = new Set();
diff --git a/applications/luci-app-passwall/luasrc/view/passwall/global/footer.htm b/applications/luci-app-passwall/luasrc/view/passwall/global/footer.htm
index ddf3b139c87..10bac9bb9de 100644
--- a/applications/luci-app-passwall/luasrc/view/passwall/global/footer.htm
+++ b/applications/luci-app-passwall/luasrc/view/passwall/global/footer.htm
@@ -13,7 +13,26 @@
@@ -68,7 +71,14 @@
geosite
- Default) has a separate switch that controls whether this rule uses the pre-proxy or not."
msgstr "设置用作前置代理的节点。每条规则(包括默认)都有独立开关控制本规则是否使用前置代理。"
+msgid "Close (Not use)"
+msgstr "关闭(不使用)"
+
+msgid "Use default node"
+msgstr "使用默认节点"
+
msgid "Direct Connection"
msgstr "直连"
-msgid "Blackhole"
-msgstr "黑洞"
+msgid "Blackhole (Block)"
+msgstr "黑洞(屏蔽)"
+
+msgid "Use preproxy node"
+msgstr "使用前置代理节点"
msgid "Default Preproxy"
msgstr "默认前置代理"
@@ -931,6 +958,12 @@ msgstr "强制更新"
msgid "Manually update"
msgstr "手动更新"
+msgid "Rollback"
+msgstr "回滚"
+
+msgid "Rollbacking..."
+msgstr "回滚中..."
+
msgid "Update Options"
msgstr "更新选项"
@@ -1996,6 +2029,9 @@ msgstr "请输入查询内容!"
msgid "No results were found!"
msgstr "未找到任何结果!"
+msgid "Rules containing this value:"
+msgstr "所在规则列表:"
+
msgid "Domain/IP Query"
msgstr "域名/IP 查询"
diff --git a/applications/luci-app-passwall/root/usr/share/passwall/app.sh b/applications/luci-app-passwall/root/usr/share/passwall/app.sh
index 7c856d1986a..653d339bb75 100755
--- a/applications/luci-app-passwall/root/usr/share/passwall/app.sh
+++ b/applications/luci-app-passwall/root/usr/share/passwall/app.sh
@@ -5,9 +5,9 @@
. /lib/functions.sh
. /lib/functions/service.sh
+. /usr/share/libubox/jshn.sh
. /usr/share/passwall/utils.sh
-
GLOBAL_ACL_PATH=${TMP_ACL_PATH}/default
LUA_UTIL_PATH=/usr/lib/lua/luci/passwall
UTIL_SINGBOX=$LUA_UTIL_PATH/util_sing-box.lua
@@ -100,7 +100,6 @@ run_singbox() {
local flag type node tcp_redir_port tcp_proxy_way udp_redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
local dns_listen_port direct_dns_query_strategy direct_dns_port direct_dns_udp_server direct_dns_tcp_server remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_fakedns remote_dns_query_strategy dns_cache dns_socks_address dns_socks_port
local loglevel log_file config_file server_host server_port no_run
- local _extra_param=""
eval_set_val $@
[ -z "$type" ] && {
local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
@@ -111,68 +110,83 @@ run_singbox() {
}
[ -z "$type" ] && return 1
[ -n "$log_file" ] || local log_file="/dev/null"
- _extra_param="${_extra_param} -log 1 -logfile ${log_file}"
+ json_init
if [ "$log_file" = "/dev/null" ]; then
- _extra_param="${_extra_param} -log 0"
+ json_add_string "log" "0"
else
- _extra_param="${_extra_param} -log 1 -logfile ${log_file}"
+ json_add_string "log" "1"
+ json_add_string "logfile" "${log_file}"
fi
[ -z "$loglevel" ] && local loglevel=$(config_t_get global loglevel "warn")
[ "$loglevel" = "warning" ] && loglevel="warn"
- _extra_param="${_extra_param} -loglevel $loglevel"
-
- [ -n "$flag" ] && _extra_param="${_extra_param} -flag $flag"
- [ -n "$node" ] && _extra_param="${_extra_param} -node $node"
- [ -n "$server_host" ] && _extra_param="${_extra_param} -server_host $server_host"
- [ -n "$server_port" ] && _extra_param="${_extra_param} -server_port $server_port"
- [ -n "$tcp_redir_port" ] && _extra_param="${_extra_param} -tcp_redir_port $tcp_redir_port"
- [ -n "$tcp_proxy_way" ] && _extra_param="${_extra_param} -tcp_proxy_way $tcp_proxy_way"
- [ -n "$udp_redir_port" ] && _extra_param="${_extra_param} -udp_redir_port $udp_redir_port"
- [ -n "$socks_address" ] && _extra_param="${_extra_param} -local_socks_address $socks_address"
- [ -n "$socks_port" ] && _extra_param="${_extra_param} -local_socks_port $socks_port"
- [ -n "$socks_username" ] && [ -n "$socks_password" ] && _extra_param="${_extra_param} -local_socks_username $socks_username -local_socks_password $socks_password"
- [ -n "$http_address" ] && _extra_param="${_extra_param} -local_http_address $http_address"
- [ -n "$http_port" ] && _extra_param="${_extra_param} -local_http_port $http_port"
- [ -n "$http_username" ] && [ -n "$http_password" ] && _extra_param="${_extra_param} -local_http_username $http_username -local_http_password $http_password"
- [ -n "$dns_socks_address" ] && [ -n "$dns_socks_port" ] && _extra_param="${_extra_param} -dns_socks_address ${dns_socks_address} -dns_socks_port ${dns_socks_port}"
- [ -n "$dns_listen_port" ] && _extra_param="${_extra_param} -dns_listen_port ${dns_listen_port}"
- [ -n "$dns_cache" ] && _extra_param="${_extra_param} -dns_cache ${dns_cache}"
+ json_add_string "loglevel" "$loglevel"
+
+ [ -n "$flag" ] && json_add_string "flag" "$flag"
+ [ -n "$node" ] && json_add_string "node" "$node"
+ [ -n "$server_host" ] && json_add_string "server_host" "$server_host"
+ [ -n "$server_port" ] && json_add_string "server_port" "$server_port"
+ [ -n "$tcp_redir_port" ] && json_add_string "tcp_redir_port" "$tcp_redir_port"
+ [ -n "$tcp_proxy_way" ] && json_add_string "tcp_proxy_way" "$tcp_proxy_way"
+ [ -n "$udp_redir_port" ] && json_add_string "udp_redir_port" "$udp_redir_port"
+ [ -n "$socks_address" ] && json_add_string "local_socks_address" "$socks_address"
+ [ -n "$socks_port" ] && json_add_string "local_socks_port" "$socks_port"
+ [ -n "$socks_username" ] && [ -n "$socks_password" ] && {
+ json_add_string "local_socks_username" "$socks_username"
+ json_add_string "local_socks_password" "$socks_password"
+ }
+ [ -n "$http_address" ] && json_add_string "local_http_address" "$http_address"
+ [ -n "$http_port" ] && json_add_string "local_http_port" "$http_port"
+ [ -n "$http_username" ] && [ -n "$http_password" ] && {
+ json_add_string "local_http_username" "$http_username"
+ json_add_string "local_http_password" "$http_password"
+ }
+ [ -n "$dns_socks_address" ] && [ -n "$dns_socks_port" ] && {
+ json_add_string "dns_socks_address" "${dns_socks_address}"
+ json_add_string "dns_socks_port" "${dns_socks_port}"
+ }
+ [ -n "$dns_listen_port" ] && json_add_string "dns_listen_port" "${dns_listen_port}"
+ [ -n "$dns_cache" ] && json_add_string "dns_cache" "${dns_cache}"
if [ -n "$direct_dns_udp_server" ]; then
direct_dns_port=$(echo ${direct_dns_udp_server} | awk -F '#' '{print $2}')
- _extra_param="${_extra_param} -direct_dns_udp_server $(echo ${direct_dns_udp_server} | awk -F '#' '{print $1}')"
+ json_add_string "direct_dns_udp_server" "$(echo ${direct_dns_udp_server} | awk -F '#' '{print $1}')"
elif [ -n "$direct_dns_tcp_server" ]; then
direct_dns_port=$(echo ${direct_dns_tcp_server} | awk -F '#' '{print $2}')
- _extra_param="${_extra_param} -direct_dns_tcp_server $(echo ${direct_dns_tcp_server} | awk -F '#' '{print $1}')"
+ json_add_string "direct_dns_tcp_server" "$(echo ${direct_dns_tcp_server} | awk -F '#' '{print $1}')"
else
local local_dns=$(echo -n $(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n1) | tr " " ",")
- _extra_param="${_extra_param} -direct_dns_udp_server $(echo ${local_dns} | awk -F '#' '{print $1}')"
+ json_add_string "direct_dns_udp_server" "$(echo ${local_dns} | awk -F '#' '{print $1}')"
direct_dns_port=$(echo ${local_dns} | awk -F '#' '{print $2}')
fi
- _extra_param="${_extra_param} -direct_dns_port ${direct_dns_port:-53}"
+ json_add_string "direct_dns_port" "${direct_dns_port:-53}"
direct_dns_query_strategy=${direct_dns_query_strategy:-UseIP}
- _extra_param="${_extra_param} -direct_dns_query_strategy ${direct_dns_query_strategy}"
+ json_add_string "direct_dns_query_strategy" "${direct_dns_query_strategy}"
- [ -n "$remote_dns_query_strategy" ] && _extra_param="${_extra_param} -remote_dns_query_strategy ${remote_dns_query_strategy}"
+ [ -n "$remote_dns_query_strategy" ] && json_add_string "remote_dns_query_strategy" "${remote_dns_query_strategy}"
case "$remote_dns_protocol" in
udp|tcp)
local _proto="$remote_dns_protocol"
local _dns=$(get_first_dns remote_dns_${_proto}_server 53 | sed 's/#/:/g')
local _dns_address=$(echo ${_dns} | awk -F ':' '{print $1}')
local _dns_port=$(echo ${_dns} | awk -F ':' '{print $2}')
- _extra_param="${_extra_param} -remote_dns_server ${_dns_address} -remote_dns_port ${_dns_port} -remote_dns_${_proto}_server ${_proto}://${_dns}"
+ json_add_string "remote_dns_server" "${_dns_address}"
+ json_add_string "remote_dns_port" "${_dns_port}"
+ json_add_string "remote_dns_${_proto}_server" "${_proto}://${_dns}"
;;
doh)
local _doh_url _doh_host _doh_port _doh_bootstrap
parse_doh "$remote_dns_doh" _doh_url _doh_host _doh_port _doh_bootstrap
- [ -n "$_doh_bootstrap" ] && _extra_param="${_extra_param} -remote_dns_server ${_doh_bootstrap}"
- _extra_param="${_extra_param} -remote_dns_port ${_doh_port} -remote_dns_doh_url ${_doh_url} -remote_dns_doh_host ${_doh_host}"
+ [ -n "$_doh_bootstrap" ] && json_add_string "remote_dns_server" "${_doh_bootstrap}"
+ json_add_string "remote_dns_port" "${_doh_port}"
+ json_add_string "remote_dns_doh_url" "${_doh_url}"
+ json_add_string "remote_dns_doh_host" "${_doh_host}"
;;
esac
- [ -n "$remote_dns_client_ip" ] && _extra_param="${_extra_param} -remote_dns_client_ip ${remote_dns_client_ip}"
- [ "$remote_fakedns" = "1" ] && _extra_param="${_extra_param} -remote_dns_fake 1"
- [ -n "$no_run" ] && _extra_param="${_extra_param} -no_run 1"
- lua $UTIL_SINGBOX gen_config ${_extra_param} > $config_file
+ [ -n "$remote_dns_client_ip" ] && json_add_string "remote_dns_client_ip" "${remote_dns_client_ip}"
+ [ "$remote_fakedns" = "1" ] && json_add_string "remote_dns_fake" "1"
+ [ -n "$no_run" ] && json_add_string "no_run" "1"
+ local _json_arg="$(json_dump)"
+ lua $UTIL_SINGBOX gen_config "${_json_arg}" > $config_file
[ -n "$no_run" ] || ln_run "$(first_type $(config_t_get global_app sing_box_file) sing-box)" "sing-box" $log_file run -c "$config_file"
}
@@ -180,7 +194,6 @@ run_xray() {
local flag type node tcp_redir_port tcp_proxy_way udp_redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
local dns_listen_port direct_dns_query_strategy direct_dns_port direct_dns_udp_server direct_dns_tcp_server remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_fakedns remote_dns_query_strategy dns_cache dns_socks_address dns_socks_port
local loglevel log_file config_file server_host server_port no_run
- local _extra_param=""
eval_set_val $@
[ -z "$type" ] && {
local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
@@ -190,67 +203,82 @@ run_xray() {
fi
}
[ -z "$type" ] && return 1
+ json_init
[ -n "$log_file" ] || local log_file="/dev/null"
[ -z "$loglevel" ] && local loglevel=$(config_t_get global loglevel "warning")
- [ -n "$flag" ] && _extra_param="${_extra_param} -flag $flag"
- [ -n "$node" ] && _extra_param="${_extra_param} -node $node"
- [ -n "$server_host" ] && _extra_param="${_extra_param} -server_host $server_host"
- [ -n "$server_port" ] && _extra_param="${_extra_param} -server_port $server_port"
- [ -n "$tcp_redir_port" ] && _extra_param="${_extra_param} -tcp_redir_port $tcp_redir_port"
- [ -n "$tcp_proxy_way" ] && _extra_param="${_extra_param} -tcp_proxy_way $tcp_proxy_way"
- [ -n "$udp_redir_port" ] && _extra_param="${_extra_param} -udp_redir_port $udp_redir_port"
- [ -n "$socks_address" ] && _extra_param="${_extra_param} -local_socks_address $socks_address"
- [ -n "$socks_port" ] && _extra_param="${_extra_param} -local_socks_port $socks_port"
- [ -n "$socks_username" ] && [ -n "$socks_password" ] && _extra_param="${_extra_param} -local_socks_username $socks_username -local_socks_password $socks_password"
- [ -n "$http_address" ] && _extra_param="${_extra_param} -local_http_address $http_address"
- [ -n "$http_port" ] && _extra_param="${_extra_param} -local_http_port $http_port"
- [ -n "$http_username" ] && [ -n "$http_password" ] && _extra_param="${_extra_param} -local_http_username $http_username -local_http_password $http_password"
- [ -n "$dns_socks_address" ] && [ -n "$dns_socks_port" ] && _extra_param="${_extra_param} -dns_socks_address ${dns_socks_address} -dns_socks_port ${dns_socks_port}"
- [ -n "$dns_listen_port" ] && _extra_param="${_extra_param} -dns_listen_port ${dns_listen_port}"
+ [ -n "$flag" ] && json_add_string "flag" "$flag"
+ [ -n "$node" ] && json_add_string "node" "$node"
+ [ -n "$server_host" ] && json_add_string "server_host" "$server_host"
+ [ -n "$server_port" ] && json_add_string "server_port" "$server_port"
+ [ -n "$tcp_redir_port" ] && json_add_string "tcp_redir_port" "$tcp_redir_port"
+ [ -n "$tcp_proxy_way" ] && json_add_string "tcp_proxy_way" "$tcp_proxy_way"
+ [ -n "$udp_redir_port" ] && json_add_string "udp_redir_port" "$udp_redir_port"
+ [ -n "$socks_address" ] && json_add_string "local_socks_address" "$socks_address"
+ [ -n "$socks_port" ] && json_add_string "local_socks_port" "$socks_port"
+ [ -n "$socks_username" ] && [ -n "$socks_password" ] && {
+ json_add_string "local_socks_username" "$socks_username"
+ json_add_string "local_socks_password" "$socks_password"
+ }
+ [ -n "$http_address" ] && json_add_string "local_http_address" "$http_address"
+ [ -n "$http_port" ] && json_add_string "local_http_port" "$http_port"
+ [ -n "$http_username" ] && [ -n "$http_password" ] && {
+ json_add_string "local_http_username" "$http_username"
+ json_add_string "local_http_password" "$http_password"
+ }
+ [ -n "$dns_socks_address" ] && [ -n "$dns_socks_port" ] && {
+ json_add_string "dns_socks_address" "${dns_socks_address}"
+ json_add_string "dns_socks_port" "${dns_socks_port}"
+ }
+ [ -n "$dns_listen_port" ] && json_add_string "dns_listen_port" "${dns_listen_port}"
if [ -n "$direct_dns_udp_server" ]; then
direct_dns_port=$(echo ${direct_dns_udp_server} | awk -F '#' '{print $2}')
- _extra_param="${_extra_param} -direct_dns_udp_server $(echo ${direct_dns_udp_server} | awk -F '#' '{print $1}')"
+ json_add_string "direct_dns_udp_server" "$(echo ${direct_dns_udp_server} | awk -F '#' '{print $1}')"
elif [ -n "$direct_dns_tcp_server" ]; then
direct_dns_port=$(echo ${direct_dns_tcp_server} | awk -F '#' '{print $2}')
- _extra_param="${_extra_param} -direct_dns_tcp_server $(echo ${direct_dns_tcp_server} | awk -F '#' '{print $1}')"
+ json_add_string "direct_dns_tcp_server" "$(echo ${direct_dns_tcp_server} | awk -F '#' '{print $1}')"
else
local local_dns=$(echo -n $(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n1) | tr " " ",")
- _extra_param="${_extra_param} -direct_dns_udp_server $(echo ${local_dns} | awk -F '#' '{print $1}')"
+ json_add_string "direct_dns_udp_server" "$(echo ${local_dns} | awk -F '#' '{print $1}')"
direct_dns_port=$(echo ${local_dns} | awk -F '#' '{print $2}')
fi
- _extra_param="${_extra_param} -direct_dns_port ${direct_dns_port:-53}"
+ json_add_string "direct_dns_port" "${direct_dns_port:-53}"
direct_dns_query_strategy=${direct_dns_query_strategy:-UseIP}
- _extra_param="${_extra_param} -direct_dns_query_strategy ${direct_dns_query_strategy}"
- [ -n "$remote_dns_query_strategy" ] && _extra_param="${_extra_param} -remote_dns_query_strategy ${remote_dns_query_strategy}"
- [ -n "$remote_dns_client_ip" ] && _extra_param="${_extra_param} -remote_dns_client_ip ${remote_dns_client_ip}"
- [ "$remote_fakedns" = "1" ] && _extra_param="${_extra_param} -remote_dns_fake 1"
- [ -n "$dns_cache" ] && _extra_param="${_extra_param} -dns_cache ${dns_cache}"
+ json_add_string "direct_dns_query_strategy" "${direct_dns_query_strategy}"
+ [ -n "$remote_dns_query_strategy" ] && json_add_string "remote_dns_query_strategy" "${remote_dns_query_strategy}"
+ [ -n "$remote_dns_client_ip" ] && json_add_string "remote_dns_client_ip" "${remote_dns_client_ip}"
+ [ "$remote_fakedns" = "1" ] && json_add_string "remote_dns_fake" "1"
+ [ -n "$dns_cache" ] && json_add_string "dns_cache" "${dns_cache}"
case "$remote_dns_protocol" in
udp)
local _dns=$(get_first_dns remote_dns_udp_server 53 | sed 's/#/:/g')
local _dns_address=$(echo ${_dns} | awk -F ':' '{print $1}')
local _dns_port=$(echo ${_dns} | awk -F ':' '{print $2}')
- _extra_param="${_extra_param} -remote_dns_udp_server ${_dns_address} -remote_dns_udp_port ${_dns_port}"
+ json_add_string "remote_dns_udp_server" "${_dns_address}"
+ json_add_string "remote_dns_udp_port" "${_dns_port}"
;;
tcp|tcp+doh)
local _dns=$(get_first_dns remote_dns_tcp_server 53 | sed 's/#/:/g')
local _dns_address=$(echo ${_dns} | awk -F ':' '{print $1}')
local _dns_port=$(echo ${_dns} | awk -F ':' '{print $2}')
- _extra_param="${_extra_param} -remote_dns_tcp_server ${_dns_address} -remote_dns_tcp_port ${_dns_port}"
+ json_add_string "remote_dns_tcp_server" "${_dns_address}"
+ json_add_string "remote_dns_tcp_port" "${_dns_port}"
[ "$remote_dns_protocol" = "tcp+doh" ] && {
local _doh_url _doh_host _doh_port _doh_bootstrap
parse_doh "$remote_dns_doh" _doh_url _doh_host _doh_port _doh_bootstrap
- [ -n "$_doh_bootstrap" ] && _extra_param="${_extra_param} -remote_dns_doh_ip ${_doh_bootstrap}"
- _extra_param="${_extra_param} -remote_dns_doh_port ${_doh_port} -remote_dns_doh_url ${_doh_url} -remote_dns_doh_host ${_doh_host}"
+ [ -n "$_doh_bootstrap" ] && json_add_string "remote_dns_doh_ip" "${_doh_bootstrap}"
+ json_add_string "remote_dns_doh_port" "${_doh_port}"
+ json_add_string "remote_dns_doh_url" "${_doh_url}"
+ json_add_string "remote_dns_doh_host" "${_doh_host}"
}
;;
esac
- _extra_param="${_extra_param} -loglevel $loglevel"
- [ -n "$no_run" ] && _extra_param="${_extra_param} -no_run 1"
- lua $UTIL_XRAY gen_config ${_extra_param} > $config_file
+ json_add_string "loglevel" "$loglevel"
+ [ -n "$no_run" ] && json_add_string "no_run" "1"
+ local _json_arg="$(json_dump)"
+ lua $UTIL_XRAY gen_config "${_json_arg}" > $config_file
[ -n "$no_run" ] || ln_run "$(first_type $(config_t_get global_app ${type}_file) ${type})" ${type} $log_file run -c "$config_file"
}
@@ -350,6 +378,10 @@ run_socks() {
}
[ "$bind" != "127.0.0.1" ] && echolog " - Socks节点:[$remarks]${tmp},启动 ${bind}:${socks_port}"
+ json_init
+ json_add_string "node" "${node}"
+ json_add_string "server_host" "${server_host}"
+ json_add_string "server_port" "${server_port}"
case "$type" in
socks)
local _socks_address _socks_port _socks_username _socks_password
@@ -365,18 +397,28 @@ run_socks() {
[ "$http_port" != "0" ] && {
http_flag=1
config_file="${config_file//SOCKS/HTTP_SOCKS}"
- local _extra_param="-local_http_address $bind -local_http_port $http_port"
+ json_add_string "local_http_address" "$bind"
+ json_add_string "local_http_port" "$http_port"
}
+ json_add_null "server_host"
+ json_add_null "server_port"
+ json_add_string "local_socks_address" "$bind"
+ json_add_string "local_socks_port" "$socks_port"
+ json_add_string "server_proto" "socks"
+ json_add_string "server_address" "${_socks_address}"
+ json_add_string "server_port" "${_socks_port}"
+ json_add_string "server_username" "${_socks_username}"
+ json_add_string "server_password" "${_socks_password}"
local bin=$(first_type $(config_t_get global_app sing_box_file) sing-box)
if [ -n "$bin" ]; then
type="sing-box"
- lua $UTIL_SINGBOX gen_proto_config -local_socks_address $bind -local_socks_port $socks_port ${_extra_param} -server_proto socks -server_address ${_socks_address} -server_port ${_socks_port} -server_username ${_socks_username} -server_password ${_socks_password} > $config_file
+ lua $UTIL_SINGBOX gen_proto_config "$(json_dump)" > $config_file
ln_run "$bin" ${type} $log_file run -c "$config_file"
else
bin=$(first_type $(config_t_get global_app xray_file) xray)
[ -n "$bin" ] && {
type="xray"
- lua $UTIL_XRAY gen_proto_config -local_socks_address $bind -local_socks_port $socks_port ${_extra_param} -server_proto socks -server_address ${_socks_address} -server_port ${_socks_port} -server_username ${_socks_username} -server_password ${_socks_password} > $config_file
+ lua $UTIL_XRAY gen_proto_config "$(json_dump)" > $config_file
ln_run "$bin" ${type} $log_file run -c "$config_file"
}
fi
@@ -402,50 +444,68 @@ run_socks() {
run_xray flag=$flag node=$node socks_address=$bind socks_port=$socks_port config_file=$config_file log_file=$log_file ${_args}
;;
trojan*)
- lua $UTIL_TROJAN gen_config -node $node -run_type client -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $server_port > $config_file
+ json_add_string "run_type" "client"
+ json_add_string "local_addr" "$bind"
+ json_add_string "local_port" "$socks_port"
+ lua $UTIL_TROJAN gen_config "$(json_dump)" > $config_file
[ -n "$no_run" ] || ln_run "$(first_type ${type})" "${type}" $log_file -c "$config_file"
;;
naiveproxy)
- lua $UTIL_NAIVE gen_config -node $node -run_type socks -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $server_port > $config_file
+ json_add_string "run_type" "socks"
+ json_add_string "local_addr" "$bind"
+ json_add_string "local_port" "$socks_port"
+ lua $UTIL_NAIVE gen_config "$(json_dump)" > $config_file
[ -n "$no_run" ] || ln_run "$(first_type naive)" naive $log_file "$config_file"
;;
ssr)
- lua $UTIL_SS gen_config -node $node -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $server_port > $config_file
+ json_add_string "local_addr" "$bind"
+ json_add_string "local_port" "$socks_port"
+ lua $UTIL_SS gen_config "$(json_dump)" > $config_file
[ -n "$no_run" ] || ln_run "$(first_type ssr-local)" "ssr-local" $log_file -c "$config_file" -v -u
;;
ss)
[ -n "$no_run" ] || {
local plugin_sh="${config_file%.json}_plugin.sh"
- local _extra_param="-plugin_sh $plugin_sh"
+ json_add_string "plugin_sh" "$plugin_sh"
}
- lua $UTIL_SS gen_config -node $node -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $server_port -mode tcp_and_udp ${_extra_param} > $config_file
+ json_add_string "local_addr" "$bind"
+ json_add_string "local_port" "$socks_port"
+ json_add_string "mode" "tcp_and_udp"
+ lua $UTIL_SS gen_config "$(json_dump)" > $config_file
[ -n "$no_run" ] || ln_run "$(first_type ss-local)" "ss-local" $log_file -c "$config_file" -v
;;
ss-rust)
- local _extra_param
[ "$http_port" != "0" ] && {
http_flag=1
config_file="${config_file//SOCKS/HTTP_SOCKS}"
- _extra_param="-local_http_address $bind -local_http_port $http_port"
+ json_add_string "local_http_address" "$bind"
+ json_add_string "local_http_port" "$http_port"
}
[ -n "$no_run" ] || {
local plugin_sh="${config_file%.json}_plugin.sh"
- _extra_param="${_extra_param:+$_extra_param }-plugin_sh $plugin_sh"
+ json_add_string "plugin_sh" "$plugin_sh"
}
- lua $UTIL_SS gen_config -node $node -local_socks_address $bind -local_socks_port $socks_port -server_host $server_host -server_port $server_port ${_extra_param} > $config_file
+ json_add_string "local_socks_address" "$bind"
+ json_add_string "local_socks_port" "$socks_port"
+ lua $UTIL_SS gen_config "$(json_dump)" > $config_file
[ -n "$no_run" ] || ln_run "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v
;;
hysteria2)
[ "$http_port" != "0" ] && {
http_flag=1
config_file="${config_file//SOCKS/HTTP_SOCKS}"
- local _extra_param="-local_http_address $bind -local_http_port $http_port"
+ json_add_string "local_http_address" "$bind"
+ json_add_string "local_http_port" "$http_port"
}
- lua $UTIL_HYSTERIA2 gen_config -node $node -local_socks_address $bind -local_socks_port $socks_port -server_host $server_host -server_port $server_port ${_extra_param} > $config_file
+ json_add_string "local_socks_address" "$bind"
+ json_add_string "local_socks_port" "$socks_port"
+ lua $UTIL_HYSTERIA2 gen_config "$(json_dump)" > $config_file
[ -n "$no_run" ] || ln_run "$(first_type $(config_t_get global_app hysteria_file))" "hysteria" $log_file -c "$config_file" client
;;
tuic)
- lua $UTIL_TUIC gen_config -node $node -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $server_port > $config_file
+ json_add_string "local_addr" "$bind"
+ json_add_string "local_port" "$socks_port"
+ lua $UTIL_TUIC gen_config "$(json_dump)" > $config_file
[ -n "$no_run" ] || ln_run "$(first_type tuic-client)" "tuic-client" $log_file -c "$config_file"
;;
esac
@@ -455,15 +515,25 @@ run_socks() {
# http to socks
[ -z "$http_flag" ] && [ "$http_port" != "0" ] && [ -n "$http_config_file" ] && [ "$type" != "sing-box" ] && [ "$type" != "xray" ] && [ "$type" != "socks" ] && {
local bin=$(first_type $(config_t_get global_app sing_box_file) sing-box)
+ json_add_null "node"
+ json_add_null "server_host"
+ json_add_null "server_port"
+ json_add_string "local_http_address" "$bind"
+ json_add_string "local_http_port" "$http_port"
+ json_add_string "server_proto" "socks"
+ json_add_string "server_address" "127.0.0.1"
+ json_add_string "server_port" "$socks_port"
+ json_add_string "server_username" "$_username"
+ json_add_string "server_password" "$_password"
if [ -n "$bin" ]; then
type="sing-box"
- lua $UTIL_SINGBOX gen_proto_config -local_http_address $bind -local_http_port $http_port -server_proto socks -server_address "127.0.0.1" -server_port $socks_port -server_username $_username -server_password $_password > $http_config_file
+ lua $UTIL_SINGBOX gen_proto_config "$(json_dump)" > $http_config_file
[ -n "$no_run" ] || ln_run "$bin" ${type} /dev/null run -c "$http_config_file"
else
bin=$(first_type $(config_t_get global_app xray_file) xray)
[ -n "$bin" ] && type="xray"
[ -z "$type" ] && return 1
- lua $UTIL_XRAY gen_proto_config local_http_address $bind -local_http_port $http_port -server_proto socks -server_address "127.0.0.1" -server_port $socks_port -server_username $_username -server_password $_password > $http_config_file
+ lua $UTIL_XRAY gen_proto_config "$(json_dump)" > $http_config_file
[ -n "$no_run" ] || ln_run "$bin" ${type} /dev/null run -c "$http_config_file"
fi
}
@@ -513,6 +583,8 @@ run_redir() {
}
[ "$bind" != "127.0.0.1" ] && echolog "${PROTO}节点:[$remarks],监听端口:$local_port"
+ json_init
+ json_add_string "node" "${node}"
case "$PROTO" in
UDP)
case "$type" in
@@ -553,30 +625,41 @@ run_redir() {
;;
trojan*)
local loglevel=$(config_t_get global trojan_loglevel "2")
- lua $UTIL_TROJAN gen_config -node $node -run_type nat -local_addr "0.0.0.0" -local_port $local_port -loglevel $loglevel > $config_file
+ json_add_string "run_type" "nat"
+ json_add_string "local_addr" "0.0.0.0"
+ json_add_string "local_port" "$local_port"
+ json_add_string "loglevel" "$loglevel"
+ lua $UTIL_TROJAN gen_config "$(json_dump)" > $config_file
ln_run "$(first_type ${type})" "${type}" $log_file -c "$config_file"
;;
naiveproxy)
echolog "Naiveproxy不支持UDP转发!"
;;
ssr)
- lua $UTIL_SS gen_config -node $node -local_addr "0.0.0.0" -local_port $local_port > $config_file
+ json_add_string "local_addr" "0.0.0.0"
+ json_add_string "local_port" "$local_port"
+ lua $UTIL_SS gen_config "$(json_dump)" > $config_file
ln_run "$(first_type ssr-redir)" "ssr-redir" $log_file -c "$config_file" -v -U
;;
ss)
local plugin_sh="${config_file%.json}_plugin.sh"
- local _extra_param="-plugin_sh $plugin_sh"
- lua $UTIL_SS gen_config -node $node -local_addr "0.0.0.0" -local_port $local_port -mode udp_only $_extra_param > $config_file
+ json_add_string "plugin_sh" "$plugin_sh"
+ json_add_string "local_addr" "0.0.0.0"
+ json_add_string "local_port" "$local_port"
+ json_add_string "mode" "udp_only"
+ lua $UTIL_SS gen_config "$(json_dump)" > $config_file
ln_run "$(first_type ss-redir)" "ss-redir" $log_file -c "$config_file" -v
;;
ss-rust)
local plugin_sh="${config_file%.json}_plugin.sh"
- local _extra_param="-plugin_sh $plugin_sh"
- lua $UTIL_SS gen_config -node $node -local_udp_redir_port $local_port $_extra_param > $config_file
+ json_add_string "plugin_sh" "$plugin_sh"
+ json_add_string "local_udp_redir_port" "$local_port"
+ lua $UTIL_SS gen_config "$(json_dump)" > $config_file
ln_run "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v
;;
hysteria2)
- lua $UTIL_HYSTERIA2 gen_config -node $node -local_udp_redir_port $local_port > $config_file
+ json_add_string "local_udp_redir_port" "$local_port"
+ lua $UTIL_HYSTERIA2 gen_config "$(json_dump)" > $config_file
ln_run "$(first_type $(config_t_get global_app hysteria_file))" "hysteria" $log_file -c "$config_file" client
;;
tuic)
@@ -794,89 +877,104 @@ run_redir() {
run_xray flag=$_flag node=$node tcp_redir_port=$local_port tcp_proxy_way=$TCP_PROXY_WAY config_file=$config_file log_file=$log_file ${_args}
;;
trojan*)
- [ "${TCP_PROXY_WAY}" = "tproxy" ] && lua_tproxy_arg="-use_tproxy true"
+ [ "${TCP_PROXY_WAY}" = "tproxy" ] && json_add_string "use_tproxy" "true"
[ "$TCP_UDP" = "1" ] && {
config_file="${config_file//TCP/TCP_UDP}"
UDP_REDIR_PORT=$TCP_REDIR_PORT
unset UDP_NODE
}
local loglevel=$(config_t_get global trojan_loglevel "2")
- lua $UTIL_TROJAN gen_config -node $node -run_type nat -local_addr "0.0.0.0" -local_port $local_port -loglevel $loglevel $lua_tproxy_arg > $config_file
+ json_add_string "run_type" "nat"
+ json_add_string "local_addr" "0.0.0.0"
+ json_add_string "local_port" "$local_port"
+ json_add_string "loglevel" "$loglevel"
+ lua $UTIL_TROJAN gen_config "$(json_dump)" > $config_file
ln_run "$(first_type ${type})" "${type}" $log_file -c "$config_file"
;;
naiveproxy)
- lua $UTIL_NAIVE gen_config -node $node -run_type redir -local_addr "0.0.0.0" -local_port $local_port > $config_file
+ json_add_string "run_type" "redir"
+ json_add_string "local_addr" "0.0.0.0"
+ json_add_string "local_port" "$local_port"
+ lua $UTIL_NAIVE gen_config "$(json_dump)" > $config_file
ln_run "$(first_type naive)" naive $log_file "$config_file"
;;
ssr)
- [ "${TCP_PROXY_WAY}" = "tproxy" ] && lua_tproxy_arg="-tcp_tproxy true"
+ [ "${TCP_PROXY_WAY}" = "tproxy" ] && json_add_string "tcp_tproxy" "true"
+ local _extra_param
[ "$TCP_UDP" = "1" ] && {
config_file="${config_file//TCP/TCP_UDP}"
UDP_REDIR_PORT=$TCP_REDIR_PORT
unset UDP_NODE
_extra_param="-u"
}
- lua $UTIL_SS gen_config -node $node -local_addr "0.0.0.0" -local_port $local_port $lua_tproxy_arg > $config_file
+ json_add_string "local_addr" "0.0.0.0"
+ json_add_string "local_port" "$local_port"
+ lua $UTIL_SS gen_config "$(json_dump)" > $config_file
ln_run "$(first_type ssr-redir)" "ssr-redir" $log_file -c "$config_file" -v ${_extra_param}
;;
ss)
- [ "${TCP_PROXY_WAY}" = "tproxy" ] && lua_tproxy_arg="-tcp_tproxy true"
- local lua_mode_arg="-mode tcp_only"
- [ "$TCP_UDP" = "1" ] && {
+ [ "${TCP_PROXY_WAY}" = "tproxy" ] && json_add_string "tcp_tproxy" "true"
+ if [ "$TCP_UDP" = "1" ]; then
config_file="${config_file//TCP/TCP_UDP}"
UDP_REDIR_PORT=$TCP_REDIR_PORT
unset UDP_NODE
- lua_mode_arg="-mode tcp_and_udp"
- }
+ json_add_string "mode" "tcp_and_udp"
+ else
+ json_add_string "mode" "tcp_only"
+ fi
local plugin_sh="${config_file%.json}_plugin.sh"
- lua_mode_arg="${lua_mode_arg} -plugin_sh $plugin_sh"
- lua $UTIL_SS gen_config -node $node -local_addr "0.0.0.0" -local_port $local_port $lua_mode_arg $lua_tproxy_arg > $config_file
+ json_add_string "plugin_sh" "$plugin_sh"
+ json_add_string "local_addr" "0.0.0.0"
+ json_add_string "local_port" "$local_port"
+ lua $UTIL_SS gen_config "$(json_dump)" > $config_file
ln_run "$(first_type ss-redir)" "ss-redir" $log_file -c "$config_file" -v
;;
ss-rust)
- local _extra_param="-local_tcp_redir_port $local_port"
- [ "${TCP_PROXY_WAY}" = "tproxy" ] && _extra_param="${_extra_param} -tcp_tproxy true"
+ json_add_string "local_tcp_redir_port" "$local_port"
+ [ "${TCP_PROXY_WAY}" = "tproxy" ] && json_add_string "tcp_tproxy" "true"
[ "$tcp_node_socks" = "1" ] && {
tcp_node_socks_flag=1
config_file="${config_file//TCP/TCP_SOCKS}"
- _extra_param="${_extra_param} -local_socks_address ${tcp_node_socks_bind} -local_socks_port ${tcp_node_socks_port}"
+ json_add_string "local_socks_address" "${tcp_node_socks_bind}"
+ json_add_string "local_socks_port" "${tcp_node_socks_port}"
}
[ "$tcp_node_http" = "1" ] && {
tcp_node_http_flag=1
config_file="${config_file//TCP/TCP_HTTP}"
- _extra_param="${_extra_param} -local_http_port ${tcp_node_http_port}"
+ json_add_string "local_http_port" "${tcp_node_http_port}"
}
[ "$TCP_UDP" = "1" ] && {
config_file="${config_file//TCP/TCP_UDP}"
UDP_REDIR_PORT=$TCP_REDIR_PORT
unset UDP_NODE
- _extra_param="${_extra_param} -local_udp_redir_port $local_port"
+ json_add_string "local_udp_redir_port" "$local_port"
}
local plugin_sh="${config_file%.json}_plugin.sh"
- _extra_param="${_extra_param} -plugin_sh $plugin_sh"
- lua $UTIL_SS gen_config -node $node ${_extra_param} > $config_file
+ json_add_string "plugin_sh" "$plugin_sh"
+ lua $UTIL_SS gen_config "$(json_dump)" > $config_file
ln_run "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v
;;
hysteria2)
- local _extra_param="-local_tcp_redir_port $local_port"
+ json_add_string "local_tcp_redir_port" "$local_port"
[ "$tcp_node_socks" = "1" ] && {
tcp_node_socks_flag=1
config_file="${config_file//TCP/TCP_SOCKS}"
- _extra_param="${_extra_param} -local_socks_address ${tcp_node_socks_bind} -local_socks_port ${tcp_node_socks_port}"
+ json_add_string "local_socks_address" "${tcp_node_socks_bind}"
+ json_add_string "local_socks_port" "${tcp_node_socks_port}"
}
[ "$tcp_node_http" = "1" ] && {
tcp_node_http_flag=1
config_file="${config_file//TCP/TCP_HTTP}"
- _extra_param="${_extra_param} -local_http_port ${tcp_node_http_port}"
+ json_add_string "local_http_port" "${tcp_node_http_port}"
}
[ "$TCP_UDP" = "1" ] && {
config_file="${config_file//TCP/TCP_UDP}"
UDP_REDIR_PORT=$TCP_REDIR_PORT
unset UDP_NODE
- _extra_param="${_extra_param} -local_udp_redir_port $local_port"
+ json_add_string "local_udp_redir_port" "$local_port"
}
- _extra_param="${_extra_param} -tcp_proxy_way ${TCP_PROXY_WAY}"
- lua $UTIL_HYSTERIA2 gen_config -node $node ${_extra_param} > $config_file
+ json_add_string "tcp_proxy_way" "${TCP_PROXY_WAY}"
+ lua $UTIL_HYSTERIA2 gen_config "$(json_dump)" > $config_file
ln_run "$(first_type $(config_t_get global_app hysteria_file))" "hysteria" $log_file -c "$config_file" client
;;
esac
@@ -1674,6 +1772,12 @@ acl_app() {
fi
}
[ -n "$udp_node" ] && {
+ [ -n "$tcp_node" ] && {
+ local protocol=$(config_n_get $tcp_node protocol)
+ [ "$protocol" = "_shunt" ] && [ "$udp_node" != "default" ] && {
+ udp_node = "tcp"
+ }
+ }
if [ "$udp_node" = "default" ]; then
local GLOBAL_UDP_NODE=$(get_cache_var "ACL_GLOBAL_UDP_node")
[ -n "${GLOBAL_UDP_NODE}" ] && GLOBAL_UDP_redir_port=$(get_cache_var "ACL_GLOBAL_UDP_redir_port")
@@ -1840,6 +1944,13 @@ get_config() {
elif [ "$UDP_NODE" = "$TCP_NODE" ]; then
TCP_UDP=1
fi
+ [ -n "$TCP_NODE" ] && {
+ local protocol=$(config_n_get $TCP_NODE protocol)
+ [ "$protocol" = "_shunt" ] && [ -n "$UDP_NODE" ] && {
+ UDP_NODE=$TCP_NODE
+ TCP_UDP=1
+ }
+ }
[ "$ENABLED" = 1 ] && {
local _node
for _node in "$TCP_NODE" "$UDP_NODE"; do
@@ -1930,8 +2041,6 @@ get_config() {
SMARTDNS_LISTEN_PORT=${NEXT_DNS_LISTEN_PORT}
NEXT_DNS_LISTEN_PORT=$(expr $NEXT_DNS_LISTEN_PORT + 1)
LOCAL_DNS="127.0.0.1#${SMARTDNS_LOCAL_PORT}"
- uci -q set smartdns.@smartdns[0].auto_set_dnsmasq=0
- uci commit smartdns
}
}
diff --git a/applications/luci-app-passwall/root/usr/share/passwall/helper_chinadns_add.lua b/applications/luci-app-passwall/root/usr/share/passwall/helper_chinadns_add.lua
index 00e7ceed350..b05479866e5 100644
--- a/applications/luci-app-passwall/root/usr/share/passwall/helper_chinadns_add.lua
+++ b/applications/luci-app-passwall/root/usr/share/passwall/helper_chinadns_add.lua
@@ -33,6 +33,11 @@ local FLAG_PATH = TMP_ACL_PATH .. "/" .. FLAG
local config_lines = {}
local tmp_lines = {}
local USE_GEOVIEW = uci:get(appname, "@global_rules[0]", "enable_geoview")
+local IS_SHUNT_NODE = uci:get(appname, TCP_NODE, "protocol") == "_shunt"
+
+if IS_SHUNT_NODE then
+ REMOTE_FAKEDNS = uci:get(appname, TCP_NODE, "fakedns") or "0"
+end
local function log(...)
if NO_LOGIC_LOG == "1" then
@@ -354,7 +359,7 @@ if CHNLIST ~= "0" and is_file_nonzero(RULES_PATH .. "/chnlist") then
end
--分流规则
-if uci:get(appname, TCP_NODE, "protocol") == "_shunt" then
+if IS_SHUNT_NODE then
local white_domain, lookup_white_domain = {}, {}
local shunt_domain, lookup_shunt_domain = {}, {}
local file_white_host = FLAG_PATH .. "/shunt_direct_host"
@@ -492,7 +497,7 @@ if CHNLIST == "proxy" then DEFAULT_TAG = "chn" end
--全局模式,默认使用远程DNS
if only_global then
DEFAULT_TAG = "gfw"
- if NO_IPV6_TRUST == "1" and uci:get(appname, TCP_NODE, "protocol") ~= "_shunt" then
+ if NO_IPV6_TRUST == "1" and not IS_SHUNT_NODE then
table.insert(config_lines, "no-ipv6")
end
end
diff --git a/applications/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq.lua b/applications/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq.lua
index 2470f21634a..44b8c6e37fd 100644
--- a/applications/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq.lua
+++ b/applications/luci-app-passwall/root/usr/share/passwall/helper_dnsmasq.lua
@@ -181,6 +181,11 @@ function add_rule(var)
local CACHE_DNS_PATH = CACHE_PATH .. "/" .. CACHE_FLAG
local CACHE_TEXT_FILE = CACHE_DNS_PATH .. ".txt"
local USE_CHINADNS_NG = "0"
+ local IS_SHUNT_NODE = uci:get(appname, TCP_NODE, "protocol") == "_shunt"
+
+ if IS_SHUNT_NODE then
+ REMOTE_FAKEDNS = uci:get(appname, TCP_NODE, "fakedns") or "0"
+ end
local list1 = {}
local excluded_domain = {}
@@ -540,7 +545,7 @@ function add_rule(var)
end
--分流规则
- if uci:get(appname, TCP_NODE, "protocol") == "_shunt" and USE_CHINADNS_NG == "0" then
+ if IS_SHUNT_NODE and USE_CHINADNS_NG == "0" then
local t = uci:get_all(appname, TCP_NODE)
local default_node_id = t["default_node"] or "_direct"
uci:foreach(appname, "shunt_rules", function(s)
diff --git a/applications/luci-app-passwall/root/usr/share/passwall/helper_smartdns_add.lua b/applications/luci-app-passwall/root/usr/share/passwall/helper_smartdns_add.lua
index 82326583f00..2f75b831cd1 100644
--- a/applications/luci-app-passwall/root/usr/share/passwall/helper_smartdns_add.lua
+++ b/applications/luci-app-passwall/root/usr/share/passwall/helper_smartdns_add.lua
@@ -40,6 +40,11 @@ local TMP_CONF_FILE = FLAG_PATH .. "/smartdns.conf"
local config_lines = {}
local tmp_lines = {}
local USE_GEOVIEW = uci:get(appname, "@global_rules[0]", "enable_geoview")
+local IS_SHUNT_NODE = uci:get(appname, TCP_NODE, "protocol") == "_shunt"
+
+if IS_SHUNT_NODE then
+ REMOTE_FAKEDNS = uci:get(appname, TCP_NODE, "fakedns") or "0"
+end
local function log(...)
if NO_LOGIC_LOG == "1" then
@@ -229,7 +234,7 @@ if DNS_MODE == "socks" then
end
table.insert(config_lines, server_param)
end
- REMOTE_FAKEDNS = 0
+ if not IS_SHUNT_NODE then REMOTE_FAKEDNS = "0" end
else
local server_param = string.format("server %s -group %s -exclude-default-group", TUN_DNS:gsub("#", ":"), REMOTE_GROUP)
table.insert(config_lines, server_param)
@@ -513,7 +518,7 @@ if CHN_LIST ~= "0" and is_file_nonzero(RULES_PATH .. "/chnlist") then
end
--分流规则
-if uci:get(appname, TCP_NODE, "protocol") == "_shunt" then
+if IS_SHUNT_NODE then
local white_domain, lookup_white_domain = {}, {}
local shunt_domain, lookup_shunt_domain = {}, {}
local file_white_host = FLAG_PATH .. "/shunt_direct_host"
diff --git a/applications/luci-app-passwall/root/usr/share/passwall/rule_update.lua b/applications/luci-app-passwall/root/usr/share/passwall/rule_update.lua
index b69d73c84c6..eac11ac664a 100755
--- a/applications/luci-app-passwall/root/usr/share/passwall/rule_update.lua
+++ b/applications/luci-app-passwall/root/usr/share/passwall/rule_update.lua
@@ -33,9 +33,13 @@ local asset_location = uci:get(name, "@global_rules[0]", "v2ray_location_asset")
local geo2rule = uci:get(name, "@global_rules[0]", "geo2rule") or "0"
local geoip_update_ok, geosite_update_ok = false, false
asset_location = asset_location:match("/$") and asset_location or (asset_location .. "/")
+local backup_path = "/tmp/bak_v2ray/"
+local rollback = false
if arg3 == "cron" then
arg2 = nil
+elseif arg3 == "rollback" then
+ rollback, geoip_update_ok, geosite_update_ok = true, true, true
end
local log = function(...)
@@ -388,7 +392,7 @@ local function GeoToRule(rule_name, rule_type, out_path)
end
--fetch rule
-local function fetch_rule(rule_name,rule_type,url,exclude_domain, max_retries)
+local function fetch_rule(rule_name, rule_type, url, exclude_domain, max_retries)
local sret = 200
local max_attempts = max_retries or 2
local rule_dataset = {}
@@ -504,7 +508,7 @@ local function fetch_rule(rule_name,rule_type,url,exclude_domain, max_retries)
os.execute(string.format("mv -f %s %s.nft", nft_file, rule_final_path))
end
os.execute(string.format("mv -f %s %s", file_tmp, rule_final_path))
- reboot = 1
+ if not rollback then reboot = 1 end
log(string.format("%s 更新成功,总规则数 %d 条。", rule_name, #result_list))
else
log(rule_name .. " 版本一致,无需更新。")
@@ -535,7 +539,7 @@ local function fetch_geofile(geo_name, geo_type, url)
local content = f:read("*l")
f:close()
if content then
- content = content:gsub(down_filename, tmp_path)
+ content = content:gsub("(%x+)%s+.+", "%1 " .. tmp_path)
f = io.open(sha_path, "w")
if f then
f:write(content)
@@ -565,7 +569,8 @@ local function fetch_geofile(geo_name, geo_type, url)
if sret_tmp == 200 then
if sha_verify then
if verify_sha256(sha_path) then
- sys.call(string.format("mkdir -p %s && cp -f %s %s", asset_location, tmp_path, asset_path))
+ sys.call(string.format("mkdir -p %s && mv -f %s %s", backup_path, asset_path, backup_path))
+ sys.call(string.format("mkdir -p %s && mv -f %s %s", asset_location, tmp_path, asset_path))
reboot = 1
log(geo_type .. " 更新成功。")
if geo_type == "geoip" then
@@ -582,7 +587,8 @@ local function fetch_geofile(geo_name, geo_type, url)
log(geo_type .. " 版本一致,无需更新。")
return 0
end
- sys.call(string.format("mkdir -p %s && cp -f %s %s", asset_location, tmp_path, asset_path))
+ sys.call(string.format("mkdir -p %s && mv -f %s %s", backup_path, asset_path, backup_path))
+ sys.call(string.format("mkdir -p %s && mv -f %s %s", asset_location, tmp_path, asset_path))
reboot = 1
log(geo_type .. " 更新成功。")
if geo_type == "geoip" then
@@ -643,6 +649,7 @@ if arg2 then
geosite_update = "1"
end
end)
+ if rollback then arg2 = nil end
else
gfwlist_update = uci:get(name, "@global_rules[0]", "gfwlist_update") or "1"
chnroute_update = uci:get(name, "@global_rules[0]", "chnroute_update") or "1"
@@ -670,13 +677,13 @@ local function remove_tmp_geofile(name)
end
if geo2rule == "1" then
- if geoip_update == "1" then
+ if geoip_update == "1" and not rollback then
log("geoip 开始更新...")
safe_call(fetch_geoip, "更新geoip发生错误...")
remove_tmp_geofile("geoip")
end
- if geosite_update == "1" then
+ if geosite_update == "1" and not rollback then
log("geosite 开始更新...")
safe_call(fetch_geosite, "更新geosite发生错误...")
remove_tmp_geofile("geosite")
@@ -685,22 +692,26 @@ if geo2rule == "1" then
-- 如果是手动更新(arg2存在)始终生成规则
local force_generate = (arg2 ~= nil)
- if geoip_update_ok or force_generate then
- if fs.access(asset_location .. "geoip.dat") then
- safe_call(fetch_chnroute, "生成chnroute发生错误...")
- safe_call(fetch_chnroute6, "生成chnroute6发生错误...")
- else
- log("geoip.dat 文件不存在,跳过规则生成。")
- end
+ if (geoip_update_ok or force_generate) and fs.access(asset_location .. "geoip.dat") then
+ if force_generate or chnroute_update == "1" then
+ safe_call(fetch_chnroute, "生成chnroute发生错误...")
+ end
+ if force_generate or chnroute6_update == "1" then
+ safe_call(fetch_chnroute6, "生成chnroute6发生错误...")
+ end
+ else
+ log("geoip.dat 文件不存在,跳过规则生成。")
end
- if geosite_update_ok or force_generate then
- if fs.access(asset_location .. "geosite.dat") then
- safe_call(fetch_gfwlist, "生成gfwlist发生错误...")
- safe_call(fetch_chnlist, "生成chnlist发生错误...")
- else
- log("geosite.dat 文件不存在,跳过规则生成。")
- end
+ if (geosite_update_ok or force_generate) and fs.access(asset_location .. "geosite.dat") then
+ if force_generate or gfwlist_update == "1" then
+ safe_call(fetch_gfwlist, "生成gfwlist发生错误...")
+ end
+ if force_generate or chnlist_update == "1" then
+ safe_call(fetch_chnlist, "生成chnlist发生错误...")
+ end
+ else
+ log("geosite.dat 文件不存在,跳过规则生成。")
end
else
if gfwlist_update == "1" then
@@ -732,13 +743,15 @@ else
end
end
-uci:set(name, "@global_rules[0]", "gfwlist_update", gfwlist_update)
-uci:set(name, "@global_rules[0]", "chnroute_update", chnroute_update)
-uci:set(name, "@global_rules[0]", "chnroute6_update", chnroute6_update)
-uci:set(name, "@global_rules[0]", "chnlist_update", chnlist_update)
-uci:set(name, "@global_rules[0]", "geoip_update", geoip_update)
-uci:set(name, "@global_rules[0]", "geosite_update", geosite_update)
-api.uci_save(uci, name, true)
+if not rollback then
+ uci:set(name, "@global_rules[0]", "gfwlist_update", gfwlist_update)
+ uci:set(name, "@global_rules[0]", "chnroute_update", chnroute_update)
+ uci:set(name, "@global_rules[0]", "chnroute6_update", chnroute6_update)
+ uci:set(name, "@global_rules[0]", "chnlist_update", chnlist_update)
+ uci:set(name, "@global_rules[0]", "geoip_update", geoip_update)
+ uci:set(name, "@global_rules[0]", "geosite_update", geosite_update)
+ api.uci_save(uci, name, true)
+end
if reboot == 1 then
if arg3 == "cron" then