Skip to content

Commit 4650a59

Browse files
luci-app-passwall: bump to 26.1.17
1 parent ebd221c commit 4650a59

File tree

33 files changed

+1037
-933
lines changed

33 files changed

+1037
-933
lines changed

applications/luci-app-passwall/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# Copyright (C) 2018-2020 L-WRT Team
22
# Copyright (C) 2021-2025 xiaorouji
3+
# Copyright (C) 2026 Openwrt-Passwall Organization
34
#
45
# This is free software, licensed under the GNU General Public License v3.
56

67
include $(TOPDIR)/rules.mk
78

89
PKG_NAME:=luci-app-passwall
9-
PKG_VERSION:=26.1.13
10+
PKG_VERSION:=26.1.17
1011
PKG_RELEASE:=1
1112

1213
PKG_CONFIG_DEPENDS:= \

applications/luci-app-passwall/luasrc/controller/passwall.lua

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
-- Copyright (C) 2018-2020 L-WRT Team
22
-- Copyright (C) 2021-2025 xiaorouji
3+
-- Copyright (C) 2026 Openwrt-Passwall Organization
34

45
module("luci.controller.passwall", package.seeall)
56
local api = require "luci.passwall.api"
@@ -334,7 +335,7 @@ function connect_status()
334335
local proxy_mode = uci:get(appname, "@global[0]", "tcp_proxy_mode") or "proxy"
335336
local localhost_proxy = uci:get(appname, "@global[0]", "localhost_proxy") or "1"
336337
local socks_server = (localhost_proxy == "0") and api.get_cache_var("GLOBAL_TCP_SOCKS_server") or ""
337-
url = "-w %{http_code}:%{time_starttransfer} " .. url
338+
url = "-w %{http_code}:%{time_pretransfer} " .. url
338339
if socks_server and socks_server ~= "" then
339340
if (chn_list == "proxy" and gfw_list == "0" and proxy_mode ~= "proxy" and baidu ~= nil) or (chn_list == "0" and gfw_list == "0" and proxy_mode == "proxy") then
340341
-- 中国列表+百度 or 全局

applications/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
210210
pt.remove = get_remove(v.id, id .. "_proxy_tag")
211211
pt:value("", translate("Close"))
212212
pt:value("main", translate("Preproxy Node"))
213+
pt:depends("__hide__", "1")
213214
for k1, v1 in pairs(socks_list) do
214215
o:value(v1.id, v1.remark)
215216
o.group[#o.group+1] = (v1.group and v1.group ~= "") and v1.group or translate("default")
@@ -274,6 +275,7 @@ if (has_singbox or has_xray) and #nodes_table > 0 then
274275
o.remove = get_remove(v.id, id)
275276
o:value("", translate("Close"))
276277
o:value("main", translate("Preproxy Node"))
278+
o:depends("__hide__", "1")
277279
for k1, v1 in pairs(normal_list) do
278280
if v1.protocol ~= "_balancing" and v1.protocol ~= "_urltest" and not api.is_local_ip(v1.address) then
279281
o:depends({ [vid .. "-default_node"] = v1.id, [vid .. "-preproxy_enabled"] = "1" })
@@ -682,13 +684,36 @@ o.default = "proxy"
682684
o = s:taboption("Proxy", DummyValue, "switch_mode", " ")
683685
o.template = appname .. "/global/proxy"
684686

685-
o = s:taboption("Proxy", Flag, "localhost_proxy", translate("Localhost Proxy"), translate("When selected, localhost can transparent proxy."))
686-
o.default = "1"
687-
o.rmempty = false
687+
---- Check the transparent proxy component
688+
local handle = io.popen("lsmod")
689+
local mods = ""
690+
if handle then
691+
mods = handle:read("*a") or ""
692+
handle:close()
693+
end
688694

689-
o = s:taboption("Proxy", Flag, "client_proxy", translate("Client Proxy"), translate("When selected, devices in LAN can transparent proxy. Otherwise, it will not be proxy. But you can still use access control to allow the designated device to proxy."))
690-
o.default = "1"
691-
o.rmempty = false
695+
if (mods:find("REDIRECT") and mods:find("TPROXY")) or (mods:find("nft_redir") and mods:find("nft_tproxy")) then
696+
o = s:taboption("Proxy", Flag, "localhost_proxy", translate("Localhost Proxy"), translate("When selected, localhost can transparent proxy."))
697+
o.default = "1"
698+
o.rmempty = false
699+
700+
o = s:taboption("Proxy", Flag, "client_proxy", translate("Client Proxy"), translate("When selected, devices in LAN can transparent proxy. Otherwise, it will not be proxy. But you can still use access control to allow the designated device to proxy."))
701+
o.default = "1"
702+
o.rmempty = false
703+
else
704+
local html = string.format([[<div class="cbi-checkbox"><input class="cbi-input-checkbox" type="checkbox" disabled></div><div class="cbi-value-description"><font color="red">%s</font></div>]], translate("Missing components, transparent proxy is unavailable."))
705+
o = s:taboption("Proxy", DummyValue, "localhost_proxy", translate("Localhost Proxy"))
706+
o.rawhtml = true
707+
function o.cfgvalue(self, section)
708+
return html
709+
end
710+
711+
o = s:taboption("Proxy", DummyValue, "client_proxy", translate("Client Proxy"))
712+
o.rawhtml = true
713+
function o.cfgvalue(self, section)
714+
return html
715+
end
716+
end
692717

693718
o = s:taboption("Proxy", DummyValue, "_proxy_tips", " ")
694719
o.rawhtml = true

applications/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ local trojan_type = {}
1212
local vmess_type = {}
1313
local vless_type = {}
1414
local hysteria2_type = {}
15+
local xray_version = api.get_app_version("xray")
1516
if has_ss then
1617
local s = "shadowsocks-libev"
1718
table.insert(ss_type, s)
@@ -38,6 +39,9 @@ if has_xray then
3839
table.insert(ss_type, s)
3940
table.insert(vmess_type, s)
4041
table.insert(vless_type, s)
42+
if api.compare_versions(xray_version, ">=", "26.1.13") then
43+
table.insert(hysteria2_type, s)
44+
end
4145
end
4246
if has_hysteria2 then
4347
local s = "hysteria2"

applications/luci-app-passwall/luasrc/model/cbi/passwall/client/node_subscribe_config.lua

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ local trojan_type = {}
2727
local vmess_type = {}
2828
local vless_type = {}
2929
local hysteria2_type = {}
30+
local xray_version = api.get_app_version("xray")
3031
if has_ss then
3132
local s = "shadowsocks-libev"
3233
table.insert(ss_type, s)
@@ -53,6 +54,9 @@ if has_xray then
5354
table.insert(ss_type, s)
5455
table.insert(vmess_type, s)
5556
table.insert(vless_type, s)
57+
if api.compare_versions(xray_version, ">=", "26.1.13") then
58+
table.insert(hysteria2_type, s)
59+
end
5660
end
5761
if has_hysteria2 then
5862
local s = "hysteria2"

applications/luci-app-passwall/luasrc/model/cbi/passwall/client/other.lua

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ local appname = "passwall"
33
local fs = api.fs
44
local has_singbox = api.finded_com("sing-box")
55
local has_xray = api.finded_com("xray")
6-
local has_fw3 = api.is_finded("fw3")
7-
local has_fw4 = api.is_finded("fw4")
86

97
local port_validate = function(self, value, t)
108
return value:gsub("-", ":")
@@ -115,16 +113,20 @@ o.cfgvalue = function(t, n)
115113
end
116114

117115
---- Use nftables
118-
o = s:option(ListValue, "use_nft", translate("Firewall tools"))
119-
o.default = "0"
120-
if has_fw3 then
121-
o:value("0", "IPtables")
122-
end
123-
if has_fw4 then
124-
o:value("1", "NFtables")
116+
o = s:option(ListValue, "prefer_nft", translate("Prefer firewall tools"))
117+
o.default = "1"
118+
o:value("0", "Iptables")
119+
o:value("1", "Nftables")
120+
121+
---- Check the transparent proxy component
122+
local handle = io.popen("lsmod")
123+
local mods = ""
124+
if handle then
125+
mods = handle:read("*a") or ""
126+
handle:close()
125127
end
126128

127-
if (os.execute("lsmod | grep -i REDIRECT >/dev/null") == 0 and os.execute("lsmod | grep -i TPROXY >/dev/null") == 0) or (os.execute("lsmod | grep -i nft_redir >/dev/null") == 0 and os.execute("lsmod | grep -i nft_tproxy >/dev/null") == 0) then
129+
if (mods:find("REDIRECT") and mods:find("TPROXY")) or (mods:find("nft_redir") and mods:find("nft_tproxy")) then
128130
o = s:option(ListValue, "tcp_proxy_way", translate("TCP Proxy Way"))
129131
o.default = "redirect"
130132
o:value("redirect", "REDIRECT")
@@ -142,7 +144,7 @@ if (os.execute("lsmod | grep -i REDIRECT >/dev/null") == 0 and os.execute("lsmod
142144
self.map:set(section, "tcp_proxy_way", value)
143145
end
144146

145-
if os.execute("lsmod | grep -i ip6table_mangle >/dev/null") == 0 or os.execute("lsmod | grep -i nft_tproxy >/dev/null") == 0 then
147+
if mods:find("ip6table_mangle") or mods:find("nft_tproxy") then
146148
---- IPv6 TProxy
147149
o = s:option(Flag, "ipv6_tproxy", translate("IPv6 TProxy"),
148150
"<font color='red'>" .. translate(

applications/luci-app-passwall/luasrc/model/cbi/passwall/client/type/ray.lua

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ o:value("socks", translate("Socks"))
4040
o:value("shadowsocks", translate("Shadowsocks"))
4141
o:value("trojan", translate("Trojan"))
4242
o:value("wireguard", translate("WireGuard"))
43+
if api.compare_versions(xray_version, ">=", "26.1.13") then
44+
o:value("hysteria2", translate("Hysteria2"))
45+
end
4346
if api.compare_versions(xray_version, ">=", "1.8.12") then
4447
o:value("_balancing", translate("Balancing"))
4548
end
@@ -266,6 +269,7 @@ m.uci:foreach(appname, "shunt_rules", function(e)
266269
local pt = s:option(ListValue, _n(e[".name"] .. "_proxy_tag"), string.format('* <a style="color:red">%s</a>', e.remarks .. " " .. translate("Preproxy")))
267270
pt:value("", translate("Close"))
268271
pt:value("main", translate("Preproxy Node"))
272+
pt:depends("__hide__", "1")
269273
for k, v in pairs(nodes_table) do
270274
o:value(v.id, v.remark)
271275
o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
@@ -308,6 +312,7 @@ if #nodes_table > 0 then
308312
local dpt = s:option(ListValue, _n("default_proxy_tag"), 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."))
309313
dpt:value("", translate("Close"))
310314
dpt:value("main", translate("Preproxy Node"))
315+
dpt:depends("__hide__", "1")
311316
for k, v in pairs(nodes_table) do
312317
o:value(v.id, v.remark)
313318
o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
@@ -399,6 +404,42 @@ o:value("", translate("Disable"))
399404
o:value("xtls-rprx-vision")
400405
o:depends({ [_n("protocol")] = "vless" })
401406

407+
---- [[hysteria2]]
408+
o = s:option(Value, _n("hysteria2_hop"), translate("Port hopping range"))
409+
o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).")
410+
o:depends({ [_n("protocol")] = "hysteria2" })
411+
412+
o = s:option(Value, _n("hysteria2_hop_interval"), translate("Hop Interval"), translate("Example:") .. "30s (≥5s)")
413+
o.placeholder = "30s"
414+
o.default = "30s"
415+
o:depends({ [_n("protocol")] = "hysteria2" })
416+
417+
o = s:option(Value, _n("hysteria2_up_mbps"), translate("Max upload Mbps"))
418+
o:depends({ [_n("protocol")] = "hysteria2" })
419+
420+
o = s:option(Value, _n("hysteria2_down_mbps"), translate("Max download Mbps"))
421+
o:depends({ [_n("protocol")] = "hysteria2" })
422+
423+
o = s:option(ListValue, _n("hysteria2_obfs_type"), translate("Obfs Type"))
424+
o:value("", translate("Disable"))
425+
o:value("salamander")
426+
o:depends({ [_n("protocol")] = "hysteria2" })
427+
428+
o = s:option(Value, _n("hysteria2_obfs_password"), translate("Obfs Password"))
429+
o:depends({ [_n("protocol")] = "hysteria2" })
430+
431+
o = s:option(Value, _n("hysteria2_auth_password"), translate("Auth Password"))
432+
o.password = true
433+
o:depends({ [_n("protocol")] = "hysteria2"})
434+
435+
o = s:option(Value, _n("hysteria2_idle_timeout"), translate("Idle Timeout"), translate("Example:") .. "30s (4s-120s)")
436+
o:depends({ [_n("protocol")] = "hysteria2"})
437+
438+
o = s:option(Flag, _n("hysteria2_disable_mtu_discovery"), translate("Disable MTU detection"))
439+
o.default = "0"
440+
o:depends({ [_n("protocol")] = "hysteria2"})
441+
---- [[hysteria2 end]]
442+
402443
o = s:option(Flag, _n("tls"), translate("TLS"))
403444
o.default = 0
404445
o:depends({ [_n("protocol")] = "vmess" })
@@ -426,6 +467,7 @@ o:value("http/1.1")
426467
o:value("h2,http/1.1")
427468
o:value("h3,h2,http/1.1")
428469
o:depends({ [_n("tls")] = true, [_n("reality")] = false })
470+
o:depends({ [_n("protocol")] = "hysteria2" })
429471

430472
-- o = s:option(Value, _n("minversion"), translate("minversion"))
431473
-- o.default = "1.3"
@@ -434,17 +476,20 @@ o:depends({ [_n("tls")] = true, [_n("reality")] = false })
434476

435477
o = s:option(Value, _n("tls_serverName"), translate("Domain"))
436478
o:depends({ [_n("tls")] = true })
479+
o:depends({ [_n("protocol")] = "hysteria2" })
437480

438481
o = s:option(Flag, _n("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped."))
439482
o.default = "0"
440483
o:depends({ [_n("tls")] = true, [_n("reality")] = false })
484+
o:depends({ [_n("protocol")] = "hysteria2" })
441485

442486
o = s:option(Value, _n("tls_chain_fingerprint"), translate("TLS Chain Fingerprint (SHA256)"), translate("Once set, connects only when the server’s chain fingerprint matches."))
443487
o:depends({ [_n("tls")] = true, [_n("reality")] = false })
444488

445489
o = s:option(Flag, _n("ech"), translate("ECH"))
446490
o.default = "0"
447491
o:depends({ [_n("tls")] = true, [_n("flow")] = "", [_n("reality")] = false })
492+
o:depends({ [_n("protocol")] = "hysteria2" })
448493

449494
o = s:option(TextValue, _n("ech_config"), translate("ECH Config"))
450495
o.default = ""
@@ -734,11 +779,6 @@ o:depends({ [_n("mux")] = true })
734779

735780
o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"))
736781
o.default = 0
737-
o:depends({ [_n("protocol")] = "vmess" })
738-
o:depends({ [_n("protocol")] = "vless" })
739-
o:depends({ [_n("protocol")] = "socks" })
740-
o:depends({ [_n("protocol")] = "shadowsocks" })
741-
o:depends({ [_n("protocol")] = "trojan" })
742782

743783
--[[tcpMptcp]]
744784
o = s:option(Flag, _n("tcpMptcp"), "tcpMptcp", translate("Enable Multipath TCP, need to be enabled in both server and client configuration."))
@@ -779,7 +819,8 @@ for k, v in pairs(nodes_table) do
779819
end
780820

781821
for i, v in ipairs(s.fields[_n("protocol")].keylist) do
782-
if not v:find("_") then
822+
if not v:find("_") and v ~= "hysteria2" then
823+
s.fields[_n("tcp_fast_open")]:depends({ [_n("protocol")] = v })
783824
s.fields[_n("tcpMptcp")]:depends({ [_n("protocol")] = v })
784825
s.fields[_n("chain_proxy")]:depends({ [_n("protocol")] = v })
785826
end

applications/luci-app-passwall/luasrc/model/cbi/passwall/client/type/sing-box.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,7 @@ m.uci:foreach(appname, "shunt_rules", function(e)
240240
local pt = s:option(ListValue, _n(e[".name"] .. "_proxy_tag"), string.format('* <a style="color:red">%s</a>', e.remarks .. " " .. translate("Preproxy")))
241241
pt:value("", translate("Close"))
242242
pt:value("main", translate("Preproxy Node"))
243+
pt:depends("__hide__", "1")
243244
for k, v in pairs(nodes_table) do
244245
o:value(v.id, v.remark)
245246
o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")
@@ -282,6 +283,7 @@ if #nodes_table > 0 then
282283
local dpt = s:option(ListValue, _n("default_proxy_tag"), 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."))
283284
dpt:value("", translate("Close"))
284285
dpt:value("main", translate("Preproxy Node"))
286+
dpt:depends("__hide__", "1")
285287
for k, v in pairs(nodes_table) do
286288
o:value(v.id, v.remark)
287289
o.group[#o.group+1] = (v.group and v.group ~= "") and v.group or translate("default")

applications/luci-app-passwall/luasrc/passwall/api.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,11 @@ function sh_uci_commit(config)
8585
end
8686

8787
function set_cache_var(key, val)
88-
sys.call(string.format('/usr/share/passwall/app.sh set_cache_var %s "%s"', key, val))
88+
sys.call(string.format('. /usr/share/passwall/utils.sh ; set_cache_var %s "%s"', key, val))
8989
end
9090

9191
function get_cache_var(key)
92-
local val = sys.exec(string.format('echo -n $(/usr/share/passwall/app.sh get_cache_var %s)', key))
92+
local val = sys.exec(string.format('. /usr/share/passwall/utils.sh ; echo -n $(get_cache_var %s)', key))
9393
if val == "" then val = nil end
9494
return val
9595
end
@@ -1159,7 +1159,7 @@ function get_version()
11591159
if not version or #version == 0 then
11601160
version = sys.exec("apk list luci-app-passwall 2>/dev/null | awk '/installed/ {print $1}' | cut -d'-' -f4-")
11611161
end
1162-
return (version or ""):gsub("\n", "")
1162+
return (version or ""):gsub("\n", ""):match("^([^-]+)")
11631163
end
11641164

11651165
function to_check_self()

applications/luci-app-passwall/luasrc/passwall/util_sing-box.lua

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,12 @@ end
6464
local new_port
6565

6666
local function get_new_port()
67-
if new_port then
68-
new_port = tonumber(sys.exec(string.format("echo -n $(/usr/share/%s/app.sh get_new_port %s tcp)", appname, new_port + 1)))
69-
else
70-
new_port = tonumber(sys.exec(string.format("echo -n $(/usr/share/%s/app.sh get_new_port auto tcp)", appname)))
67+
local cmd_format = ". /usr/share/passwall/utils.sh ; echo -n $(get_new_port %s tcp)"
68+
local set_port = 0
69+
if new_port and tonumber(new_port) then
70+
set_port = tonumber(new_port) + 1
7171
end
72+
new_port = tonumber(sys.exec(string.format(cmd_format, set_port == 0 and "auto" or set_port)))
7273
return new_port
7374
end
7475

0 commit comments

Comments
 (0)