Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion applications/luci-app-passwall/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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:= \
Expand Down
80 changes: 74 additions & 6 deletions applications/luci-app-passwall/luasrc/controller/passwall.lua
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -83,13 +84,15 @@ 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
entry({"admin", "services", appname, "get_node"}, call("get_node")).leaf = true
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
Expand Down Expand Up @@ -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()
Expand All @@ -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})
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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"
Expand All @@ -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:)(.*)$")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand All @@ -219,14 +223,36 @@ o = s:option(ListValue, "udp_node", "<a style='color: red'>" .. 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", "<a style='color: red'>" .. translate("UDP Node") .. "</a>")
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")
Expand Down Expand Up @@ -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"})
Expand Down
Loading