update 2025-05-07 20:46:48

This commit is contained in:
kenzok8 2025-05-07 20:46:48 +08:00
parent 66c2e2d076
commit 00f5221d9e
16 changed files with 364 additions and 79 deletions

View File

@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall2
PKG_VERSION:=25.4.22
PKG_VERSION:=25.5.7
PKG_RELEASE:=1
PKG_CONFIG_DEPENDS:= \

View File

@ -60,6 +60,7 @@ function index()
entry({"admin", "services", appname, "link_add_node"}, call("link_add_node")).leaf = true
entry({"admin", "services", appname, "socks_autoswitch_add_node"}, call("socks_autoswitch_add_node")).leaf = true
entry({"admin", "services", appname, "socks_autoswitch_remove_node"}, call("socks_autoswitch_remove_node")).leaf = true
entry({"admin", "services", appname, "gen_client_config"}, call("gen_client_config")).leaf = true
entry({"admin", "services", appname, "get_now_use_node"}, call("get_now_use_node")).leaf = true
entry({"admin", "services", appname, "get_redir_log"}, call("get_redir_log")).leaf = true
entry({"admin", "services", appname, "get_socks_log"}, call("get_socks_log")).leaf = true
@ -161,6 +162,19 @@ function socks_autoswitch_remove_node()
luci.http.redirect(api.url("socks_config", id))
end
function gen_client_config()
local id = luci.http.formvalue("id")
local config_file = api.TMP_PATH .. "/config_" .. id
luci.sys.call(string.format("/usr/share/passwall2/app.sh run_socks flag=config_%s node=%s bind=127.0.0.1 socks_port=1080 config_file=%s no_run=1", id, id, config_file))
if nixio.fs.access(config_file) then
luci.http.prepare_content("application/json")
luci.http.write(luci.sys.exec("cat " .. config_file))
luci.sys.call("rm -f " .. config_file)
else
luci.http.redirect(api.url("node_list"))
end
end
function get_now_use_node()
local e = {}
local node = api.get_cache_var("ACL_GLOBAL_node")

View File

@ -41,17 +41,42 @@ end
e = t:option(DummyValue, "remarks", translate("Remarks"))
e.width = "15%"
---- Type
e = t:option(DummyValue, "type", translate("Type"))
e.width = "20%"
e.rawhtml = true
e.cfgvalue = function(t, n)
local v = Value.cfgvalue(t, n)
if v then
if v == "sing-box" or v == "Xray" then
local protocol = m:get(n, "protocol")
return v .. " -> " .. protocol
local str = ""
local type = m:get(n, "type") or ""
if type == "sing-box" or type == "Xray" then
local protocol = m:get(n, "protocol") or ""
if protocol == "vmess" then
protocol = "VMess"
elseif protocol == "vless" then
protocol = "VLESS"
elseif protocol == "shadowsocks" then
protocol = "SS"
elseif protocol == "shadowsocksr" then
protocol = "SSR"
elseif protocol == "wireguard" then
protocol = "WG"
elseif protocol == "hysteria" then
protocol = "HY"
elseif protocol == "hysteria2" then
protocol = "HY2"
elseif protocol == "anytls" then
protocol = "AnyTLS"
else
protocol = protocol:gsub("^%l",string.upper)
local custom = m:get(n, "custom") or "0"
if custom == "1" then
protocol = translate("Custom Config")
end
end
return v
if type == "sing-box" then type = "Sing-Box" end
type = type .. " " .. protocol
end
str = str .. translate(type)
return str
end
e = t:option(DummyValue, "port", translate("Port"))

View File

@ -18,32 +18,42 @@ end
s.fields["type"]:value(type_name, "Hysteria2")
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port"
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("obfs"), translate("Obfs Password"))
o.rewrite_option = o.option
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("auth_password"), translate("Auth Password"))
o.password = true
o.rewrite_option = o.option
o:depends({ [_n("custom")] = false })
o = s:option(Flag, _n("udp"), translate("UDP"))
o.default = "1"
o.rewrite_option = o.option
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("up_mbps"), translate("Max upload Mbps"))
o.rewrite_option = o.option
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("down_mbps"), translate("Max download Mbps"))
o.rewrite_option = o.option
o:depends({ [_n("custom")] = false })
o = s:option(Flag, _n("ignoreClientBandwidth"), translate("ignoreClientBandwidth"))
o.default = "0"
o.rewrite_option = o.option
o:depends({ [_n("custom")] = false })
o = s:option(FileUpload, _n("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem")
o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem"
if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end
o.validate = function(self, value, t)
if value and value ~= "" then
if not nixio.fs.access(value) then
@ -54,9 +64,11 @@ o.validate = function(self, value, t)
end
return nil
end
o:depends({ [_n("custom")] = false })
o = s:option(FileUpload, _n("tls_keyFile"), translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key")
o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key"
if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end
o.validate = function(self, value, t)
if value and value ~= "" then
if not nixio.fs.access(value) then
@ -67,6 +79,28 @@ o.validate = function(self, value, t)
end
return nil
end
o:depends({ [_n("custom")] = false })
o = s:option(TextValue, _n("custom_config"), translate("Custom Config"))
o.rows = 10
o.wrap = "off"
o:depends({ [_n("custom")] = true })
o.validate = function(self, value, t)
if value and api.jsonc.parse(value) then
return value
else
return nil, translate("Must be JSON text!")
end
end
o.custom_cfgvalue = function(self, section, value)
local config_str = m:get(section, "config_str")
if config_str then
return api.base64Decode(config_str)
end
end
o.custom_write = function(self, section, value)
m:set(section, "config_str", api.base64Encode(value))
end
o = s:option(Flag, _n("log"), translate("Log"))
o.default = "1"

View File

@ -29,6 +29,8 @@ if not s.fields["type"].default then
s.fields["type"].default = type_name
end
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
o = s:option(ListValue, _n("protocol"), translate("Protocol"))
o:value("vmess", "Vmess")
o:value("vless", "VLESS")
@ -37,9 +39,11 @@ o:value("socks", "Socks")
o:value("shadowsocks", "Shadowsocks")
o:value("trojan", "Trojan")
o:value("dokodemo-door", "dokodemo-door")
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port"
o:depends({ [_n("custom")] = false })
o = s:option(Flag, _n("auth"), translate("Auth"))
o.validate = function(self, value, t)
@ -191,6 +195,7 @@ o:depends({ [_n("tls")] = true })
-- [[ TLS部分 ]] --
o = s:option(FileUpload, _n("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem")
o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem"
if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end
o:depends({ [_n("tls")] = true, [_n("reality")] = false })
o.validate = function(self, value, t)
if value and value ~= "" then
@ -205,6 +210,7 @@ end
o = s:option(FileUpload, _n("tls_keyFile"), translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key")
o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key"
if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end
o:depends({ [_n("tls")] = true, [_n("reality")] = false })
o.validate = function(self, value, t)
if value and value ~= "" then
@ -346,6 +352,7 @@ o:depends({ [_n("transport")] = "grpc" })
o = s:option(Flag, _n("acceptProxyProtocol"), translate("acceptProxyProtocol"), translate("Whether to receive PROXY protocol, when this node want to be fallback or forwarded by proxy, it must be enable, otherwise it cannot be used."))
o.default = "0"
o:depends({ [_n("custom")] = false })
-- [[ Fallback部分 ]]--
o = s:option(Flag, _n("fallback"), translate("Fallback"))
@ -372,9 +379,11 @@ o:depends({ [_n("fallback")] = true })
o = s:option(Flag, _n("bind_local"), translate("Bind Local"), translate("When selected, it can only be accessed localhost."))
o.default = "0"
o:depends({ [_n("custom")] = false })
o = s:option(Flag, _n("accept_lan"), translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!"))
o.default = "0"
o:depends({ [_n("custom")] = false })
local nodes_table = {}
for k, e in ipairs(api.get_valid_nodes()) do
@ -392,6 +401,7 @@ o:value("_socks", translate("Custom Socks"))
o:value("_http", translate("Custom HTTP"))
o:value("_iface", translate("Custom Interface"))
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("outbound_node_address"), translate("Address (Support Domain Name)"))
o:depends({ [_n("outbound_node")] = "_socks"})
@ -415,6 +425,27 @@ o = s:option(Value, _n("outbound_node_iface"), translate("Interface"))
o.default = "eth1"
o:depends({ [_n("outbound_node")] = "_iface"})
o = s:option(TextValue, _n("custom_config"), translate("Custom Config"))
o.rows = 10
o.wrap = "off"
o:depends({ [_n("custom")] = true })
o.validate = function(self, value, t)
if value and api.jsonc.parse(value) then
return value
else
return nil, translate("Must be JSON text!")
end
end
o.custom_cfgvalue = function(self, section, value)
local config_str = m:get(section, "config_str")
if config_str then
return api.base64Decode(config_str)
end
end
o.custom_write = function(self, section, value)
m:set(section, "config_str", api.base64Encode(value))
end
o = s:option(Flag, _n("log"), translate("Log"))
o.default = "1"
o.rmempty = false

View File

@ -35,6 +35,8 @@ if not s.fields["type"].default then
s.fields["type"].default = type_name
end
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
o = s:option(ListValue, _n("protocol"), translate("Protocol"))
o:value("mixed", "Mixed")
o:value("socks", "Socks")
@ -57,9 +59,11 @@ if version_ge_1_12_0 then
o:value("anytls", "AnyTLS")
end
o:value("direct", "Direct")
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port"
o:depends({ [_n("custom")] = false })
o = s:option(Flag, _n("auth"), translate("Auth"))
o.validate = function(self, value, t)
@ -263,6 +267,7 @@ end
o = s:option(FileUpload, _n("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem")
o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem"
if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end
o:depends({ [_n("tls")] = true, [_n("reality")] = false })
o:depends({ [_n("protocol")] = "naive" })
o:depends({ [_n("protocol")] = "hysteria" })
@ -281,6 +286,7 @@ end
o = s:option(FileUpload, _n("tls_keyFile"), translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key")
o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key"
if o and o:formvalue(arg[1]) then o.default = o:formvalue(arg[1]) end
o:depends({ [_n("tls")] = true, [_n("reality")] = false })
o:depends({ [_n("protocol")] = "naive" })
o:depends({ [_n("protocol")] = "hysteria" })
@ -392,9 +398,11 @@ o:depends({ [_n("tcpbrutal")] = true })
o = s:option(Flag, _n("bind_local"), translate("Bind Local"), translate("When selected, it can only be accessed localhost."))
o.default = "0"
o:depends({ [_n("custom")] = false })
o = s:option(Flag, _n("accept_lan"), translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!"))
o.default = "0"
o:depends({ [_n("custom")] = false })
local nodes_table = {}
for k, e in ipairs(api.get_valid_nodes()) do
@ -412,6 +420,7 @@ o:value("_socks", translate("Custom Socks"))
o:value("_http", translate("Custom HTTP"))
o:value("_iface", translate("Custom Interface"))
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("outbound_node_address"), translate("Address (Support Domain Name)"))
o:depends({ [_n("outbound_node")] = "_socks" })
@ -435,6 +444,27 @@ o = s:option(Value, _n("outbound_node_iface"), translate("Interface"))
o.default = "eth1"
o:depends({ [_n("outbound_node")] = "_iface" })
o = s:option(TextValue, _n("custom_config"), translate("Custom Config"))
o.rows = 10
o.wrap = "off"
o:depends({ [_n("custom")] = true })
o.validate = function(self, value, t)
if value and api.jsonc.parse(value) then
return value
else
return nil, translate("Must be JSON text!")
end
end
o.custom_cfgvalue = function(self, section, value)
local config_str = m:get(section, "config_str")
if config_str then
return api.base64Decode(config_str)
end
end
o.custom_write = function(self, section, value)
m:set(section, "config_str", api.base64Encode(value))
end
o = s:option(Flag, _n("log"), translate("Log"))
o.default = "1"
o.rmempty = false

View File

@ -24,21 +24,49 @@ local ssrust_encrypt_method_list = {
s.fields["type"]:value(type_name, translate("Shadowsocks Rust"))
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port"
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("password"), translate("Password"))
o.password = true
o:depends({ [_n("custom")] = false })
o = s:option(ListValue, _n("method"), translate("Encrypt Method"))
for a, t in ipairs(ssrust_encrypt_method_list) do o:value(t) end
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
o.datatype = "uinteger"
o.default = 300
o:depends({ [_n("custom")] = false })
o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"))
o.default = "0"
o:depends({ [_n("custom")] = false })
o = s:option(TextValue, _n("custom_config"), translate("Custom Config"))
o.rows = 10
o.wrap = "off"
o:depends({ [_n("custom")] = true })
o.validate = function(self, value, t)
if value and api.jsonc.parse(value) then
return value
else
return nil, translate("Must be JSON text!")
end
end
o.custom_cfgvalue = function(self, section, value)
local config_str = m:get(section, "config_str")
if config_str then
return api.base64Decode(config_str)
end
end
o.custom_write = function(self, section, value)
m:set(section, "config_str", api.base64Encode(value))
end
o = s:option(Flag, _n("log"), translate("Log"))
o.default = "1"

View File

@ -27,21 +27,49 @@ local ss_encrypt_method_list = {
s.fields["type"]:value(type_name, translate("Shadowsocks"))
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port"
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("password"), translate("Password"))
o.password = true
o:depends({ [_n("custom")] = false })
o = s:option(ListValue, _n("method"), translate("Encrypt Method"))
for a, t in ipairs(ss_encrypt_method_list) do o:value(t) end
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
o.datatype = "uinteger"
o.default = 300
o:depends({ [_n("custom")] = false })
o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"))
o.default = "0"
o:depends({ [_n("custom")] = false })
o = s:option(TextValue, _n("custom_config"), translate("Custom Config"))
o.rows = 10
o.wrap = "off"
o:depends({ [_n("custom")] = true })
o.validate = function(self, value, t)
if value and api.jsonc.parse(value) then
return value
else
return nil, translate("Must be JSON text!")
end
end
o.custom_cfgvalue = function(self, section, value)
local config_str = m:get(section, "config_str")
if config_str then
return api.base64Decode(config_str)
end
end
o.custom_write = function(self, section, value)
m:set(section, "config_str", api.base64Encode(value))
end
o = s:option(Flag, _n("log"), translate("Log"))
o.default = "1"

View File

@ -37,31 +37,63 @@ local ssr_obfs_list = {
s.fields["type"]:value(type_name, translate("ShadowsocksR"))
o = s:option(Flag, _n("custom"), translate("Use Custom Config"))
o = s:option(Value, _n("port"), translate("Listen Port"))
o.datatype = "port"
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("password"), translate("Password"))
o.password = true
o:depends({ [_n("custom")] = false })
o = s:option(ListValue, _n("method"), translate("Encrypt Method"))
for a, t in ipairs(ssr_encrypt_method_list) do o:value(t) end
o:depends({ [_n("custom")] = false })
o = s:option(ListValue, _n("protocol"), translate("Protocol"))
for a, t in ipairs(ssr_protocol_list) do o:value(t) end
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("protocol_param"), translate("Protocol_param"))
o:depends({ [_n("custom")] = false })
o = s:option(ListValue, _n("obfs"), translate("Obfs"))
for a, t in ipairs(ssr_obfs_list) do o:value(t) end
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("obfs_param"), translate("Obfs_param"))
o:depends({ [_n("custom")] = false })
o = s:option(Value, _n("timeout"), translate("Connection Timeout"))
o.datatype = "uinteger"
o.default = 300
o:depends({ [_n("custom")] = false })
o = s:option(Flag, _n("tcp_fast_open"), "TCP " .. translate("Fast Open"))
o.default = "0"
o:depends({ [_n("custom")] = false })
o = s:option(TextValue, _n("custom_config"), translate("Custom Config"))
o.rows = 10
o.wrap = "off"
o:depends({ [_n("custom")] = true })
o.validate = function(self, value, t)
if value and api.jsonc.parse(value) then
return value
else
return nil, translate("Must be JSON text!")
end
end
o.custom_cfgvalue = function(self, section, value)
local config_str = m:get(section, "config_str")
if config_str then
return api.base64Decode(config_str)
end
end
o.custom_write = function(self, section, value)
m:set(section, "config_str", api.base64Encode(value))
end
o = s:option(Flag, _n("udp_forward"), translate("UDP Forward"))
o.default = "1"

View File

@ -122,6 +122,11 @@ function base64Decode(text)
end
end
function base64Encode(text)
local result = nixio.bin.b64encode(text)
return result
end
--提取URL中的域名和端口(no ip)
function get_domain_port_from_url(url)
local scheme, domain, port = string.match(url, "^(https?)://([%w%.%-]+):?(%d*)")
@ -1222,11 +1227,16 @@ function luci_types(id, m, s, type_name, option_prefix)
end
s.fields[key].cfgvalue = function(self, section)
if self.rewrite_option then
return m:get(section, self.rewrite_option)
-- 添加自定义 custom_cfgvalue 属性,如果有自定义的 custom_cfgvalue 函数,则使用自定义的 cfgvalue 逻辑
if self.custom_cfgvalue then
return self:custom_cfgvalue(section)
else
if self.option:find(option_prefix) == 1 then
return m:get(section, self.option:sub(1 + #option_prefix))
if self.rewrite_option then
return m:get(section, self.rewrite_option)
else
if self.option:find(option_prefix) == 1 then
return m:get(section, self.option:sub(1 + #option_prefix))
end
end
end
end

View File

@ -120,20 +120,12 @@ local function start()
local config_file = CONFIG_PATH .. "/" .. id .. ".json"
local udp_forward = 1
local type = user.type or ""
if type == "Socks" then
local auth = ""
if user.auth and user.auth == "1" then
local username = user.username or ""
local password = user.password or ""
if username ~= "" and password ~= "" then
username = "-u " .. username
password = "-P " .. password
auth = username .. " " .. password
end
if type == "SS" or type == "SSR" then
if user.custom == "1" and user.config_str then
config = jsonc.parse(api.base64Decode(user.config_str))
else
config = require(require_dir .. "util_shadowsocks").gen_config_server(user)
end
bin = ln_run("/usr/bin/microsocks", "microsocks_" .. id, string.format("-i :: -p %s %s", port, auth), log_path)
elseif type == "SS" or type == "SSR" then
config = require(require_dir .. "util_shadowsocks").gen_config_server(user)
local udp_param = ""
udp_forward = tonumber(user.udp_forward) or 1
if udp_forward == 1 then
@ -142,16 +134,47 @@ local function start()
type = type:lower()
bin = ln_run("/usr/bin/" .. type .. "-server", type .. "-server", "-c " .. config_file .. " " .. udp_param, log_path)
elseif type == "SS-Rust" then
config = require(require_dir .. "util_shadowsocks").gen_config_server(user)
if user.custom == "1" and user.config_str then
config = jsonc.parse(api.base64Decode(user.config_str))
else
config = require(require_dir .. "util_shadowsocks").gen_config_server(user)
end
bin = ln_run("/usr/bin/ssserver", "ssserver", "-c " .. config_file, log_path)
elseif type == "Xray" then
config = require(require_dir .. "util_xray").gen_config_server(user)
if user.custom == "1" and user.config_str then
config = jsonc.parse(api.base64Decode(user.config_str))
if log_path then
if not config.log then
config.log = {}
end
config.log.loglevel = user.loglevel
end
else
config = require(require_dir .. "util_xray").gen_config_server(user)
end
bin = ln_run(api.get_app_path("xray"), "xray", "run -c " .. config_file, log_path)
elseif type == "sing-box" then
config = require(require_dir .. "util_sing-box").gen_config_server(user)
if user.custom == "1" and user.config_str then
config = jsonc.parse(api.base64Decode(user.config_str))
if log_path then
if not config.log then
config.log = {}
end
config.log.timestamp = true
config.log.disabled = false
config.log.level = user.loglevel
config.log.output = log_path
end
else
config = require(require_dir .. "util_sing-box").gen_config_server(user)
end
bin = ln_run(api.get_app_path("sing-box"), "sing-box", "run -c " .. config_file, log_path)
elseif type == "Hysteria2" then
config = require(require_dir .. "util_hysteria2").gen_config_server(user)
if user.custom == "1" and user.config_str then
config = jsonc.parse(api.base64Decode(user.config_str))
else
config = require(require_dir .. "util_hysteria2").gen_config_server(user)
end
bin = ln_run(api.get_app_path("hysteria"), "hysteria", "-c " .. config_file .. " server", log_path)
end
@ -161,7 +184,7 @@ local function start()
f:write(jsonc.stringify(config, 1))
f:close()
end
log(string.format("%s %s 生成配置文件并运行 - %s", remarks, port, config_file))
log(string.format("%s 生成配置文件并运行 - %s", remarks, config_file))
end
if bin then
@ -169,7 +192,7 @@ local function start()
end
local bind_local = user.bind_local or 0
if bind_local and tonumber(bind_local) ~= 1 then
if bind_local and tonumber(bind_local) ~= 1 and port then
if nft_flag == "0" then
ipt(string.format('-A PSW2-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))
ip6t(string.format('-A PSW2-SERVER -p tcp --dport %s -m comment --comment "%s" -j ACCEPT', port, remarks))

View File

@ -31,8 +31,10 @@ function gen_outbound(flag, node, tag, proxy_table)
end
local proxy_tag = nil
local run_socks_instance = true
if proxy_table ~= nil and type(proxy_table) == "table" then
proxy_tag = proxy_table.tag or nil
run_socks_instance = proxy_table.run_socks_instance
end
if node.type ~= "sing-box" then
@ -42,18 +44,20 @@ function gen_outbound(flag, node, tag, proxy_table)
if tag and node_id and tag ~= node_id then
config_file = string.format("%s_%s_%s_%s.json", flag, tag, node_id, new_port)
end
sys.call(string.format('/usr/share/%s/app.sh run_socks "%s"> /dev/null',
appname,
string.format("flag=%s node=%s bind=%s socks_port=%s config_file=%s relay_port=%s",
new_port, --flag
node_id, --node
"127.0.0.1", --bind
new_port, --socks port
config_file, --config file
(proxy_tag and relay_port) and tostring(relay_port) or "" --relay port
if run_socks_instance then
sys.call(string.format('/usr/share/%s/app.sh run_socks "%s"> /dev/null',
appname,
string.format("flag=%s node=%s bind=%s socks_port=%s config_file=%s relay_port=%s",
new_port, --flag
node_id, --node
"127.0.0.1", --bind
new_port, --socks port
config_file, --config file
(proxy_tag and relay_port) and tostring(relay_port) or "" --relay port
)
)
)
)
end
node = {
protocol = "socks",
address = "127.0.0.1",
@ -820,6 +824,7 @@ function gen_config(var)
local remote_dns_client_ip = var["-remote_dns_client_ip"]
local dns_cache = var["-dns_cache"]
local tags = var["-tags"]
local no_run = var["-no_run"]
local dns_domain_rules = {}
local dns = nil
@ -1114,7 +1119,7 @@ function gen_config(var)
end
end
local _outbound = gen_outbound(flag, _node, rule_name, { tag = use_proxy and preproxy_tag or nil })
local _outbound = gen_outbound(flag, _node, rule_name, { tag = use_proxy and preproxy_tag or nil, run_socks_instance = not no_run})
if _outbound then
_outbound.tag = _outbound.tag .. ":" .. _node.remarks
rule_outboundTag, last_insert_outbound = set_outbound_detour(_node, _outbound, outbounds, rule_name)
@ -1577,7 +1582,7 @@ function gen_config(var)
tag = "block"
})
for index, value in ipairs(config.outbounds) do
if not value["_flag_proxy_tag"] and not value.detour and value["_id"] and value.server and value.server_port then
if not value["_flag_proxy_tag"] and not value.detour and value["_id"] and value.server and value.server_port and not no_run then
sys.call(string.format("echo '%s' >> %s", value["_id"], api.TMP_PATH .. "/direct_node_list"))
end
for k, v in pairs(config.outbounds[index]) do

View File

@ -58,10 +58,12 @@ function gen_outbound(flag, node, tag, proxy_table)
local proxy_tag = nil
local fragment = nil
local noise = nil
local run_socks_instance = true
if proxy_table ~= nil and type(proxy_table) == "table" then
proxy_tag = proxy_table.tag or nil
fragment = proxy_table.fragment or nil
noise = proxy_table.noise or nil
run_socks_instance = proxy_table.run_socks_instance
end
if node.type ~= "Xray" then
@ -71,18 +73,20 @@ function gen_outbound(flag, node, tag, proxy_table)
if tag and node_id and tag ~= node_id then
config_file = string.format("%s_%s_%s_%s.json", flag, tag, node_id, new_port)
end
sys.call(string.format('/usr/share/%s/app.sh run_socks "%s"> /dev/null',
appname,
string.format("flag=%s node=%s bind=%s socks_port=%s config_file=%s relay_port=%s",
new_port, --flag
node_id, --node
"127.0.0.1", --bind
new_port, --socks port
config_file, --config file
(proxy_tag and relay_port) and tostring(relay_port) or "" --relay port
if run_socks_instance then
sys.call(string.format('/usr/share/%s/app.sh run_socks "%s"> /dev/null',
appname,
string.format("flag=%s node=%s bind=%s socks_port=%s config_file=%s relay_port=%s",
new_port, --flag
node_id, --node
"127.0.0.1", --bind
new_port, --socks port
config_file, --config file
(proxy_tag and relay_port) and tostring(relay_port) or "" --relay port
)
)
)
)
end
node = {}
node.protocol = "socks"
node.transport = "tcp"
@ -577,6 +581,7 @@ function gen_config(var)
local remote_dns_query_strategy = var["-remote_dns_query_strategy"]
local remote_dns_detour = var["-remote_dns_detour"]
local dns_cache = var["-dns_cache"]
local no_run = var["-no_run"]
local dns_domain_rules = {}
local dns = nil
@ -928,7 +933,8 @@ function gen_config(var)
})
end
local proxy_table = {
tag = use_proxy and preproxy_tag or nil
tag = use_proxy and preproxy_tag or nil,
run_socks_instance = not no_run
}
if not proxy_table.tag then
if xray_settings.fragment == "1" then
@ -1580,7 +1586,7 @@ function gen_config(var)
end
for index, value in ipairs(config.outbounds) do
if not value["_flag_proxy_tag"] and value["_id"] and value.server and value.server_port then
if not value["_flag_proxy_tag"] and value["_id"] and value.server and value.server_port and not no_run then
sys.call(string.format("echo '%s' >> %s", value["_id"], api.TMP_PATH .. "/direct_node_list"))
end
for k, v in pairs(config.outbounds[index]) do

View File

@ -1510,11 +1510,16 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin
s.innerHTML = "<font color='green'><%:Import Finished %></font>";
return false;
}
function exportConfigFile(btn, sid) {
window.open('<%=api.url("gen_client_config")%>?id=' + sid, "_blank")
}
//]]></script>
<input type="button" class="btn cbi-button cbi-button-apply" value='<%:From Share URL%>' onclick="return fromUrl(this, '<%=self.option%>', '<%=self.value%>')" />
<input type="button" class="btn cbi-button cbi-button-apply" value='<%:Build Share URL%>' onclick="return exportUrl(this, '<%=self.option%>', '<%=self.value%>')" />
<input type="button" class="btn cbi-button cbi-button-apply" value='<%:Generate QRCode%>' onclick="return genQrcode(this, '<%=self.option%>', '<%=self.value%>')" />
<input type="button" class="btn cbi-button cbi-button-apply" value='<%:Export Config File%>' onclick="return exportConfigFile(this, '<%=self.value%>')" />
<div id="qrcode_div" style="margin-top: 1rem;display:none">
<div id="qrcode"></div>
</div>

View File

@ -424,6 +424,9 @@ msgstr "导出分享URL"
msgid "Generate QRCode"
msgstr "生成二维码"
msgid "Export Config File"
msgstr "导出配置文件"
msgid "Import Finished"
msgstr "导入完成:"
@ -1692,3 +1695,12 @@ msgstr "端口跳跃范围"
msgid "Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,)."
msgstr "格式为1000:2000 或 1000-2000 多组时用逗号(,)隔开。"
msgid "Use Custom Config"
msgstr "使用自定义配置"
msgid "Custom Config"
msgstr "自定义配置"
msgid "Must be JSON text!"
msgstr "必须是 JSON 文本内容!"

View File

@ -556,7 +556,7 @@ run_singbox() {
}
run_socks() {
local flag node bind socks_port config_file http_port http_config_file relay_port log_file
local flag node bind socks_port config_file http_port http_config_file relay_port log_file no_run
eval_set_val $@
[ -n "$config_file" ] && [ -z "$(echo ${config_file} | grep $TMP_PATH)" ] && config_file=$TMP_PATH/$config_file
[ -n "$http_port" ] || http_port=0
@ -569,20 +569,20 @@ run_socks() {
local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
local remarks=$(config_n_get $node remarks)
local server_host=$(config_n_get $node address)
local port=$(config_n_get $node port)
local server_port=$(config_n_get $node port)
[ -n "$relay_port" ] && {
server_host="127.0.0.1"
port=$relay_port
server_port=$relay_port
}
local error_msg tmp
if [ -n "$server_host" ] && [ -n "$port" ]; then
if [ -n "$server_host" ] && [ -n "$server_port" ]; then
check_host $server_host
[ $? != 0 ] && {
echolog " - Socks节点[$remarks]${server_host} 是非法的服务器地址,无法启动!"
return 1
}
tmp="${server_host}:${port}"
tmp="${server_host}:${server_port}"
else
error_msg="某种原因,此 Socks 服务的相关配置已失联,启动中止!"
fi
@ -607,14 +607,15 @@ run_socks() {
config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g")
local _extra_param="-local_http_address $bind -local_http_port $http_port"
}
[ -n "$relay_port" ] && _extra_param="${_extra_param} -server_host $server_host -server_port $port"
[ -n "$relay_port" ] && _extra_param="${_extra_param} -server_host $server_host -server_port $server_port"
[ "${log_file}" != "/dev/null" ] && {
local loglevel=$(config_t_get global loglevel "warn")
[ "$loglevel" = "warning" ] && loglevel="warn"
_extra_param="${_extra_param} -log 1 -loglevel $loglevel -logfile $log_file"
}
[ -n "$no_run" ] && _extra_param="${_extra_param} -no_run 1"
lua $UTIL_SINGBOX gen_config -flag SOCKS_$flag -node $node -local_socks_address $bind -local_socks_port $socks_port ${_extra_param} > $config_file
ln_run "$(first_type $(config_t_get global_app singbox_file) sing-box)" "sing-box" /dev/null run -c "$config_file"
[ -n "$no_run" ] || ln_run "$(first_type $(config_t_get global_app singbox_file) sing-box)" "sing-box" /dev/null run -c "$config_file"
;;
xray)
[ "$http_port" != "0" ] && {
@ -622,21 +623,22 @@ run_socks() {
config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g")
local _extra_param="-local_http_address $bind -local_http_port $http_port"
}
[ -n "$relay_port" ] && _extra_param="${_extra_param} -server_host $server_host -server_port $port"
[ -n "$relay_port" ] && _extra_param="${_extra_param} -server_host $server_host -server_port $server_port"
[ -n "$no_run" ] && _extra_param="${_extra_param} -no_run 1"
lua $UTIL_XRAY gen_config -flag SOCKS_$flag -node $node -local_socks_address $bind -local_socks_port $socks_port ${_extra_param} > $config_file
ln_run "$(first_type $(config_t_get global_app xray_file) xray)" "xray" $log_file run -c "$config_file"
[ -n "$no_run" ] || ln_run "$(first_type $(config_t_get global_app xray_file) xray)" "xray" $log_file run -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 $port > $config_file
ln_run "$(first_type naive)" naive $log_file "$config_file"
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
[ -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 $port > $config_file
ln_run "$(first_type ssr-local)" "ssr-local" $log_file -c "$config_file" -v -u
lua $UTIL_SS gen_config -node $node -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $server_port > $config_file
[ -n "$no_run" ] || ln_run "$(first_type ssr-local)" "ssr-local" $log_file -c "$config_file" -v -u
;;
ss)
lua $UTIL_SS gen_config -node $node -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $port -mode tcp_and_udp > $config_file
ln_run "$(first_type ss-local)" "ss-local" $log_file -c "$config_file" -v
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 > $config_file
[ -n "$no_run" ] || ln_run "$(first_type ss-local)" "ss-local" $log_file -c "$config_file" -v
;;
ss-rust)
[ "$http_port" != "0" ] && {
@ -644,8 +646,8 @@ run_socks() {
config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g")
local _extra_param="-local_http_address $bind -local_http_port $http_port"
}
lua $UTIL_SS gen_config -node $node -local_socks_address $bind -local_socks_port $socks_port -server_host $server_host -server_port $port ${_extra_param} > $config_file
ln_run "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v
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
[ -n "$no_run" ] || ln_run "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v
;;
hysteria2)
[ "$http_port" != "0" ] && {
@ -653,12 +655,12 @@ run_socks() {
config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g")
local _extra_param="-local_http_address $bind -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 $port ${_extra_param} > $config_file
ln_run "$(first_type $(config_t_get global_app hysteria_file))" "hysteria" $log_file -c "$config_file" client
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
[ -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 $port > $config_file
ln_run "$(first_type tuic-client)" "tuic-client" $log_file -c "$config_file"
lua $UTIL_TUIC gen_config -node $node -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $server_port > $config_file
[ -n "$no_run" ] || ln_run "$(first_type tuic-client)" "tuic-client" $log_file -c "$config_file"
;;
esac
@ -668,18 +670,18 @@ run_socks() {
if [ -n "$bin" ]; then
type="sing-box"
lua $UTIL_SINGBOX gen_proto_config -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
ln_run "$bin" ${type} /dev/null run -c "$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_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
ln_run "$bin" ${type} /dev/null run -c "$http_config_file"
[ -n "$no_run" ] || ln_run "$bin" ${type} /dev/null run -c "$http_config_file"
fi
}
unset http_flag
[ "${server_host}" != "127.0.0.1" ] && [ "$type" != "sing-box" ] && [ "$type" != "xray" ] && echo "${node}" >> $TMP_PATH/direct_node_list
[ -z "$no_run" ] && [ "${server_host}" != "127.0.0.1" ] && [ "$type" != "sing-box" ] && [ "$type" != "xray" ] && echo "${node}" >> $TMP_PATH/direct_node_list
}
socks_node_switch() {