Skip to content
Merged
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.17
PKG_VERSION:=26.1.25
PKG_RELEASE:=1

PKG_CONFIG_DEPENDS:= \
Expand Down
31 changes: 31 additions & 0 deletions applications/luci-app-passwall/luasrc/controller/passwall.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ local http = require "luci.http"
local util = require "luci.util"
local i18n = require "luci.i18n"
local jsonStringify = luci.jsonc.stringify
local jsonParse = luci.jsonc.parse

function index()
if not nixio.fs.access("/etc/config/passwall") then
Expand Down Expand Up @@ -79,6 +80,7 @@ function index()
entry({"admin", "services", appname, "ping_node"}, call("ping_node")).leaf = true
entry({"admin", "services", appname, "urltest_node"}, call("urltest_node")).leaf = true
entry({"admin", "services", appname, "add_node"}, call("add_node")).leaf = true
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, "clear_all_nodes"}, call("clear_all_nodes")).leaf = true
Expand Down Expand Up @@ -119,6 +121,16 @@ local function http_write_json(content)
http.write(jsonStringify(content or {code = 1}))
end

local function http_write_json_ok(data)
http.prepare_content("application/json")
http.write(jsonStringify({code = 1, data = data}))
end

local function http_write_json_error(data)
http.prepare_content("application/json")
http.write(jsonStringify({code = 0, data = data}))
end

function reset_config()
luci.sys.call('/etc/init.d/passwall stop')
luci.sys.call('[ -f "/usr/share/passwall/0_default_config" ] && cp -f /usr/share/passwall/0_default_config /etc/config/passwall')
Expand Down Expand Up @@ -412,6 +424,8 @@ function add_node()
uci:set(appname, uuid, "group", group)
end

uci:set(appname, uuid, "type", "Xray")

if redirect == "1" then
api.uci_save(uci, appname)
http.redirect(api.url("node_config", uuid))
Expand All @@ -421,6 +435,23 @@ function add_node()
end
end

function update_node()
local id = http.formvalue("id") -- Node id
local data = http.formvalue("data") -- json new Data
if id and data then
local data_t = jsonParse(data) or {}
if next(data_t) then
for k, v in pairs(data_t) do
uci:set(appname, id, k, v)
end
api.uci_save(uci, appname)
http_write_json_ok()
return
end
end
http_write_json_error()
end

function set_node()
local protocol = http.formvalue("protocol")
local section = http.formvalue("section")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -464,11 +464,19 @@ o:depends({xray_dns_mode = "tcp+doh"})
o:depends({singbox_dns_mode = "doh"})

o = s:option(Value, "remote_dns_client_ip", translate("EDNS Client Subnet"))
o.description = translate("Notify the DNS server when the DNS query is notified, the location of the client (cannot be a private IP address).") .. "<br />" ..
translate("This feature requires the DNS server to support the Edns Client Subnet (RFC7871).")
o.datatype = "ipaddr"
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.default = "0"
o.rmempty = false
o:depends({dns_mode = "sing-box"})
o:depends({dns_mode = "xray"})

o = s:option(ListValue, "chinadns_ng_default_tag", translate("Default DNS"))
o.default = "none"
o:value("gfw", translate("Remote DNS"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,8 @@ 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
Expand All @@ -118,29 +120,34 @@ o:value("", translate("Close"))
o:value("tcp", translate("Same as the tcp node"))
o.group = {"",""}

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
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)
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
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)
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
end
end
if #normal_list > 0 then
for k, v in pairs(shunt_list) do
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"))
Expand All @@ -161,7 +168,7 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
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('<a style="color:red">%s</a>', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including <code>Default</code>) has a separate switch that controls whether this rule uses the pre-proxy or not."))
o = s:taboption("Main", ListValue, vid .. "-main_node", string.format('<a style="color:#FF8C00">%s</a>', translate("Preproxy Node")), translate("Set the node to be used as a pre-proxy. Each rule (including <code>Default</code>) 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 = {}
Expand All @@ -188,6 +195,12 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
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"
Expand All @@ -204,16 +217,23 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
o.template = appname .. "/cbi/nodes_listvalue"
o.group = {"","","",""}

local pt = s:taboption("Main", ListValue, vid .. "-".. id .. "_proxy_tag", string.format('* <a style="color:red">%s</a>', e.remarks .. " " .. translate("Preproxy")))
local pt = s:taboption("Main", ListValue, vid .. "-".. id .. "_proxy_tag", string.format('* <a style="color:#FF8C00">%s</a>', 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('* <a style="color:#FF8C00">%s</a>', 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)
Expand All @@ -233,6 +253,10 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
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)
Expand Down Expand Up @@ -269,7 +293,7 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
end

local id = "default_proxy_tag"
o = s:taboption("Main", ListValue, vid .. "-" .. id, string.format('* <a style="color:red">%s</a>', translate("Default Preproxy")), translate("When using, localhost will connect this node first and then use this node to connect the default node."))
o = s:taboption("Main", ListValue, vid .. "-" .. id, string.format('* <a style="color:#FF8C00">%s</a>', translate("Default Preproxy")), translate("When using, localhost will connect this node first and then use this node to connect the default node."))
o.cfgvalue = get_cfgvalue(v.id, id)
o.write = get_write(v.id, id)
o.remove = get_remove(v.id, id)
Expand Down Expand Up @@ -335,7 +359,7 @@ if api.is_finded("smartdns") then
o = s:taboption("DNS", Value, "group_domestic", translate("Domestic group name"))
o.placeholder = "local"
o:depends("dns_shunt", "smartdns")
o.description = translate("You only need to configure domestic DNS packets in SmartDNS and set it redirect or as Dnsmasq upstream, and fill in the domestic DNS group name here.")
o.description = translate("You only need to configure domestic DNS packets in SmartDNS, and fill in the domestic DNS group name here.")
end

o = s:taboption("DNS", ListValue, "direct_dns_mode", translate("Direct DNS") .. " " .. translate("Request protocol"))
Expand Down Expand Up @@ -559,7 +583,7 @@ o:depends({singbox_dns_mode = "doh"})

o = s:taboption("DNS", Value, "remote_dns_client_ip", translate("EDNS Client Subnet"))
o.description = translate("Notify the DNS server when the DNS query is notified, the location of the client (cannot be a private IP address).") .. "<br />" ..
translate("This feature requires the DNS server to support the Edns Client Subnet (RFC7871).")
translate("This feature requires the DNS server to support the Edns Client Subnet (RFC7871).")
o.datatype = "ipaddr"
o:depends({dns_mode = "sing-box"})
o:depends({dns_mode = "xray"})
Expand All @@ -574,7 +598,7 @@ o:depends({smartdns_dns_mode = "sing-box", dns_shunt = "smartdns"})
o:depends({dns_mode = "xray", dns_shunt = "dnsmasq"})
o:depends({dns_mode = "xray", dns_shunt = "chinadns-ng"})
o:depends({smartdns_dns_mode = "xray", dns_shunt = "smartdns"})
o:depends("_node_sel_shunt", "1")
--o:depends("_node_sel_shunt", "1")
o.validate = function(self, value, t)
if value and value == "1" then
local _dns_mode = s.fields["dns_mode"]:formvalue(t)
Expand Down Expand Up @@ -924,6 +948,10 @@ for k, v in pairs(nodes_table) do
end
end

m:append(Template(appname .. "/global/footer"))
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
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ if not arg[1] or not m:get(arg[1]) then
luci.http.redirect(m.redirect)
end

local header = Template(appname .. "/node_config/header")
header.api = api
header.section = arg[1]
m:append(header)

m:append(Template(appname .. "/cbi/nodes_multivalue_com"))
m:append(Template(appname .. "/cbi/nodes_listvalue_com"))

Expand All @@ -18,7 +23,7 @@ s.dynamic = false

o = s:option(DummyValue, "passwall", " ")
o.rawhtml = true
o.template = "passwall/node_list/link_share_man"
o.template = "passwall/node_config/link_share_man"
o.value = arg[1]

o = s:option(Value, "remarks", translate("Node Remarks"))
Expand Down Expand Up @@ -55,35 +60,40 @@ o.write = function(self, section, value)
m:set(section, self.option, value)
end

local fs = api.fs
local types_dir = "/usr/lib/lua/luci/model/cbi/passwall/client/type/"
s.val = {}
s.val["type"] = m.uci:get(appname, arg[1], "type")
s.val["protocol"] = m.uci:get(appname, arg[1], "protocol")

o = s:option(ListValue, "type", translate("Type"))

if api.is_finded("ipt2socks") then
local function _n(name)
return "socks_" .. name
end

s.fields["type"]:value("Socks", translate("Socks"))

o = s:option(ListValue, _n("del_protocol"), " ") --始终隐藏,用于删除 protocol
o:depends({ [_n("__hide")] = "1" })
o.rewrite_option = "protocol"
if s.val["type"] == "Socks" then
local function _n(name)
return "socks_" .. name
end
o = s:option(ListValue, _n("del_protocol"), " ") --始终隐藏,用于删除 protocol
o:depends({ [_n("__hide")] = "1" })
o.rewrite_option = "protocol"

o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))

o = s:option(Value, _n("address"), translate("Address (Support Domain Name)"))
o = s:option(Value, _n("port"), translate("Port"))
o.datatype = "port"

o = s:option(Value, _n("port"), translate("Port"))
o.datatype = "port"
o = s:option(Value, _n("username"), translate("Username"))

o = s:option(Value, _n("username"), translate("Username"))
o = s:option(Value, _n("password"), translate("Password"))
o.password = true

o = s:option(Value, _n("password"), translate("Password"))
o.password = true
api.luci_types(arg[1], m, s, "Socks", "socks_")
end

api.luci_types(arg[1], m, s, "Socks", "socks_")
end

local fs = api.fs
local types_dir = "/usr/lib/lua/luci/model/cbi/passwall/client/type/"

local type_table = {}
for filename in fs.dir(types_dir) do
table.insert(type_table, filename)
Expand All @@ -95,4 +105,10 @@ for index, value in ipairs(type_table) do
setfenv(p_func, getfenv(1))(m, s)
end

local footer = Template(appname .. "/node_config/footer")
footer.api = api
footer.section = arg[1]

m:append(footer)

return m
Loading