diff --git a/package/lienol/luci-app-passwall/Makefile b/package/lienol/luci-app-passwall/Makefile
index 81dbc80417..ec7eb8fd24 100644
--- a/package/lienol/luci-app-passwall/Makefile
+++ b/package/lienol/luci-app-passwall/Makefile
@@ -7,8 +7,8 @@ include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
PKG_VERSION:=4
-PKG_RELEASE:=14
-PKG_DATE:=20210209
+PKG_RELEASE:=15
+PKG_DATE:=20210213
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
@@ -101,6 +101,7 @@ define Package/$(PKG_NAME)
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR:shadowsocksr-libev-ssr-local \
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Server:shadowsocksr-libev-ssr-server \
+PACKAGE_$(PKG_NAME)_INCLUDE_Xray:xray-core \
+ +PACKAGE_$(PKG_NAME)_INCLUDE_Xray:xray-geodata \
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan_Plus:trojan-plus \
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan_GO:trojan-go \
+PACKAGE_$(PKG_NAME)_INCLUDE_NaiveProxy:naiveproxy \
diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/api.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/api.lua
index 593c9cdf64..4b044ef385 100644
--- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/api.lua
+++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/api.lua
@@ -162,6 +162,24 @@ function is_finded(e)
return luci.sys.exec('type -t -p "/bin/%s" -p "%s" "%s"' % {e, get_customed_path(e), e}) ~= "" and true or false
end
+
+function clone(org)
+ local function copy(org, res)
+ for k,v in pairs(org) do
+ if type(v) ~= "table" then
+ res[k] = v;
+ else
+ res[k] = {};
+ copy(v, res[k])
+ end
+ end
+ end
+
+ local res = {}
+ copy(org, res)
+ return res
+end
+
function get_xray_path()
local path = uci_get_type("global_app", "xray_file")
return path
diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_xray.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_xray.lua
index 2c124ab5f4..6052b597d9 100644
--- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_xray.lua
+++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_xray.lua
@@ -25,7 +25,7 @@ local new_port
local ucursor = require"luci.model.uci".cursor()
local sys = require "luci.sys"
local json = require "luci.jsonc"
-local appname = "passwall"
+local appname = api.appname
local dns = nil
local inbounds = {}
local outbounds = {}
@@ -40,31 +40,48 @@ local function get_new_port()
return new_port
end
-function gen_outbound(node, tag, relay_port)
+function gen_outbound(node, tag, is_proxy)
local result = nil
- if node then
+ if node and node ~= "nil" then
local node_id = node[".name"]
if tag == nil then
tag = node_id
end
+
+ if is_proxy and is_proxy == "1" then
+ new_port = get_new_port()
+ table.insert(inbounds, {
+ tag = "proxy_" .. tag,
+ listen = "127.0.0.1",
+ port = new_port,
+ protocol = "dokodemo-door",
+ settings = {network = "tcp,udp", address = node.address, port = tonumber(node.port)}
+ })
+ if node.tls_serverName == nil then
+ node.tls_serverName = node.address
+ end
+ node.address = "127.0.0.1"
+ node.port = new_port
+ end
+
if node.type ~= "Xray" and node.type ~= "V2ray" then
if node.type == "Socks" then
node.protocol = "socks"
node.transport = "tcp"
else
local node_type = proto or "socks"
+ local relay_port = node.port
new_port = get_new_port()
node.port = new_port
- sys.call(string.format('/usr/share/%s/app.sh run_socks "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s"> /dev/null',
- appname,
- new_port,
- node_id,
- "127.0.0.1",
- new_port,
- string.format("/var/etc/%s/v2_%s_%s.json", appname, node_type, node_id),
- "0",
- "nil",
- relay_port and tostring(relay_port) or ""
+ sys.call(string.format('/usr/share/%s/app.sh run_socks "%s" "%s" "%s" "%s" "%s" "%s" "%s" "%s"> /dev/null', appname,
+ new_port, --flag
+ node_id, --node
+ "127.0.0.1", --bind
+ new_port, --socks port
+ string.format("/var/etc/%s/v2_%s_%s_%s.json", appname, node_type, node_id, new_port), --config file
+ "0", --http port
+ "nil", -- http config file
+ (is_proxy and is_proxy == "1" and relay_port) and tostring(relay_port) or "" --relay port
)
)
node.protocol = "socks"
@@ -86,6 +103,8 @@ function gen_outbound(node, tag, relay_port)
end
result = {
+ _flag_tag = node_id,
+ _flag_is_proxy = (is_proxy and is_proxy == "1") and "1" or "0",
tag = tag,
protocol = node.protocol,
mux = (node.stream_security ~= "xtls") and {
@@ -222,11 +241,80 @@ if node_section then
end
end
+ local up_trust_doh = ucursor:get(appname, "@global[0]", "up_trust_doh")
+ if up_trust_doh then
+ local t = {}
+ string.gsub(up_trust_doh, '[^' .. "," .. ']+', function (w)
+ table.insert(t, w)
+ end)
+ if #t > 1 then
+ local host = sys.exec("echo -n $(echo " .. t[1] .. " | sed 's/https:\\/\\///g' | awk -F ':' '{print $1}' | awk -F '/' '{print $1}')")
+ dns = {
+ hosts = {
+ [host] = t[2]
+ }
+ }
+ end
+ end
+
if node.protocol == "_shunt" then
local rules = {}
+
+ local default_node_id = node.default_node or "_direct"
+ local outboundTag
+ if default_node_id == "_direct" then
+ outboundTag = "direct"
+ elseif default_node_id == "_blackhole" then
+ outboundTag = "blackhole"
+ else
+ local default_node = ucursor:get_all(appname, default_node_id)
+ local main_node_id = node.main_node or "nil"
+ if main_node_id ~= "nil" then
+ if main_node_id == default_node_id then
+ else
+ new_port = get_new_port()
+ table.insert(inbounds, {
+ tag = "proxy_default",
+ listen = "127.0.0.1",
+ port = new_port,
+ protocol = "dokodemo-door",
+ settings = {network = "tcp,udp", address = default_node.address, port = tonumber(default_node.port)}
+ })
+ if default_node.tls_serverName == nil then
+ default_node.tls_serverName = default_node.address
+ end
+ default_node.address = "127.0.0.1"
+ default_node.port = new_port
+ local node = ucursor:get_all(appname, main_node_id)
+ local outbound = gen_outbound(node, "main")
+ if outbound then
+ table.insert(outbounds, outbound)
+ table.insert(rules, 1, {
+ type = "field",
+ inboundTag = {"proxy_default"},
+ outboundTag = "main"
+ })
+ end
+ end
+ end
+ local default_outbound = gen_outbound(default_node, "default")
+ if default_outbound then
+ table.insert(outbounds, default_outbound)
+ outboundTag = "default"
+ end
+ end
+ if outboundTag then
+ table.insert(rules, {
+ type = "field",
+ outboundTag = outboundTag,
+ network = network
+ })
+ end
+
ucursor:foreach(appname, "shunt_rules", function(e)
local name = e[".name"]
local _node_id = node[name] or "nil"
+ local is_proxy = node[name .. "_proxy"] or "0"
local outboundTag
if _node_id == "_direct" then
outboundTag = "direct"
@@ -234,36 +322,31 @@ if node_section then
outboundTag = "blackhole"
else
if _node_id ~= "nil" then
- local _node = ucursor:get_all(appname, _node_id)
- local is_proxy = node[name .. "_proxy"]
- local relay_port
- if is_proxy and is_proxy == "1" then
- new_port = get_new_port()
- relay_port = new_port
- table.insert(inbounds, {
- tag = "proxy_" .. name,
- listen = "127.0.0.1",
- port = new_port,
- protocol = "dokodemo-door",
- settings = {network = "tcp,udp", address = _node.address, port = tonumber(_node.port)}
- })
- if _node.tls_serverName == nil then
- _node.tls_serverName = _node.address
+ local has_outbound
+ for index, value in ipairs(outbounds) do
+ if value["_flag_tag"] == _node_id and value["_flag_is_proxy"] == is_proxy then
+ has_outbound = api.clone(value)
+ break
end
- _node.address = "127.0.0.1"
- _node.port = new_port
end
- local _outbound = gen_outbound(_node, name, relay_port)
- if _outbound then
- table.insert(outbounds, _outbound)
- if is_proxy and is_proxy == "1" then
- table.insert(rules, {
- type = "field",
- inboundTag = {"proxy_" .. name},
- outboundTag = "default"
- })
- end
+ if has_outbound then
+ has_outbound["tag"] = name
+ table.insert(outbounds, has_outbound)
outboundTag = name
+ else
+ local _node = ucursor:get_all(appname, _node_id)
+ local _outbound = gen_outbound(_node, name, is_proxy)
+ if _outbound then
+ if is_proxy == "1" then
+ table.insert(rules, 1, {
+ type = "field",
+ inboundTag = {"proxy_" .. name},
+ outboundTag = "default"
+ })
+ end
+ table.insert(outbounds, _outbound)
+ outboundTag = name
+ end
end
end
end
@@ -292,59 +375,10 @@ if node_section then
end
end
end)
-
- local default_node_id = node.default_node or nil
- if default_node_id and default_node_id ~= "nil" then
- local default_node = ucursor:get_all(appname, default_node_id)
- if "1" == node.default_proxy then
- local node_id = node.main_node or nil
- if node_id and node_id ~= "nil" then
- if node_id == default_node_id then
- else
- new_port = get_new_port()
- table.insert(inbounds, {
- tag = "proxy_default",
- listen = "127.0.0.1",
- port = new_port,
- protocol = "dokodemo-door",
- settings = {network = "tcp,udp", address = default_node.address, port = tonumber(default_node.port)}
- })
- if default_node.tls_serverName == nil then
- default_node.tls_serverName = default_node.address
- end
- default_node.address = "127.0.0.1"
- default_node.port = new_port
- local node = ucursor:get_all(appname, node_id)
- local outbound = gen_outbound(node, "main")
- if outbound then
- table.insert(outbounds, outbound)
- local rule = {
- type = "field",
- inboundTag = {"proxy_default"},
- outboundTag = "main"
- }
- table.insert(rules, rule)
- end
- end
- end
- end
- local default_outbound = gen_outbound(default_node, "default")
- if default_outbound then
- table.insert(outbounds, default_outbound)
- local rule = {
- type = "field",
- outboundTag = "default",
- network = network
- }
- table.insert(rules, rule)
- end
- end
-
routing = {
domainStrategy = node.domainStrategy or "AsIs",
rules = rules
}
-
elseif node.protocol == "_balancing" then
if node.balancing_node then
local nodes = node.balancing_node
@@ -456,7 +490,14 @@ if inbounds or outbounds then
table.insert(outbounds, {
protocol = "freedom",
tag = "direct",
- settings = {domainStrategy = "UseIPv4"}
+ settings = {
+ domainStrategy = "UseIPv4"
+ },
+ streamSettings = {
+ sockopt = {
+ mark = 255
+ }
+ }
})
table.insert(outbounds, {
protocol = "blackhole",
@@ -465,7 +506,7 @@ if inbounds or outbounds then
local xray = {
log = {
- -- error = string.format("/var/etc/passwall/%s.log", node[".name"]),
+ -- error = string.format("/var/etc/%s/%s.log", appname, node[".name"]),
loglevel = loglevel
},
-- DNS
diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/auto_switch.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/auto_switch.lua
index ab048d5eeb..3161695663 100644
--- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/auto_switch.lua
+++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/auto_switch.lua
@@ -3,10 +3,7 @@ local appname = api.appname
local nodes_table = {}
for k, e in ipairs(api.get_valid_nodes()) do
- nodes_table[#nodes_table + 1] = {
- id = e[".name"],
- remarks = e.remarks_name
- }
+ nodes_table[#nodes_table + 1] = e
end
m = Map(appname)
@@ -26,7 +23,9 @@ o.default = "1"
o = s:option(DynamicList, "tcp_node", "TCP " .. translate("List of backup nodes"))
for k, v in pairs(nodes_table) do
- o:value(v.id, v.remarks)
+ if v.node_type == "normal" then
+ o:value(v.id, v.remarks_name)
+ end
end
o = s:option(Flag, "restore_switch", "TCP " .. translate("Restore Switch"), translate("When detects main node is available, switch back to the main node."))
diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua
index 299a324956..3e7b721cbf 100644
--- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua
+++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua
@@ -120,11 +120,11 @@ if has_xray and #nodes_table > 0 then
local id = e[".name"]
o = s:taboption("Main", ListValue, v.id .. "." .. id .. "_node", string.format('* %s', api.url("shunt_rules", id), translate(e.remarks)))
o:depends("tcp_node", v.id)
- o:value("nil", translate("Close"))
+ o:value("nil", translate("Default"))
o:value("_direct", translate("Direct Connection"))
o:value("_blackhole", translate("Blackhole"))
- for k, v in pairs(normal_list) do
- o:value(v.id, v.remarks_name)
+ for k1, v1 in pairs(normal_list) do
+ o:value(v1.id, v1.remarks_name)
end
o.cfgvalue = function(self, section)
return m:get(v.id, id) or "nil"
@@ -137,9 +137,10 @@ if has_xray and #nodes_table > 0 then
local id = "default_node"
o = s:taboption("Main", ListValue, v.id .. "." .. id, "* " .. translate("Default"))
o:depends("tcp_node", v.id)
- o:value("nil", translate("Close"))
- for k, v in pairs(normal_list) do
- o:value(v.id, v.remarks_name)
+ o:value("_direct", translate("Direct Connection"))
+ o:value("_blackhole", translate("Blackhole"))
+ for k1, v1 in pairs(normal_list) do
+ o:value(v1.id, v1.remarks_name)
end
o.cfgvalue = function(self, section)
return m:get(v.id, id) or "nil"
@@ -152,8 +153,8 @@ if has_xray and #nodes_table > 0 then
o = s:taboption("Main", ListValue, v.id .. "." .. id, "* " .. translate("Default") .. translate("Preproxy"))
o:depends("tcp_node", v.id)
o:value("nil", translate("Close"))
- for k, v in pairs(normal_list) do
- o:value(v.id, v.remarks_name)
+ for k1, v1 in pairs(normal_list) do
+ o:value(v1.id, v1.remarks_name)
end
o.cfgvalue = function(self, section)
return m:get(v.id, id) or "nil"
@@ -274,7 +275,9 @@ o:depends({dns_mode = "pdnsd"})
o = s:taboption("DNS", Button, "clear_ipset", translate("Clear IPSET"), translate("Try this feature if the rule modification does not take effect."))
o.inputstyle = "remove"
function o.write(e, e)
- luci.sys.call("/etc/init.d/" .. appname .. " stop && /usr/share/" .. appname .. "/iptables.sh flush_ipset && /etc/init.d/" .. appname .. " restart")
+ luci.sys.call("/etc/init.d/" .. appname .. " stop")
+ luci.sys.call("/usr/share/" .. appname .. "/iptables.sh flush_ipset")
+ luci.sys.call("/etc/init.d/" .. appname .. " restart")
end
s:tab("Proxy", translate("Mode"))
diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua
index 4f3c4b6f51..b8c933e995 100644
--- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua
+++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua
@@ -129,7 +129,7 @@ balancing_node:depends("protocol", "_balancing")
-- 分流
uci:foreach(appname, "shunt_rules", function(e)
o = s:option(ListValue, e[".name"], string.format('* %s', api.url("shunt_rules", e[".name"]), translate(e.remarks)))
- o:value("nil", translate("Close"))
+ o:value("nil", translate("Default"))
o:value("_direct", translate("Direct Connection"))
o:value("_blackhole", translate("Blackhole"))
o:depends("protocol", "_shunt")
@@ -153,17 +153,19 @@ end
shunt_tips:depends("protocol", "_shunt")
default_node = s:option(ListValue, "default_node", translate("Default") .. " " .. translate("Node"))
-default_node:value("nil", translate("Close"))
+default_node:value("_direct", translate("Direct Connection"))
+default_node:value("_blackhole", translate("Blackhole"))
for k, v in pairs(nodes_table) do default_node:value(v.id, v.remarks) end
default_node:depends("protocol", "_shunt")
-default_proxy = s:option(Flag, "default_proxy", translate("Default") .. translate("Node") .. translate("Preproxy"), translate("Use the under node for the transit."))
-default_proxy.default = 0
-default_proxy:depends("protocol", "_shunt")
-
-o = s:option(ListValue, "main_node", " ")
-for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
-o:depends("default_proxy", "1")
+if #nodes_table > 0 then
+ o = s:option(ListValue, "main_node", translate("Default") .. " " .. translate("Node") .. translate("Preproxy"), translate("Use this node proxy to forward the default node."))
+ o:value("nil", translate("Close"))
+ for k, v in pairs(nodes_table) do
+ o:value(v.id, v.remarks)
+ o:depends("default_node", v.id)
+ end
+end
domainStrategy = s:option(ListValue, "domainStrategy", translate("Domain Strategy"))
domainStrategy:value("AsIs")
diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua
index 5025bf5853..de2e63faa6 100644
--- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua
+++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua
@@ -28,6 +28,9 @@ o = s:option(Value, "chnroute6_url", translate("China IPv6s(chnroute6) Update UR
o:value("https://ispip.clang.cn/all_cn_ipv6.txt", translate("Clang.CN.IPv6"))
o.default = "https://ispip.clang.cn/all_cn_ipv6.txt"
+----chnlist URL
+o = s:option(DynamicList, "chnlist_url", translate("China List(Chnlist) Update URL"))
+
s:append(Template(appname .. "/rule/rule_version"))
---- Auto Update
@@ -57,6 +60,7 @@ s = m:section(TypedSection, "shunt_rules", "Xray" .. translate("Shunt") .. trans
s.template = "cbi/tblsection"
s.anonymous = false
s.addremove = true
+s.sortable = true
s.extedit = api.url("shunt_rules", "%s")
function s.create(e, t)
TypedSection.create(e, t)
diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua
index 4ddc363eda..94814bf8b9 100644
--- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua
+++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua
@@ -57,7 +57,7 @@ ip_list.validate = function(self, value)
if ipmask:find("geoip:") and ipmask:find("geoip:") == 1 then
elseif ipmask:find("ext:") and ipmask:find("ext:") == 1 then
else
- if not datatypes.ipmask4(ipmask) then
+ if not (datatypes.ipmask4(ipmask) or datatypes.ipmask6(ipmask)) then
return nil, ipmask .. " " .. translate("Not valid IP format, please re-enter!")
end
end
diff --git a/package/lienol/luci-app-passwall/luasrc/view/passwall/rule/rule_version.htm b/package/lienol/luci-app-passwall/luasrc/view/passwall/rule/rule_version.htm
index 4d8d9ba62a..f6cea0bfdd 100644
--- a/package/lienol/luci-app-passwall/luasrc/view/passwall/rule/rule_version.htm
+++ b/package/lienol/luci-app-passwall/luasrc/view/passwall/rule/rule_version.htm
@@ -5,6 +5,8 @@ local gfwlist_update = api.uci_get_type("global_rules", "gfwlist_update", "1") =
local chnroute_update = api.uci_get_type("global_rules", "chnroute_update", "1") == "1" and "checked='checked'" or ""
local chnroute6_update = api.uci_get_type("global_rules", "chnroute6_update", "1") == "1" and "checked='checked'" or ""
local chnlist_update = api.uci_get_type("global_rules", "chnlist_update", "1") == "1" and "checked='checked'" or ""
+local geoip_update = api.uci_get_type("global_rules", "geoip_update", "1") == "1" and "checked='checked'" or ""
+local geosite_update = api.uci_get_type("global_rules", "geosite_update", "1") == "1" and "checked='checked'" or ""
-%>