luci-app-passwall2: sync upstream
This commit is contained in:
parent
0a9636efda
commit
714c9178fa
@ -5,7 +5,7 @@
|
|||||||
include $(TOPDIR)/rules.mk
|
include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=luci-app-passwall2
|
PKG_NAME:=luci-app-passwall2
|
||||||
PKG_VERSION:=1.19-6
|
PKG_VERSION:=1.20-4
|
||||||
PKG_RELEASE:=
|
PKG_RELEASE:=
|
||||||
|
|
||||||
PKG_CONFIG_DEPENDS:= \
|
PKG_CONFIG_DEPENDS:= \
|
||||||
@ -23,8 +23,8 @@ PKG_CONFIG_DEPENDS:= \
|
|||||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client \
|
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client \
|
||||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server \
|
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server \
|
||||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs \
|
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs \
|
||||||
|
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_SingBox \
|
||||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_tuic_client \
|
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_tuic_client \
|
||||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \
|
|
||||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin
|
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin
|
||||||
|
|
||||||
LUCI_TITLE:=LuCI support for PassWall 2
|
LUCI_TITLE:=LuCI support for PassWall 2
|
||||||
@ -47,8 +47,8 @@ LUCI_DEPENDS:=+coreutils +coreutils-base64 +coreutils-nohup +curl \
|
|||||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client:shadowsocksr-libev-ssr-redir \
|
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client:shadowsocksr-libev-ssr-redir \
|
||||||
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server:shadowsocksr-libev-ssr-server \
|
+PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server:shadowsocksr-libev-ssr-server \
|
||||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs:simple-obfs \
|
+PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs:simple-obfs \
|
||||||
|
+PACKAGE_$(PKG_NAME)_INCLUDE_SingBox:sing-box \
|
||||||
+PACKAGE_$(PKG_NAME)_INCLUDE_tuic_client:tuic-client \
|
+PACKAGE_$(PKG_NAME)_INCLUDE_tuic_client:tuic-client \
|
||||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray-core \
|
|
||||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin:v2ray-plugin
|
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin:v2ray-plugin
|
||||||
|
|
||||||
define Package/$(PKG_NAME)/config
|
define Package/$(PKG_NAME)/config
|
||||||
@ -133,15 +133,15 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs
|
|||||||
bool "Include Simple-Obfs (Shadowsocks Plugin)"
|
bool "Include Simple-Obfs (Shadowsocks Plugin)"
|
||||||
default y
|
default y
|
||||||
|
|
||||||
|
config PACKAGE_$(PKG_NAME)_INCLUDE_SingBox
|
||||||
|
bool "Include Sing-Box"
|
||||||
|
default y if aarch64||arm||i386||x86_64
|
||||||
|
|
||||||
config PACKAGE_$(PKG_NAME)_INCLUDE_tuic_client
|
config PACKAGE_$(PKG_NAME)_INCLUDE_tuic_client
|
||||||
bool "Include tuic-client"
|
bool "Include tuic-client"
|
||||||
depends on aarch64||arm||i386||x86_64
|
depends on aarch64||arm||i386||x86_64
|
||||||
default n
|
default n
|
||||||
|
|
||||||
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray
|
|
||||||
bool "Include V2ray"
|
|
||||||
default n
|
|
||||||
|
|
||||||
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin
|
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin
|
||||||
bool "Include V2ray-Plugin (Shadowsocks Plugin)"
|
bool "Include V2ray-Plugin (Shadowsocks Plugin)"
|
||||||
default y if aarch64||arm||i386||x86_64
|
default y if aarch64||arm||i386||x86_64
|
||||||
|
@ -2,7 +2,7 @@ local api = require "luci.passwall2.api"
|
|||||||
local appname = api.appname
|
local appname = api.appname
|
||||||
local uci = api.uci
|
local uci = api.uci
|
||||||
local datatypes = api.datatypes
|
local datatypes = api.datatypes
|
||||||
local has_v2ray = api.is_finded("v2ray")
|
local has_singbox = api.is_finded("sing-box")
|
||||||
local has_xray = api.is_finded("xray")
|
local has_xray = api.is_finded("xray")
|
||||||
|
|
||||||
m = Map(appname)
|
m = Map(appname)
|
||||||
@ -36,6 +36,8 @@ end
|
|||||||
|
|
||||||
m:append(Template(appname .. "/global/status"))
|
m:append(Template(appname .. "/global/status"))
|
||||||
|
|
||||||
|
local global_cfgid = uci:get_all(appname, "@global[0]")[".name"]
|
||||||
|
|
||||||
s = m:section(TypedSection, "global")
|
s = m:section(TypedSection, "global")
|
||||||
s.anonymous = true
|
s.anonymous = true
|
||||||
s.addremove = false
|
s.addremove = false
|
||||||
@ -51,7 +53,7 @@ node = s:taboption("Main", ListValue, "node", "<a style='color: red'>" .. transl
|
|||||||
node:value("nil", translate("Close"))
|
node:value("nil", translate("Close"))
|
||||||
|
|
||||||
-- 分流
|
-- 分流
|
||||||
if (has_v2ray or has_xray) and #nodes_table > 0 then
|
if (has_singbox or has_xray) and #nodes_table > 0 then
|
||||||
local normal_list = {}
|
local normal_list = {}
|
||||||
local balancing_list = {}
|
local balancing_list = {}
|
||||||
local shunt_list = {}
|
local shunt_list = {}
|
||||||
@ -84,10 +86,10 @@ if (has_v2ray or has_xray) and #nodes_table > 0 then
|
|||||||
if #normal_list > 0 then
|
if #normal_list > 0 then
|
||||||
for k, v in pairs(shunt_list) do
|
for k, v in pairs(shunt_list) do
|
||||||
local vid = v.id
|
local vid = v.id
|
||||||
-- shunt node type, V2ray or Xray
|
-- shunt node type, Sing-Box or Xray
|
||||||
local type = s:taboption("Main", ListValue, vid .. "-type", translate("Type"))
|
local type = s:taboption("Main", ListValue, vid .. "-type", translate("Type"))
|
||||||
if has_v2ray then
|
if has_singbox then
|
||||||
type:value("V2ray", translate("V2ray"))
|
type:value("sing-box", translate("Sing-Box"))
|
||||||
end
|
end
|
||||||
if has_xray then
|
if has_xray then
|
||||||
type:value("Xray", translate("Xray"))
|
type:value("Xray", translate("Xray"))
|
||||||
@ -119,7 +121,7 @@ if (has_v2ray or has_xray) and #nodes_table > 0 then
|
|||||||
o.cfgvalue = get_cfgvalue(v.id, "main_node")
|
o.cfgvalue = get_cfgvalue(v.id, "main_node")
|
||||||
o.write = get_write(v.id, "main_node")
|
o.write = get_write(v.id, "main_node")
|
||||||
|
|
||||||
if (has_v2ray and has_xray) or (v.type == "V2ray" and not has_v2ray) or (v.type == "Xray" and not has_xray) then
|
if (has_singbox and has_xray) or (v.type == "sing-box" and not has_singbox) or (v.type == "Xray" and not has_xray) then
|
||||||
type:depends("node", v.id)
|
type:depends("node", v.id)
|
||||||
else
|
else
|
||||||
type:depends("node", "hide") --不存在的依赖,即始终隐藏
|
type:depends("node", "hide") --不存在的依赖,即始终隐藏
|
||||||
@ -212,14 +214,6 @@ node_socks_port = s:taboption("Main", Value, "node_socks_port", translate("Node"
|
|||||||
node_socks_port.default = 1070
|
node_socks_port.default = 1070
|
||||||
node_socks_port.datatype = "port"
|
node_socks_port.datatype = "port"
|
||||||
|
|
||||||
--[[
|
|
||||||
if has_v2ray or has_xray then
|
|
||||||
node_http_port = s:taboption("Main", Value, "node_http_port", translate("Node") .. " HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use"))
|
|
||||||
node_http_port.default = 0
|
|
||||||
node_http_port.datatype = "port"
|
|
||||||
end
|
|
||||||
]]--
|
|
||||||
|
|
||||||
s:tab("DNS", translate("DNS"))
|
s:tab("DNS", translate("DNS"))
|
||||||
|
|
||||||
o = s:taboption("DNS", ListValue, "remote_dns_protocol", translate("Remote DNS Protocol"))
|
o = s:taboption("DNS", ListValue, "remote_dns_protocol", translate("Remote DNS Protocol"))
|
||||||
@ -260,8 +254,6 @@ o = s:taboption("DNS", Value, "remote_dns_client_ip", translate("Remote DNS EDNS
|
|||||||
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 />" ..
|
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.datatype = "ipaddr"
|
||||||
o:depends("remote_dns_protocol", "tcp")
|
|
||||||
o:depends("remote_dns_protocol", "doh")
|
|
||||||
|
|
||||||
o = s:taboption("DNS", Flag, "remote_fakedns", "FakeDNS", translate("Use FakeDNS work in the shunt domain that proxy."))
|
o = s:taboption("DNS", Flag, "remote_fakedns", "FakeDNS", translate("Use FakeDNS work in the shunt domain that proxy."))
|
||||||
o.default = "0"
|
o.default = "0"
|
||||||
@ -273,9 +265,16 @@ o:value("UseIP")
|
|||||||
o:value("UseIPv4")
|
o:value("UseIPv4")
|
||||||
o:value("UseIPv6")
|
o:value("UseIPv6")
|
||||||
|
|
||||||
hosts = s:taboption("DNS", TextValue, "dns_hosts", translate("Domain Override"))
|
o = s:taboption("DNS", TextValue, "dns_hosts", translate("Domain Override"))
|
||||||
hosts.rows = 5
|
o.rows = 5
|
||||||
hosts.wrap = "off"
|
o.wrap = "off"
|
||||||
|
o.remove = function(self, section)
|
||||||
|
local node_value = node:formvalue(global_cfgid)
|
||||||
|
local node_t = m:get(node_value)
|
||||||
|
if node_t.type == "Xray" then
|
||||||
|
AbstractValue.remove(self, section)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
o = s:taboption("DNS", Button, "clear_ipset", translate("Clear IPSET"), translate("Try this feature if the rule modification does not take effect."))
|
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"
|
o.inputstyle = "remove"
|
||||||
@ -284,6 +283,14 @@ function o.write(e, e)
|
|||||||
luci.http.redirect(api.url("log"))
|
luci.http.redirect(api.url("log"))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
for k, v in pairs(nodes_table) do
|
||||||
|
if v.type == "Xray" then
|
||||||
|
s.fields["remote_dns_client_ip"]:depends({ node = v.id, remote_dns_protocol = "tcp" })
|
||||||
|
s.fields["remote_dns_client_ip"]:depends({ node = v.id, remote_dns_protocol = "doh" })
|
||||||
|
s.fields["dns_hosts"]:depends({ node = v.id })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
s:tab("log", translate("Log"))
|
s:tab("log", translate("Log"))
|
||||||
o = s:taboption("log", Flag, "close_log", translate("Close Node Log"))
|
o = s:taboption("log", Flag, "close_log", translate("Close Node Log"))
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
@ -342,7 +349,7 @@ o.default = n + 1080
|
|||||||
o.datatype = "port"
|
o.datatype = "port"
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
|
|
||||||
if has_v2ray or has_xray then
|
if has_singbox or has_xray then
|
||||||
o = s:option(Value, "http_port", "HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use"))
|
o = s:option(Value, "http_port", "HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use"))
|
||||||
o.default = 0
|
o.default = 0
|
||||||
o.datatype = "port"
|
o.datatype = "port"
|
||||||
@ -351,7 +358,7 @@ end
|
|||||||
for k, v in pairs(nodes_table) do
|
for k, v in pairs(nodes_table) do
|
||||||
node:value(v.id, v["remark"])
|
node:value(v.id, v["remark"])
|
||||||
if v.type == "Socks" then
|
if v.type == "Socks" then
|
||||||
if has_v2ray or has_xray then
|
if has_singbox or has_xray then
|
||||||
socks_node:value(v.id, v["remark"])
|
socks_node:value(v.id, v["remark"])
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
@ -83,7 +83,7 @@ o.cfgvalue = function(t, n)
|
|||||||
local remarks = m:get(n, "remarks") or ""
|
local remarks = m:get(n, "remarks") or ""
|
||||||
local type = m:get(n, "type") or ""
|
local type = m:get(n, "type") or ""
|
||||||
str = str .. string.format("<input type='hidden' id='cbid.%s.%s.type' value='%s'/>", appname, n, type)
|
str = str .. string.format("<input type='hidden' id='cbid.%s.%s.type' value='%s'/>", appname, n, type)
|
||||||
if type == "V2ray" or type == "Xray" then
|
if type == "sing-box" or type == "Xray" then
|
||||||
local protocol = m:get(n, "protocol")
|
local protocol = m:get(n, "protocol")
|
||||||
if protocol == "_balancing" then
|
if protocol == "_balancing" then
|
||||||
protocol = translate("Balancing")
|
protocol = translate("Balancing")
|
||||||
|
@ -2,7 +2,7 @@ local api = require "luci.passwall2.api"
|
|||||||
local appname = api.appname
|
local appname = api.appname
|
||||||
local has_ss = api.is_finded("ss-redir")
|
local has_ss = api.is_finded("ss-redir")
|
||||||
local has_ss_rust = api.is_finded("sslocal")
|
local has_ss_rust = api.is_finded("sslocal")
|
||||||
local has_v2ray = api.is_finded("v2ray")
|
local has_singbox = api.is_finded("sing-box")
|
||||||
local has_xray = api.is_finded("xray")
|
local has_xray = api.is_finded("xray")
|
||||||
local ss_aead_type = {}
|
local ss_aead_type = {}
|
||||||
if has_ss then
|
if has_ss then
|
||||||
@ -11,8 +11,8 @@ end
|
|||||||
if has_ss_rust then
|
if has_ss_rust then
|
||||||
ss_aead_type[#ss_aead_type + 1] = "shadowsocks-rust"
|
ss_aead_type[#ss_aead_type + 1] = "shadowsocks-rust"
|
||||||
end
|
end
|
||||||
if has_v2ray then
|
if has_singbox then
|
||||||
ss_aead_type[#ss_aead_type + 1] = "v2ray"
|
ss_aead_type[#ss_aead_type + 1] = "sing-box"
|
||||||
end
|
end
|
||||||
if has_xray then
|
if has_xray then
|
||||||
ss_aead_type[#ss_aead_type + 1] = "xray"
|
ss_aead_type[#ss_aead_type + 1] = "xray"
|
||||||
|
@ -3,7 +3,7 @@ local appname = api.appname
|
|||||||
local sys = api.sys
|
local sys = api.sys
|
||||||
local has_ss = api.is_finded("ss-redir")
|
local has_ss = api.is_finded("ss-redir")
|
||||||
local has_ss_rust = api.is_finded("sslocal")
|
local has_ss_rust = api.is_finded("sslocal")
|
||||||
local has_v2ray = api.is_finded("v2ray")
|
local has_singbox = api.is_finded("sing-box")
|
||||||
local has_xray = api.is_finded("xray")
|
local has_xray = api.is_finded("xray")
|
||||||
local ss_aead_type = {}
|
local ss_aead_type = {}
|
||||||
if has_ss then
|
if has_ss then
|
||||||
@ -12,8 +12,8 @@ end
|
|||||||
if has_ss_rust then
|
if has_ss_rust then
|
||||||
ss_aead_type[#ss_aead_type + 1] = "shadowsocks-rust"
|
ss_aead_type[#ss_aead_type + 1] = "shadowsocks-rust"
|
||||||
end
|
end
|
||||||
if has_v2ray then
|
if has_singbox then
|
||||||
ss_aead_type[#ss_aead_type + 1] = "v2ray"
|
ss_aead_type[#ss_aead_type + 1] = "sing-box"
|
||||||
end
|
end
|
||||||
if has_xray then
|
if has_xray then
|
||||||
ss_aead_type[#ss_aead_type + 1] = "xray"
|
ss_aead_type[#ss_aead_type + 1] = "xray"
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
local api = require "luci.passwall2.api"
|
local api = require "luci.passwall2.api"
|
||||||
local appname = api.appname
|
local appname = api.appname
|
||||||
local fs = api.fs
|
local fs = api.fs
|
||||||
local has_v2ray = api.is_finded("v2ray")
|
local uci = api.uci
|
||||||
|
local has_singbox = api.is_finded("sing-box")
|
||||||
local has_xray = api.is_finded("xray")
|
local has_xray = api.is_finded("xray")
|
||||||
local has_fw3 = api.is_finded("fw3")
|
local has_fw3 = api.is_finded("fw3")
|
||||||
local has_fw4 = api.is_finded("fw4")
|
local has_fw4 = api.is_finded("fw4")
|
||||||
@ -126,8 +127,8 @@ o = s:option(Flag, "accept_icmpv6", translate("Hijacking ICMPv6 (IPv6 PING)"))
|
|||||||
o:depends("ipv6_tproxy", true)
|
o:depends("ipv6_tproxy", true)
|
||||||
o.default = 0
|
o.default = 0
|
||||||
|
|
||||||
if has_v2ray or has_xray then
|
if has_xray then
|
||||||
s = m:section(TypedSection, "global_xray", "V2Ray/Xray " .. translate("Settings"))
|
s = m:section(TypedSection, "global_xray", "Xray " .. translate("Settings"))
|
||||||
s.anonymous = true
|
s.anonymous = true
|
||||||
s.addremove = false
|
s.addremove = false
|
||||||
|
|
||||||
@ -158,4 +159,33 @@ if has_v2ray or has_xray then
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
if has_singbox then
|
||||||
|
s = m:section(TypedSection, "global_singbox", "Sing-Box " .. translate("Settings"))
|
||||||
|
s.anonymous = true
|
||||||
|
s.addremove = false
|
||||||
|
|
||||||
|
o = s:option(Flag, "sniff_override_destination", translate("Override the connection destination address"), translate("Override the connection destination address with the sniffed domain."))
|
||||||
|
o.default = 1
|
||||||
|
o.rmempty = false
|
||||||
|
|
||||||
|
o = s:option(Value, "geoip_path", translate("Custom geoip Path"))
|
||||||
|
o.default = "/tmp/singbox/geoip.db"
|
||||||
|
o.rmempty = false
|
||||||
|
|
||||||
|
o = s:option(Value, "geoip_url", translate("Custom geoip URL"))
|
||||||
|
o.default = "https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db"
|
||||||
|
o:value("https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db")
|
||||||
|
o.rmempty = false
|
||||||
|
|
||||||
|
o = s:option(Value, "geosite_path", translate("Custom geosite Path"))
|
||||||
|
o.default = "/tmp/singbox/geosite.db"
|
||||||
|
o.rmempty = false
|
||||||
|
|
||||||
|
o = s:option(Value, "geosite_url", translate("Custom geosite URL"))
|
||||||
|
o.default = "https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db"
|
||||||
|
o:value("https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db")
|
||||||
|
o.rmempty = false
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
@ -41,7 +41,7 @@ for e = 0, 23 do o:value(e, e .. translate("oclock")) end
|
|||||||
o.default = 0
|
o.default = 0
|
||||||
o:depends("auto_update", true)
|
o:depends("auto_update", true)
|
||||||
|
|
||||||
s = m:section(TypedSection, "shunt_rules", "V2ray/Xray " .. translate("Shunt Rule"), "<a style='color: red'>" .. translate("Please note attention to the priority, the higher the order, the higher the priority.") .. "</a>")
|
s = m:section(TypedSection, "shunt_rules", "Xray " .. translate("Shunt Rule"), "<a style='color: red'>" .. translate("Please note attention to the priority, the higher the order, the higher the priority.") .. "</a>")
|
||||||
s.template = "cbi/tblsection"
|
s.template = "cbi/tblsection"
|
||||||
s.anonymous = false
|
s.anonymous = false
|
||||||
s.addremove = true
|
s.addremove = true
|
||||||
|
@ -2,7 +2,7 @@ local api = require "luci.passwall2.api"
|
|||||||
local appname = api.appname
|
local appname = api.appname
|
||||||
local datatypes = api.datatypes
|
local datatypes = api.datatypes
|
||||||
|
|
||||||
m = Map(appname, "V2ray/Xray " .. translate("Shunt Rule"))
|
m = Map(appname, "Xray " .. translate("Shunt Rule"))
|
||||||
m.redirect = api.url()
|
m.redirect = api.url()
|
||||||
|
|
||||||
s = m:section(NamedSection, arg[1], "shunt_rules", "")
|
s = m:section(NamedSection, arg[1], "shunt_rules", "")
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
local api = require "luci.passwall2.api"
|
local api = require "luci.passwall2.api"
|
||||||
local appname = api.appname
|
local appname = api.appname
|
||||||
local uci = api.uci
|
local uci = api.uci
|
||||||
local has_v2ray = api.is_finded("v2ray")
|
local has_singbox = api.is_finded("sing-box")
|
||||||
local has_xray = api.is_finded("xray")
|
local has_xray = api.is_finded("xray")
|
||||||
|
|
||||||
m = Map(appname)
|
m = Map(appname)
|
||||||
@ -54,7 +54,7 @@ o.default = n + 1080
|
|||||||
o.datatype = "port"
|
o.datatype = "port"
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
|
|
||||||
if has_v2ray or has_xray then
|
if has_singbox or has_xray then
|
||||||
o = s:option(Value, "http_port", "HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use"))
|
o = s:option(Value, "http_port", "HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use"))
|
||||||
o.default = 0
|
o.default = 0
|
||||||
o.datatype = "port"
|
o.datatype = "port"
|
||||||
|
@ -2,13 +2,15 @@ local m, s = ...
|
|||||||
|
|
||||||
local api = require "luci.passwall2.api"
|
local api = require "luci.passwall2.api"
|
||||||
|
|
||||||
if not api.is_finded("xray") and not api.is_finded("v2ray") then
|
if not api.is_finded("xray") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
local appname = api.appname
|
local appname = api.appname
|
||||||
local uci = api.uci
|
local uci = api.uci
|
||||||
|
|
||||||
|
local type_name = "Xray"
|
||||||
|
|
||||||
local option_prefix = "xray_"
|
local option_prefix = "xray_"
|
||||||
|
|
||||||
local function option_name(name)
|
local function option_name(name)
|
||||||
@ -21,52 +23,20 @@ local function rm_prefix_cfgvalue(self, section)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
local function rm_prefix_write(self, section, value)
|
local function rm_prefix_write(self, section, value)
|
||||||
if s.fields["type"]:formvalue(arg[1]) == "Xray" or s.fields["type"]:formvalue(arg[1]) == "V2ray" then
|
if s.fields["type"]:formvalue(arg[1]) == type_name then
|
||||||
if self.option:find(option_prefix) == 1 then
|
if self.option:find(option_prefix) == 1 then
|
||||||
m:set(section, self.option:sub(1 + #option_prefix), value)
|
m:set(section, self.option:sub(1 + #option_prefix), value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local function rm_prefix_remove(self, section, value)
|
local function rm_prefix_remove(self, section, value)
|
||||||
if s.fields["type"]:formvalue(arg[1]) == "Xray" or s.fields["type"]:formvalue(arg[1]) == "V2ray" then
|
if s.fields["type"]:formvalue(arg[1]) == type_name then
|
||||||
if self.option:find(option_prefix) == 1 then
|
if self.option:find(option_prefix) == 1 then
|
||||||
m:del(section, self.option:sub(1 + #option_prefix))
|
m:del(section, self.option:sub(1 + #option_prefix))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function add_xray_depends(o, field, value)
|
|
||||||
local deps = { type = "Xray" }
|
|
||||||
if field then
|
|
||||||
if type(field) == "string" then
|
|
||||||
deps[field] = value
|
|
||||||
else
|
|
||||||
for key, value in pairs(field) do
|
|
||||||
deps[key] = value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
o:depends(deps)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function add_v2ray_depends(o, field, value)
|
|
||||||
local deps = { type = "V2ray" }
|
|
||||||
if field then
|
|
||||||
if type(field) == "string" then
|
|
||||||
deps[field] = value
|
|
||||||
else
|
|
||||||
for key, value in pairs(field) do
|
|
||||||
deps[key] = value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
o:depends(deps)
|
|
||||||
end
|
|
||||||
|
|
||||||
local v_ss_encrypt_method_list = {
|
|
||||||
"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305"
|
|
||||||
}
|
|
||||||
|
|
||||||
local x_ss_encrypt_method_list = {
|
local x_ss_encrypt_method_list = {
|
||||||
"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "xchacha20-poly1305", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "xchacha20-poly1305", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
||||||
}
|
}
|
||||||
@ -79,12 +49,7 @@ local header_type_list = {
|
|||||||
|
|
||||||
-- [[ Xray ]]
|
-- [[ Xray ]]
|
||||||
|
|
||||||
if api.is_finded("xray") then
|
s.fields["type"]:value(type_name, "Xray")
|
||||||
s.fields["type"]:value("Xray", translate("Xray"))
|
|
||||||
end
|
|
||||||
if api.is_finded("v2ray") then
|
|
||||||
s.fields["type"]:value("V2ray", translate("V2ray"))
|
|
||||||
end
|
|
||||||
|
|
||||||
o = s:option(ListValue, option_name("protocol"), translate("Protocol"))
|
o = s:option(ListValue, option_name("protocol"), translate("Protocol"))
|
||||||
o:value("vmess", translate("Vmess"))
|
o:value("vmess", translate("Vmess"))
|
||||||
@ -97,8 +62,6 @@ o:value("wireguard", translate("WireGuard"))
|
|||||||
o:value("_balancing", translate("Balancing"))
|
o:value("_balancing", translate("Balancing"))
|
||||||
o:value("_shunt", translate("Shunt"))
|
o:value("_shunt", translate("Shunt"))
|
||||||
o:value("_iface", translate("Custom Interface") .. " (Only Support Xray)")
|
o:value("_iface", translate("Custom Interface") .. " (Only Support Xray)")
|
||||||
add_xray_depends(o)
|
|
||||||
add_v2ray_depends(o)
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("iface"), translate("Interface"))
|
o = s:option(Value, option_name("iface"), translate("Interface"))
|
||||||
o.default = "eth1"
|
o.default = "eth1"
|
||||||
@ -131,31 +94,26 @@ end
|
|||||||
-- 负载均衡列表
|
-- 负载均衡列表
|
||||||
local o = s:option(DynamicList, option_name("balancing_node"), translate("Load balancing node list"), translate("Load balancing node list, <a target='_blank' href='https://toutyrater.github.io/routing/balance2.html'>document</a>"))
|
local o = s:option(DynamicList, option_name("balancing_node"), translate("Load balancing node list"), translate("Load balancing node list, <a target='_blank' href='https://toutyrater.github.io/routing/balance2.html'>document</a>"))
|
||||||
o:depends({ [option_name("protocol")] = "_balancing" })
|
o:depends({ [option_name("protocol")] = "_balancing" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "_balancing" })
|
|
||||||
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
|
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
|
||||||
|
|
||||||
local o = s:option(ListValue, option_name("balancingStrategy"), translate("Balancing Strategy"))
|
local o = s:option(ListValue, option_name("balancingStrategy"), translate("Balancing Strategy"))
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "_balancing" })
|
o:depends({ [option_name("protocol")] = "_balancing" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "_balancing" })
|
|
||||||
o:value("random")
|
o:value("random")
|
||||||
o:value("leastPing")
|
o:value("leastPing")
|
||||||
o.default = "random"
|
o.default = "random"
|
||||||
|
|
||||||
-- 探测地址
|
-- 探测地址
|
||||||
local o = s:option(Flag, option_name("useCustomProbeUrl"), translate("Use Custome Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL."))
|
local o = s:option(Flag, option_name("useCustomProbeUrl"), translate("Use Custome Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL."))
|
||||||
add_xray_depends(o, { [option_name("balancingStrategy")] = "leastPing" })
|
o:depends({ [option_name("balancingStrategy")] = "leastPing" })
|
||||||
add_v2ray_depends(o, { [option_name("balancingStrategy")] = "leastPing" })
|
|
||||||
|
|
||||||
local o = s:option(Value, option_name("probeUrl"), translate("Probe URL"))
|
local o = s:option(Value, option_name("probeUrl"), translate("Probe URL"))
|
||||||
add_xray_depends(o, { [option_name("useCustomProbeUrl")] = true })
|
o:depends({ [option_name("useCustomProbeUrl")] = true })
|
||||||
add_v2ray_depends(o, { [option_name("useCustomProbeUrl")] = true })
|
|
||||||
o.default = "https://www.google.com/generate_204"
|
o.default = "https://www.google.com/generate_204"
|
||||||
o.description = translate("The URL used to detect the connection status.")
|
o.description = translate("The URL used to detect the connection status.")
|
||||||
|
|
||||||
-- 探测间隔
|
-- 探测间隔
|
||||||
local o = s:option(Value, option_name("probeInterval"), translate("Probe Interval"))
|
local o = s:option(Value, option_name("probeInterval"), translate("Probe Interval"))
|
||||||
add_xray_depends(o, { [option_name("balancingStrategy")] = "leastPing" })
|
o:depends({ [option_name("balancingStrategy")] = "leastPing" })
|
||||||
add_v2ray_depends(o, { [option_name("balancingStrategy")] = "leastPing" })
|
|
||||||
o.default = "1m"
|
o.default = "1m"
|
||||||
o.description = translate("The interval between initiating probes. Every time this time elapses, a server status check is performed on a server. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively.")
|
o.description = translate("The interval between initiating probes. Every time this time elapses, a server status check is performed on a server. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively.")
|
||||||
|
|
||||||
@ -163,11 +121,9 @@ o.description = translate("The interval between initiating probes. Every time th
|
|||||||
if #nodes_table > 0 then
|
if #nodes_table > 0 then
|
||||||
o = s:option(Flag, option_name("preproxy_enabled"), translate("Preproxy"))
|
o = s:option(Flag, option_name("preproxy_enabled"), translate("Preproxy"))
|
||||||
o:depends({ [option_name("protocol")] = "_shunt" })
|
o:depends({ [option_name("protocol")] = "_shunt" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "_shunt" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("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:option(Value, option_name("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:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true })
|
o:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true })
|
|
||||||
for k, v in pairs(balancers_table) do
|
for k, v in pairs(balancers_table) do
|
||||||
o:value(v.id, v.remarks)
|
o:value(v.id, v.remarks)
|
||||||
end
|
end
|
||||||
@ -187,7 +143,6 @@ uci:foreach(appname, "shunt_rules", function(e)
|
|||||||
o:value("_direct", translate("Direct Connection"))
|
o:value("_direct", translate("Direct Connection"))
|
||||||
o:value("_blackhole", translate("Blackhole"))
|
o:value("_blackhole", translate("Blackhole"))
|
||||||
o:depends({ [option_name("protocol")] = "_shunt" })
|
o:depends({ [option_name("protocol")] = "_shunt" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "_shunt" })
|
|
||||||
|
|
||||||
if #nodes_table > 0 then
|
if #nodes_table > 0 then
|
||||||
for k, v in pairs(balancers_table) do
|
for k, v in pairs(balancers_table) do
|
||||||
@ -203,7 +158,6 @@ uci:foreach(appname, "shunt_rules", function(e)
|
|||||||
for k, v in pairs(nodes_table) do
|
for k, v in pairs(nodes_table) do
|
||||||
o:value(v.id, v.remarks)
|
o:value(v.id, v.remarks)
|
||||||
pt:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true, [option_name(e[".name"])] = v.id })
|
pt:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true, [option_name(e[".name"])] = v.id })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true, [option_name(e[".name"])] = v.id })
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -258,134 +212,88 @@ o:depends({ [option_name("protocol")] = "_shunt" })
|
|||||||
-- [[ 分流模块 End ]]
|
-- [[ 分流模块 End ]]
|
||||||
|
|
||||||
o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)"))
|
o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)"))
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vmess" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vless" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "http" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "socks" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "trojan" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "wireguard" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vmess" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vless" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "http" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "socks" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "trojan" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("port"), translate("Port"))
|
o = s:option(Value, option_name("port"), translate("Port"))
|
||||||
o.datatype = "port"
|
o.datatype = "port"
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vmess" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vless" })
|
local protocols = s.fields[option_name("protocol")].keylist
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "http" })
|
if #protocols > 0 then
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "socks" })
|
for index, value in ipairs(protocols) do
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
if not value:find("_") then
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "trojan" })
|
s.fields[option_name("address")]:depends({ [option_name("protocol")] = value })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "wireguard" })
|
s.fields[option_name("port")]:depends({ [option_name("protocol")] = value })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vmess" })
|
end
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vless" })
|
end
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "http" })
|
end
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "socks" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "trojan" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("username"), translate("Username"))
|
o = s:option(Value, option_name("username"), translate("Username"))
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "http" })
|
o:depends({ [option_name("protocol")] = "http" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "socks" })
|
o:depends({ [option_name("protocol")] = "socks" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "http" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "socks" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("password"), translate("Password"))
|
o = s:option(Value, option_name("password"), translate("Password"))
|
||||||
o.password = true
|
o.password = true
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "http" })
|
o:depends({ [option_name("protocol")] = "http" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "socks" })
|
o:depends({ [option_name("protocol")] = "socks" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "trojan" })
|
o:depends({ [option_name("protocol")] = "trojan" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "http" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "socks" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "trojan" })
|
|
||||||
|
|
||||||
o = s:option(ListValue, option_name("security"), translate("Encrypt Method"))
|
o = s:option(ListValue, option_name("security"), translate("Encrypt Method"))
|
||||||
for a, t in ipairs(security_list) do o:value(t) end
|
for a, t in ipairs(security_list) do o:value(t) end
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vmess" })
|
o:depends({ [option_name("protocol")] = "vmess" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vmess" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("encryption"), translate("Encrypt Method"))
|
o = s:option(Value, option_name("encryption"), translate("Encrypt Method"))
|
||||||
o.default = "none"
|
o.default = "none"
|
||||||
o:value("none")
|
o:value("none")
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vless" })
|
o:depends({ [option_name("protocol")] = "vless" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vless" })
|
|
||||||
|
|
||||||
o = s:option(ListValue, "v_ss_encrypt_method", translate("Encrypt Method"))
|
|
||||||
o.not_rewrite = true
|
|
||||||
for a, t in ipairs(v_ss_encrypt_method_list) do o:value(t) end
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
|
||||||
function o.cfgvalue(self, section)
|
|
||||||
return m:get(section, "method")
|
|
||||||
end
|
|
||||||
function o.write(self, section, value)
|
|
||||||
if s.fields["type"]:formvalue(arg[1]) == "Xray" or s.fields["type"]:formvalue(arg[1]) == "V2ray" then
|
|
||||||
m:set(section, "method", value)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
o = s:option(ListValue, option_name("x_ss_encrypt_method"), translate("Encrypt Method"))
|
o = s:option(ListValue, option_name("x_ss_encrypt_method"), translate("Encrypt Method"))
|
||||||
o.not_rewrite = true
|
o.not_rewrite = true
|
||||||
for a, t in ipairs(x_ss_encrypt_method_list) do o:value(t) end
|
for a, t in ipairs(x_ss_encrypt_method_list) do o:value(t) end
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
function o.cfgvalue(self, section)
|
function o.cfgvalue(self, section)
|
||||||
return m:get(section, "method")
|
return m:get(section, "method")
|
||||||
end
|
end
|
||||||
function o.write(self, section, value)
|
function o.write(self, section, value)
|
||||||
if s.fields["type"]:formvalue(arg[1]) == "Xray" or s.fields["type"]:formvalue(arg[1]) == "V2ray" then
|
if s.fields["type"]:formvalue(arg[1]) == type_name then
|
||||||
m:set(section, "method", value)
|
m:set(section, "method", value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:option(Flag, option_name("iv_check"), translate("IV Check"))
|
o = s:option(Flag, option_name("iv_check"), translate("IV Check"))
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "aes-128-gcm" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "aes-128-gcm" })
|
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "aes-256-gcm" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "aes-256-gcm" })
|
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "chacha20-poly1305" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "chacha20-poly1305" })
|
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "xchacha20-poly1305" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "xchacha20-poly1305" })
|
|
||||||
|
|
||||||
o = s:option(Flag, option_name("uot"), translate("UDP over TCP"), translate("Need Xray-core or sing-box as server side."))
|
o = s:option(Flag, option_name("uot"), translate("UDP over TCP"), translate("Need Xray-core or sing-box as server side."))
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "2022-blake3-aes-128-gcm" })
|
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "2022-blake3-aes-128-gcm" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "2022-blake3-aes-256-gcm" })
|
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "2022-blake3-aes-256-gcm" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "2022-blake3-chacha20-poly1305" })
|
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("x_ss_encrypt_method")] = "2022-blake3-chacha20-poly1305" })
|
||||||
|
|
||||||
o = s:option(Value, option_name("uuid"), translate("ID"))
|
o = s:option(Value, option_name("uuid"), translate("ID"))
|
||||||
o.password = true
|
o.password = true
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vmess" })
|
o:depends({ [option_name("protocol")] = "vmess" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vless" })
|
o:depends({ [option_name("protocol")] = "vless" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vmess" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vless" })
|
|
||||||
|
|
||||||
o = s:option(Flag, option_name("tls"), translate("TLS"))
|
o = s:option(ListValue, option_name("flow"), translate("flow"))
|
||||||
o.default = 0
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vmess" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vless" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "socks" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "trojan" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vmess" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vless" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "socks" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "trojan" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("tlsflow"), translate("flow"))
|
|
||||||
o.default = ""
|
o.default = ""
|
||||||
o:value("", translate("Disable"))
|
o:value("", translate("Disable"))
|
||||||
o:value("xtls-rprx-vision")
|
o:value("xtls-rprx-vision")
|
||||||
o:value("xtls-rprx-vision-udp443")
|
o:depends({ [option_name("protocol")] = "vless" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vless", [option_name("tls")] = true, [option_name("transport")] = "tcp" })
|
|
||||||
|
|
||||||
o = s:option(Flag, option_name("reality"), translate("REALITY"), translate("Only recommend to use with VLESS-TCP-XTLS-Vision."))
|
o = s:option(Flag, option_name("tls"), translate("TLS"))
|
||||||
o.default = 0
|
o.default = 0
|
||||||
add_xray_depends(o, { [option_name("tls")] = true, [option_name("transport")] = "tcp" })
|
o:depends({ [option_name("protocol")] = "vmess" })
|
||||||
add_xray_depends(o, { [option_name("tls")] = true, [option_name("transport")] = "h2" })
|
o:depends({ [option_name("protocol")] = "vless" })
|
||||||
add_xray_depends(o, { [option_name("tls")] = true, [option_name("transport")] = "grpc" })
|
o:depends({ [option_name("protocol")] = "socks" })
|
||||||
|
o:depends({ [option_name("protocol")] = "trojan" })
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
|
|
||||||
|
o = s:option(Flag, option_name("reality"), translate("REALITY"))
|
||||||
|
o.default = 0
|
||||||
|
o:depends({ [option_name("tls")] = true, [option_name("transport")] = "tcp" })
|
||||||
|
o:depends({ [option_name("tls")] = true, [option_name("transport")] = "h2" })
|
||||||
|
o:depends({ [option_name("tls")] = true, [option_name("transport")] = "grpc" })
|
||||||
|
|
||||||
o = s:option(ListValue, option_name("alpn"), translate("alpn"))
|
o = s:option(ListValue, option_name("alpn"), translate("alpn"))
|
||||||
o.default = "default"
|
o.default = "default"
|
||||||
@ -393,72 +301,49 @@ o:value("default", translate("Default"))
|
|||||||
o:value("h2,http/1.1")
|
o:value("h2,http/1.1")
|
||||||
o:value("h2")
|
o:value("h2")
|
||||||
o:value("http/1.1")
|
o:value("http/1.1")
|
||||||
add_xray_depends(o, { [option_name("tls")] = true, [option_name("reality")] = false })
|
o:depends({ [option_name("tls")] = true, [option_name("reality")] = false })
|
||||||
add_v2ray_depends(o, { [option_name("tls")] = true })
|
|
||||||
|
|
||||||
-- o = s:option(Value, option_name("minversion"), translate("minversion"))
|
-- o = s:option(Value, option_name("minversion"), translate("minversion"))
|
||||||
-- o.default = "1.3"
|
-- o.default = "1.3"
|
||||||
-- o:value("1.3")
|
-- o:value("1.3")
|
||||||
-- add_xray_depends(o, { [option_name("tls")] = true })
|
-- o:depends({ [option_name("tls")] = true })
|
||||||
-- add_v2ray_depends(o, { [option_name("tls")] = true })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("tls_serverName"), translate("Domain"))
|
o = s:option(Value, option_name("tls_serverName"), translate("Domain"))
|
||||||
add_xray_depends(o, { [option_name("tls")] = true })
|
o:depends({ [option_name("tls")] = true })
|
||||||
add_v2ray_depends(o, { [option_name("tls")] = true })
|
|
||||||
|
|
||||||
o = s:option(Flag, option_name("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped."))
|
o = s:option(Flag, option_name("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped."))
|
||||||
o.default = "0"
|
o.default = "0"
|
||||||
add_xray_depends(o, { [option_name("tls")] = true, [option_name("reality")] = false })
|
o:depends({ [option_name("tls")] = true, [option_name("reality")] = false })
|
||||||
add_v2ray_depends(o, { [option_name("tls")] = true })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("fingerprint"), translate("Finger Print"), translate("Avoid using randomized, unless you have to."))
|
|
||||||
o:value("", translate("Disable"))
|
|
||||||
o:value("chrome")
|
|
||||||
o:value("firefox")
|
|
||||||
o:value("safari")
|
|
||||||
o:value("ios")
|
|
||||||
-- o:value("android")
|
|
||||||
o:value("edge")
|
|
||||||
-- o:value("360")
|
|
||||||
o:value("qq")
|
|
||||||
o:value("random")
|
|
||||||
o:value("randomized")
|
|
||||||
o.default = ""
|
|
||||||
add_xray_depends(o, { [option_name("tls")] = true, [option_name("reality")] = false })
|
|
||||||
|
|
||||||
-- [[ REALITY部分 ]] --
|
-- [[ REALITY部分 ]] --
|
||||||
o = s:option(Value, option_name("reality_publicKey"), translate("Public Key"))
|
o = s:option(Value, option_name("reality_publicKey"), translate("Public Key"))
|
||||||
add_xray_depends(o, { [option_name("tls")] = true, [option_name("reality")] = true })
|
o:depends({ [option_name("tls")] = true, [option_name("reality")] = true })
|
||||||
|
|
||||||
o = s:option(Value, option_name("reality_shortId"), translate("Short Id"))
|
o = s:option(Value, option_name("reality_shortId"), translate("Short Id"))
|
||||||
add_xray_depends(o, { [option_name("tls")] = true, [option_name("reality")] = true })
|
o:depends({ [option_name("tls")] = true, [option_name("reality")] = true })
|
||||||
|
|
||||||
o = s:option(Value, option_name("reality_spiderX"), translate("Spider X"))
|
o = s:option(Value, option_name("reality_spiderX"), translate("Spider X"))
|
||||||
o.placeholder = "/"
|
o.placeholder = "/"
|
||||||
add_xray_depends(o, { [option_name("tls")] = true, [option_name("reality")] = true })
|
o:depends({ [option_name("tls")] = true, [option_name("reality")] = true })
|
||||||
|
|
||||||
o = s:option(Value, option_name("reality_fingerprint"), translate("Finger Print"), translate("Avoid using randomized, unless you have to."))
|
o = s:option(Flag, option_name("utls"), translate("uTLS"))
|
||||||
o.not_rewrite = true
|
o.default = "0"
|
||||||
|
o:depends({ [option_name("tls")] = true, [option_name("reality")] = false })
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("fingerprint"), translate("Finger Print"))
|
||||||
o:value("chrome")
|
o:value("chrome")
|
||||||
o:value("firefox")
|
o:value("firefox")
|
||||||
o:value("safari")
|
|
||||||
o:value("ios")
|
|
||||||
-- o:value("android")
|
|
||||||
o:value("edge")
|
o:value("edge")
|
||||||
-- o:value("360")
|
o:value("safari")
|
||||||
|
o:value("360")
|
||||||
o:value("qq")
|
o:value("qq")
|
||||||
|
o:value("ios")
|
||||||
|
o:value("android")
|
||||||
o:value("random")
|
o:value("random")
|
||||||
o:value("randomized")
|
o:value("randomized")
|
||||||
o.default = "chrome"
|
o.default = "chrome"
|
||||||
add_xray_depends(o, { [option_name("tls")] = true, [option_name("reality")] = true })
|
o:depends({ [option_name("tls")] = true, [option_name("utls")] = true })
|
||||||
function o.cfgvalue(self, section)
|
o:depends({ [option_name("tls")] = true, [option_name("reality")] = true })
|
||||||
return m:get(section, "fingerprint")
|
|
||||||
end
|
|
||||||
function o.write(self, section, value)
|
|
||||||
if s.fields["type"]:formvalue(arg[1]) == "Xray" or s.fields["type"]:formvalue(arg[1]) == "V2ray" then
|
|
||||||
m:set(section, "fingerprint", value)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
o = s:option(ListValue, option_name("transport"), translate("Transport"))
|
o = s:option(ListValue, option_name("transport"), translate("Transport"))
|
||||||
o:value("tcp", "TCP")
|
o:value("tcp", "TCP")
|
||||||
@ -468,50 +353,44 @@ o:value("h2", "HTTP/2")
|
|||||||
o:value("ds", "DomainSocket")
|
o:value("ds", "DomainSocket")
|
||||||
o:value("quic", "QUIC")
|
o:value("quic", "QUIC")
|
||||||
o:value("grpc", "gRPC")
|
o:value("grpc", "gRPC")
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vmess" })
|
o:depends({ [option_name("protocol")] = "vmess" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vless" })
|
o:depends({ [option_name("protocol")] = "vless" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "socks" })
|
o:depends({ [option_name("protocol")] = "socks" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "trojan" })
|
o:depends({ [option_name("protocol")] = "trojan" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vmess" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vless" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "socks" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "trojan" })
|
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
o = s:option(ListValue, option_name("ss_transport"), translate("Transport"))
|
o = s:option(ListValue, option_name("ss_transport"), translate("Transport"))
|
||||||
o:value("ws", "WebSocket")
|
o:value("ws", "WebSocket")
|
||||||
o:value("h2", "HTTP/2")
|
o:value("h2", "HTTP/2")
|
||||||
o:value("h2+ws", "HTTP/2 & WebSocket")
|
o:value("h2+ws", "HTTP/2 & WebSocket")
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
|
||||||
]]--
|
]]--
|
||||||
|
|
||||||
o = s:option(Value, option_name("wireguard_public_key"), translate("Public Key"))
|
o = s:option(Value, option_name("wireguard_public_key"), translate("Public Key"))
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "wireguard" })
|
o:depends({ [option_name("protocol")] = "wireguard" })
|
||||||
|
|
||||||
o = s:option(Value, option_name("wireguard_secret_key"), translate("Private Key"))
|
o = s:option(Value, option_name("wireguard_secret_key"), translate("Private Key"))
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "wireguard" })
|
o:depends({ [option_name("protocol")] = "wireguard" })
|
||||||
|
|
||||||
o = s:option(Value, option_name("wireguard_preSharedKey"), translate("Pre shared key"))
|
o = s:option(Value, option_name("wireguard_preSharedKey"), translate("Pre shared key"))
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "wireguard" })
|
o:depends({ [option_name("protocol")] = "wireguard" })
|
||||||
|
|
||||||
o = s:option(DynamicList, option_name("wireguard_local_address"), translate("Local Address"))
|
o = s:option(DynamicList, option_name("wireguard_local_address"), translate("Local Address"))
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "wireguard" })
|
o:depends({ [option_name("protocol")] = "wireguard" })
|
||||||
|
|
||||||
o = s:option(Value, option_name("wireguard_mtu"), translate("MTU"))
|
o = s:option(Value, option_name("wireguard_mtu"), translate("MTU"))
|
||||||
o.default = "1420"
|
o.default = "1420"
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "wireguard" })
|
o:depends({ [option_name("protocol")] = "wireguard" })
|
||||||
|
|
||||||
if api.compare_versions(api.get_app_version("xray"), ">=", "1.8.0") then
|
if api.compare_versions(api.get_app_version("xray"), ">=", "1.8.0") then
|
||||||
o = s:option(Value, option_name("wireguard_reserved"), translate("Reserved"), translate("Decimal numbers separated by \",\" or Base64-encoded strings."))
|
o = s:option(Value, option_name("wireguard_reserved"), translate("Reserved"), translate("Decimal numbers separated by \",\" or Base64-encoded strings."))
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "wireguard" })
|
o:depends({ [option_name("protocol")] = "wireguard" })
|
||||||
end
|
end
|
||||||
|
|
||||||
o = s:option(Value, option_name("wireguard_keepAlive"), translate("Keep Alive"))
|
o = s:option(Value, option_name("wireguard_keepAlive"), translate("Keep Alive"))
|
||||||
o.default = "0"
|
o.default = "0"
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "wireguard" })
|
o:depends({ [option_name("protocol")] = "wireguard" })
|
||||||
|
|
||||||
-- [[ TCP部分 ]]--
|
-- [[ TCP部分 ]]--
|
||||||
|
|
||||||
@ -519,194 +398,152 @@ add_xray_depends(o, { [option_name("protocol")] = "wireguard" })
|
|||||||
o = s:option(ListValue, option_name("tcp_guise"), translate("Camouflage Type"))
|
o = s:option(ListValue, option_name("tcp_guise"), translate("Camouflage Type"))
|
||||||
o:value("none", "none")
|
o:value("none", "none")
|
||||||
o:value("http", "http")
|
o:value("http", "http")
|
||||||
add_xray_depends(o, { [option_name("transport")] = "tcp" })
|
o:depends({ [option_name("transport")] = "tcp" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "tcp" })
|
|
||||||
|
|
||||||
-- HTTP域名
|
-- HTTP域名
|
||||||
o = s:option(DynamicList, option_name("tcp_guise_http_host"), translate("HTTP Host"))
|
o = s:option(DynamicList, option_name("tcp_guise_http_host"), translate("HTTP Host"))
|
||||||
add_xray_depends(o, { [option_name("tcp_guise")] = "http" })
|
o:depends({ [option_name("tcp_guise")] = "http" })
|
||||||
add_v2ray_depends(o, { [option_name("tcp_guise")] = "http" })
|
|
||||||
|
|
||||||
-- HTTP路径
|
-- HTTP路径
|
||||||
o = s:option(DynamicList, option_name("tcp_guise_http_path"), translate("HTTP Path"))
|
o = s:option(DynamicList, option_name("tcp_guise_http_path"), translate("HTTP Path"))
|
||||||
o.placeholder = "/"
|
o.placeholder = "/"
|
||||||
add_xray_depends(o, { [option_name("tcp_guise")] = "http" })
|
o:depends({ [option_name("tcp_guise")] = "http" })
|
||||||
add_v2ray_depends(o, { [option_name("tcp_guise")] = "http" })
|
|
||||||
|
|
||||||
-- [[ mKCP部分 ]]--
|
-- [[ mKCP部分 ]]--
|
||||||
|
|
||||||
o = s:option(ListValue, option_name("mkcp_guise"), translate("Camouflage Type"), translate('<br />none: default, no masquerade, data sent is packets with no characteristics.<br />srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).<br />utp: packets disguised as uTP will be recognized as bittorrent downloaded data.<br />wechat-video: packets disguised as WeChat video calls.<br />dtls: disguised as DTLS 1.2 packet.<br />wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)'))
|
o = s:option(ListValue, option_name("mkcp_guise"), translate("Camouflage Type"), translate('<br />none: default, no masquerade, data sent is packets with no characteristics.<br />srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).<br />utp: packets disguised as uTP will be recognized as bittorrent downloaded data.<br />wechat-video: packets disguised as WeChat video calls.<br />dtls: disguised as DTLS 1.2 packet.<br />wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)'))
|
||||||
for a, t in ipairs(header_type_list) do o:value(t) end
|
for a, t in ipairs(header_type_list) do o:value(t) end
|
||||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
o:depends({ [option_name("transport")] = "mkcp" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("mkcp_mtu"), translate("KCP MTU"))
|
o = s:option(Value, option_name("mkcp_mtu"), translate("KCP MTU"))
|
||||||
o.default = "1350"
|
o.default = "1350"
|
||||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
o:depends({ [option_name("transport")] = "mkcp" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("mkcp_tti"), translate("KCP TTI"))
|
o = s:option(Value, option_name("mkcp_tti"), translate("KCP TTI"))
|
||||||
o.default = "20"
|
o.default = "20"
|
||||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
o:depends({ [option_name("transport")] = "mkcp" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("mkcp_uplinkCapacity"), translate("KCP uplinkCapacity"))
|
o = s:option(Value, option_name("mkcp_uplinkCapacity"), translate("KCP uplinkCapacity"))
|
||||||
o.default = "5"
|
o.default = "5"
|
||||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
o:depends({ [option_name("transport")] = "mkcp" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("mkcp_downlinkCapacity"), translate("KCP downlinkCapacity"))
|
o = s:option(Value, option_name("mkcp_downlinkCapacity"), translate("KCP downlinkCapacity"))
|
||||||
o.default = "20"
|
o.default = "20"
|
||||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
o:depends({ [option_name("transport")] = "mkcp" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
|
||||||
|
|
||||||
o = s:option(Flag, option_name("mkcp_congestion"), translate("KCP Congestion"))
|
o = s:option(Flag, option_name("mkcp_congestion"), translate("KCP Congestion"))
|
||||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
o:depends({ [option_name("transport")] = "mkcp" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("mkcp_readBufferSize"), translate("KCP readBufferSize"))
|
o = s:option(Value, option_name("mkcp_readBufferSize"), translate("KCP readBufferSize"))
|
||||||
o.default = "1"
|
o.default = "1"
|
||||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
o:depends({ [option_name("transport")] = "mkcp" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("mkcp_writeBufferSize"), translate("KCP writeBufferSize"))
|
o = s:option(Value, option_name("mkcp_writeBufferSize"), translate("KCP writeBufferSize"))
|
||||||
o.default = "1"
|
o.default = "1"
|
||||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
o:depends({ [option_name("transport")] = "mkcp" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("mkcp_seed"), translate("KCP Seed"))
|
o = s:option(Value, option_name("mkcp_seed"), translate("KCP Seed"))
|
||||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
o:depends({ [option_name("transport")] = "mkcp" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
|
||||||
|
|
||||||
-- [[ WebSocket部分 ]]--
|
-- [[ WebSocket部分 ]]--
|
||||||
o = s:option(Value, option_name("ws_host"), translate("WebSocket Host"))
|
o = s:option(Value, option_name("ws_host"), translate("WebSocket Host"))
|
||||||
add_xray_depends(o, { [option_name("transport")] = "ws" })
|
o:depends({ [option_name("transport")] = "ws" })
|
||||||
add_xray_depends(o, { [option_name("ss_transport")] = "ws" })
|
o:depends({ [option_name("ss_transport")] = "ws" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "ws" })
|
|
||||||
add_v2ray_depends(o, { [option_name("ss_transport")] = "ws" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("ws_path"), translate("WebSocket Path"))
|
o = s:option(Value, option_name("ws_path"), translate("WebSocket Path"))
|
||||||
o.placeholder = "/"
|
o.placeholder = "/"
|
||||||
add_xray_depends(o, { [option_name("transport")] = "ws" })
|
o:depends({ [option_name("transport")] = "ws" })
|
||||||
add_xray_depends(o, { [option_name("ss_transport")] = "ws" })
|
o:depends({ [option_name("ss_transport")] = "ws" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "ws" })
|
|
||||||
add_v2ray_depends(o, { [option_name("ss_transport")] = "ws" })
|
|
||||||
|
|
||||||
o = s:option(Flag, "v2ray_ws_enableEarlyData", translate("Enable early data"))
|
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "ws" })
|
|
||||||
|
|
||||||
o = s:option(Value, "v2ray_ws_maxEarlyData", translate("Early data length"))
|
|
||||||
o.default = "1024"
|
|
||||||
add_v2ray_depends(o, { v2ray_ws_enableEarlyData = true })
|
|
||||||
|
|
||||||
o = s:option(Value, "v2ray_ws_earlyDataHeaderName", translate("Early data header name"), translate("Recommended value: Sec-WebSocket-Protocol"))
|
|
||||||
add_v2ray_depends(o, { v2ray_ws_enableEarlyData = true })
|
|
||||||
|
|
||||||
-- [[ HTTP/2部分 ]]--
|
-- [[ HTTP/2部分 ]]--
|
||||||
o = s:option(Value, option_name("h2_host"), translate("HTTP/2 Host"))
|
o = s:option(Value, option_name("h2_host"), translate("HTTP/2 Host"))
|
||||||
add_xray_depends(o, { [option_name("transport")] = "h2" })
|
o:depends({ [option_name("transport")] = "h2" })
|
||||||
add_xray_depends(o, { [option_name("ss_transport")] = "h2" })
|
o:depends({ [option_name("ss_transport")] = "h2" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "h2" })
|
|
||||||
add_v2ray_depends(o, { [option_name("ss_transport")] = "h2" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("h2_path"), translate("HTTP/2 Path"))
|
o = s:option(Value, option_name("h2_path"), translate("HTTP/2 Path"))
|
||||||
o.placeholder = "/"
|
o.placeholder = "/"
|
||||||
add_xray_depends(o, { [option_name("transport")] = "h2" })
|
o:depends({ [option_name("transport")] = "h2" })
|
||||||
add_xray_depends(o, { [option_name("ss_transport")] = "h2" })
|
o:depends({ [option_name("ss_transport")] = "h2" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "h2" })
|
|
||||||
add_v2ray_depends(o, { [option_name("ss_transport")] = "h2" })
|
|
||||||
|
|
||||||
o = s:option(Flag, option_name("h2_health_check"), translate("Health check"))
|
o = s:option(Flag, option_name("h2_health_check"), translate("Health check"))
|
||||||
add_xray_depends(o, { [option_name("transport")] = "h2" })
|
o:depends({ [option_name("transport")] = "h2" })
|
||||||
|
|
||||||
o = s:option(Value, option_name("h2_read_idle_timeout"), translate("Idle timeout"))
|
o = s:option(Value, option_name("h2_read_idle_timeout"), translate("Idle timeout"))
|
||||||
o.default = "10"
|
o.default = "10"
|
||||||
add_xray_depends(o, { [option_name("h2_health_check")] = true })
|
o:depends({ [option_name("h2_health_check")] = true })
|
||||||
|
|
||||||
o = s:option(Value, option_name("h2_health_check_timeout"), translate("Health check timeout"))
|
o = s:option(Value, option_name("h2_health_check_timeout"), translate("Health check timeout"))
|
||||||
o.default = "15"
|
o.default = "15"
|
||||||
add_xray_depends(o, { [option_name("h2_health_check")] = true })
|
o:depends({ [option_name("h2_health_check")] = true })
|
||||||
|
|
||||||
-- [[ DomainSocket部分 ]]--
|
-- [[ DomainSocket部分 ]]--
|
||||||
o = s:option(Value, option_name("ds_path"), "Path", translate("A legal file path. This file must not exist before running."))
|
o = s:option(Value, option_name("ds_path"), "Path", translate("A legal file path. This file must not exist before running."))
|
||||||
add_xray_depends(o, { [option_name("transport")] = "ds" })
|
o:depends({ [option_name("transport")] = "ds" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "ds" })
|
|
||||||
|
|
||||||
-- [[ QUIC部分 ]]--
|
-- [[ QUIC部分 ]]--
|
||||||
o = s:option(ListValue, option_name("quic_security"), translate("Encrypt Method"))
|
o = s:option(ListValue, option_name("quic_security"), translate("Encrypt Method"))
|
||||||
o:value("none")
|
o:value("none")
|
||||||
o:value("aes-128-gcm")
|
o:value("aes-128-gcm")
|
||||||
o:value("chacha20-poly1305")
|
o:value("chacha20-poly1305")
|
||||||
add_xray_depends(o, { [option_name("transport")] = "quic" })
|
o:depends({ [option_name("transport")] = "quic" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "quic" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("quic_key"), translate("Encrypt Method") .. translate("Key"))
|
o = s:option(Value, option_name("quic_key"), translate("Encrypt Method") .. translate("Key"))
|
||||||
add_xray_depends(o, { [option_name("transport")] = "quic" })
|
o:depends({ [option_name("transport")] = "quic" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "quic" })
|
|
||||||
|
|
||||||
o = s:option(ListValue, option_name("quic_guise"), translate("Camouflage Type"))
|
o = s:option(ListValue, option_name("quic_guise"), translate("Camouflage Type"))
|
||||||
for a, t in ipairs(header_type_list) do o:value(t) end
|
for a, t in ipairs(header_type_list) do o:value(t) end
|
||||||
add_xray_depends(o, { [option_name("transport")] = "quic" })
|
o:depends({ [option_name("transport")] = "quic" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "quic" })
|
|
||||||
|
|
||||||
-- [[ gRPC部分 ]]--
|
-- [[ gRPC部分 ]]--
|
||||||
o = s:option(Value, option_name("grpc_serviceName"), "ServiceName")
|
o = s:option(Value, option_name("grpc_serviceName"), "ServiceName")
|
||||||
add_xray_depends(o, { [option_name("transport")] = "grpc" })
|
o:depends({ [option_name("transport")] = "grpc" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "grpc" })
|
|
||||||
|
|
||||||
o = s:option(ListValue, option_name("grpc_mode"), "gRPC " .. translate("Transfer mode"))
|
o = s:option(ListValue, option_name("grpc_mode"), "gRPC " .. translate("Transfer mode"))
|
||||||
o:value("gun")
|
o:value("gun")
|
||||||
o:value("multi")
|
o:value("multi")
|
||||||
add_xray_depends(o, { [option_name("transport")] = "grpc" })
|
o:depends({ [option_name("transport")] = "grpc" })
|
||||||
|
|
||||||
o = s:option(Flag, option_name("grpc_health_check"), translate("Health check"))
|
o = s:option(Flag, option_name("grpc_health_check"), translate("Health check"))
|
||||||
add_xray_depends(o, { [option_name("transport")] = "grpc" })
|
o:depends({ [option_name("transport")] = "grpc" })
|
||||||
|
|
||||||
o = s:option(Value, option_name("grpc_idle_timeout"), translate("Idle timeout"))
|
o = s:option(Value, option_name("grpc_idle_timeout"), translate("Idle timeout"))
|
||||||
o.default = "10"
|
o.default = "10"
|
||||||
add_xray_depends(o, { [option_name("grpc_health_check")] = true })
|
o:depends({ [option_name("grpc_health_check")] = true })
|
||||||
|
|
||||||
o = s:option(Value, option_name("grpc_health_check_timeout"), translate("Health check timeout"))
|
o = s:option(Value, option_name("grpc_health_check_timeout"), translate("Health check timeout"))
|
||||||
o.default = "20"
|
o.default = "20"
|
||||||
add_xray_depends(o, { [option_name("grpc_health_check")] = true })
|
o:depends({ [option_name("grpc_health_check")] = true })
|
||||||
|
|
||||||
o = s:option(Flag, option_name("grpc_permit_without_stream"), translate("Permit without stream"))
|
o = s:option(Flag, option_name("grpc_permit_without_stream"), translate("Permit without stream"))
|
||||||
o.default = "0"
|
o.default = "0"
|
||||||
add_xray_depends(o, { [option_name("grpc_health_check")] = true })
|
o:depends({ [option_name("grpc_health_check")] = true })
|
||||||
|
|
||||||
o = s:option(Value, option_name("grpc_initial_windows_size"), translate("Initial Windows Size"))
|
o = s:option(Value, option_name("grpc_initial_windows_size"), translate("Initial Windows Size"))
|
||||||
o.default = "0"
|
o.default = "0"
|
||||||
add_xray_depends(o, { [option_name("transport")] = "grpc" })
|
o:depends({ [option_name("transport")] = "grpc" })
|
||||||
|
|
||||||
-- [[ Mux ]]--
|
-- [[ Mux ]]--
|
||||||
o = s:option(Flag, option_name("mux"), translate("Mux"))
|
o = s:option(Flag, option_name("mux"), translate("Mux"))
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vmess" })
|
o:depends({ [option_name("protocol")] = "vmess" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vless" })
|
o:depends({ [option_name("protocol")] = "vless", [option_name("flow")] = "" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "http" })
|
o:depends({ [option_name("protocol")] = "http" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "socks" })
|
o:depends({ [option_name("protocol")] = "socks" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "trojan" })
|
o:depends({ [option_name("protocol")] = "trojan" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vmess" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vless", [option_name("tlsflow")] = "" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "http" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "socks" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "trojan" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("mux_concurrency"), translate("Mux concurrency"))
|
o = s:option(Value, option_name("mux_concurrency"), translate("Mux concurrency"))
|
||||||
o.default = 8
|
o.default = 8
|
||||||
add_xray_depends(o, { [option_name("mux")] = true })
|
o:depends({ [option_name("mux")] = true })
|
||||||
add_v2ray_depends(o, { [option_name("mux")] = true })
|
|
||||||
|
|
||||||
-- [[ XUDP Mux ]]--
|
-- [[ XUDP Mux ]]--
|
||||||
o = s:option(Flag, option_name("xmux"), translate("xMux"))
|
o = s:option(Flag, option_name("xmux"), translate("xMux"))
|
||||||
o.default = 1
|
o.default = 1
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vless", [option_name("tlsflow")] = "xtls-rprx-vision" })
|
o:depends({ [option_name("protocol")] = "vless", [option_name("flow")] = "xtls-rprx-vision" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vless", [option_name("tlsflow")] = "xtls-rprx-vision-udp443" })
|
o:depends({ [option_name("protocol")] = "vless", [option_name("flow")] = "xtls-rprx-vision-udp443" })
|
||||||
|
|
||||||
o = s:option(Value, option_name("xudp_concurrency"), translate("XUDP Mux concurrency"))
|
o = s:option(Value, option_name("xudp_concurrency"), translate("XUDP Mux concurrency"))
|
||||||
o.default = 8
|
o.default = 8
|
||||||
add_xray_depends(o, { [option_name("xmux")] = true })
|
o:depends({ [option_name("xmux")] = true })
|
||||||
|
|
||||||
for key, value in pairs(s.fields) do
|
for key, value in pairs(s.fields) do
|
||||||
if key:find(option_prefix) == 1 then
|
if key:find(option_prefix) == 1 then
|
||||||
@ -715,5 +552,14 @@ for key, value in pairs(s.fields) do
|
|||||||
s.fields[key].write = rm_prefix_write
|
s.fields[key].write = rm_prefix_write
|
||||||
s.fields[key].remove = rm_prefix_remove
|
s.fields[key].remove = rm_prefix_remove
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local deps = s.fields[key].deps
|
||||||
|
if #deps > 0 then
|
||||||
|
for index, value in ipairs(deps) do
|
||||||
|
deps[index]["type"] = type_name
|
||||||
|
end
|
||||||
|
else
|
||||||
|
s.fields[key]:depends({ type = type_name })
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -0,0 +1,567 @@
|
|||||||
|
local m, s = ...
|
||||||
|
|
||||||
|
local api = require "luci.passwall2.api"
|
||||||
|
|
||||||
|
if not api.is_finded("sing-box") then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local singbox_tags = luci.sys.exec(api.finded("sing-box") .. " version | grep 'Tags:' | awk '{print $2}'")
|
||||||
|
|
||||||
|
local appname = api.appname
|
||||||
|
local uci = api.uci
|
||||||
|
|
||||||
|
local type_name = "sing-box"
|
||||||
|
|
||||||
|
local option_prefix = "singbox_"
|
||||||
|
|
||||||
|
local function option_name(name)
|
||||||
|
return option_prefix .. name
|
||||||
|
end
|
||||||
|
|
||||||
|
local function rm_prefix_cfgvalue(self, section)
|
||||||
|
if self.option:find(option_prefix) == 1 then
|
||||||
|
return m:get(section, self.option:sub(1 + #option_prefix))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local function rm_prefix_write(self, section, value)
|
||||||
|
if s.fields["type"]:formvalue(arg[1]) == type_name then
|
||||||
|
if self.option:find(option_prefix) == 1 then
|
||||||
|
m:set(section, self.option:sub(1 + #option_prefix), value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local function rm_prefix_remove(self, section, value)
|
||||||
|
if s.fields["type"]:formvalue(arg[1]) == type_name then
|
||||||
|
if self.option:find(option_prefix) == 1 then
|
||||||
|
m:del(section, self.option:sub(1 + #option_prefix))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local ss_method_new_list = {
|
||||||
|
"none", "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
||||||
|
}
|
||||||
|
|
||||||
|
local ss_method_old_list = {
|
||||||
|
"aes-128-ctr", "aes-192-ctr", "aes-256-ctr", "aes-128-cfb", "aes-192-cfb", "aes-256-cfb", "rc4-md5", "chacha20-ietf", "xchacha20",
|
||||||
|
}
|
||||||
|
|
||||||
|
local security_list = { "none", "auto", "aes-128-gcm", "chacha20-poly1305", "zero" }
|
||||||
|
|
||||||
|
-- [[ sing-box ]]
|
||||||
|
|
||||||
|
s.fields["type"]:value(type_name, translate("Sing-Box"))
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("protocol"), translate("Protocol"))
|
||||||
|
o:value("socks", "Socks")
|
||||||
|
o:value("http", "HTTP")
|
||||||
|
o:value("shadowsocks", "Shadowsocks")
|
||||||
|
if singbox_tags:find("with_shadowsocksr") then
|
||||||
|
o:value("shadowsocksr", "ShadowsocksR")
|
||||||
|
end
|
||||||
|
o:value("vmess", "Vmess")
|
||||||
|
o:value("trojan", "Trojan")
|
||||||
|
if singbox_tags:find("with_wireguard") then
|
||||||
|
o:value("wireguard", "WireGuard")
|
||||||
|
end
|
||||||
|
if singbox_tags:find("with_quic") then
|
||||||
|
o:value("hysteria", "Hysteria")
|
||||||
|
end
|
||||||
|
o:value("shadowtls", "ShadowTLS")
|
||||||
|
o:value("vless", "VLESS")
|
||||||
|
if singbox_tags:find("with_quic") then
|
||||||
|
o:value("tuic", "TUIC")
|
||||||
|
end
|
||||||
|
if singbox_tags:find("with_quic") then
|
||||||
|
o:value("hysteria2", "Hysteria2")
|
||||||
|
end
|
||||||
|
o:value("_shunt", translate("Shunt"))
|
||||||
|
o:value("_iface", translate("Custom Interface") .. " (Only Support Xray)")
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("iface"), translate("Interface"))
|
||||||
|
o.default = "eth1"
|
||||||
|
o:depends({ [option_name("protocol")] = "_iface" })
|
||||||
|
|
||||||
|
local nodes_table = {}
|
||||||
|
local balancers_table = {}
|
||||||
|
local iface_table = {}
|
||||||
|
for k, e in ipairs(api.get_valid_nodes()) do
|
||||||
|
if e.node_type == "normal" then
|
||||||
|
nodes_table[#nodes_table + 1] = {
|
||||||
|
id = e[".name"],
|
||||||
|
remarks = e["remark"]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
if e.protocol == "_iface" then
|
||||||
|
iface_table[#iface_table + 1] = {
|
||||||
|
id = e[".name"],
|
||||||
|
remarks = e["remark"]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- [[ 分流模块 ]]
|
||||||
|
if #nodes_table > 0 then
|
||||||
|
o = s:option(Flag, option_name("preproxy_enabled"), translate("Preproxy"))
|
||||||
|
o:depends({ [option_name("protocol")] = "_shunt" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("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:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true })
|
||||||
|
for k, v in pairs(balancers_table) do
|
||||||
|
o:value(v.id, v.remarks)
|
||||||
|
end
|
||||||
|
for k, v in pairs(iface_table) do
|
||||||
|
o:value(v.id, v.remarks)
|
||||||
|
end
|
||||||
|
for k, v in pairs(nodes_table) do
|
||||||
|
o:value(v.id, v.remarks)
|
||||||
|
end
|
||||||
|
o.default = "nil"
|
||||||
|
end
|
||||||
|
uci:foreach(appname, "shunt_rules", function(e)
|
||||||
|
if e[".name"] and e.remarks then
|
||||||
|
o = s:option(Value, option_name(e[".name"]), string.format('* <a href="%s" target="_blank">%s</a>', api.url("shunt_rules", e[".name"]), e.remarks))
|
||||||
|
o:value("nil", translate("Close"))
|
||||||
|
o:value("_default", translate("Default"))
|
||||||
|
o:value("_direct", translate("Direct Connection"))
|
||||||
|
o:value("_blackhole", translate("Blackhole"))
|
||||||
|
o:depends({ [option_name("protocol")] = "_shunt" })
|
||||||
|
|
||||||
|
if #nodes_table > 0 then
|
||||||
|
for k, v in pairs(balancers_table) do
|
||||||
|
o:value(v.id, v.remarks)
|
||||||
|
end
|
||||||
|
for k, v in pairs(iface_table) do
|
||||||
|
o:value(v.id, v.remarks)
|
||||||
|
end
|
||||||
|
local pt = s:option(ListValue, option_name(e[".name"] .. "_proxy_tag"), string.format('* <a style="color:red">%s</a>', e.remarks .. " " .. translate("Preproxy")))
|
||||||
|
pt:value("nil", translate("Close"))
|
||||||
|
pt:value("main", translate("Preproxy Node"))
|
||||||
|
pt.default = "nil"
|
||||||
|
for k, v in pairs(nodes_table) do
|
||||||
|
o:value(v.id, v.remarks)
|
||||||
|
pt:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true, [option_name(e[".name"])] = v.id })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
o = s:option(DummyValue, option_name("shunt_tips"), " ")
|
||||||
|
o.not_rewrite = true
|
||||||
|
o.rawhtml = true
|
||||||
|
o.cfgvalue = function(t, n)
|
||||||
|
return string.format('<a style="color: red" href="../rule">%s</a>', translate("No shunt rules? Click me to go to add."))
|
||||||
|
end
|
||||||
|
o:depends({ [option_name("protocol")] = "_shunt" })
|
||||||
|
|
||||||
|
local o = s:option(Value, option_name("default_node"), string.format('* <a style="color:red">%s</a>', translate("Default")))
|
||||||
|
o:depends({ [option_name("protocol")] = "_shunt" })
|
||||||
|
o:value("_direct", translate("Direct Connection"))
|
||||||
|
o:value("_blackhole", translate("Blackhole"))
|
||||||
|
|
||||||
|
if #nodes_table > 0 then
|
||||||
|
for k, v in pairs(balancers_table) do
|
||||||
|
o:value(v.id, v.remarks)
|
||||||
|
end
|
||||||
|
for k, v in pairs(iface_table) do
|
||||||
|
o:value(v.id, v.remarks)
|
||||||
|
end
|
||||||
|
local dpt = s:option(ListValue, option_name("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."))
|
||||||
|
dpt:value("nil", translate("Close"))
|
||||||
|
dpt:value("main", translate("Preproxy Node"))
|
||||||
|
dpt.default = "nil"
|
||||||
|
for k, v in pairs(nodes_table) do
|
||||||
|
o:value(v.id, v.remarks)
|
||||||
|
dpt:depends({ [option_name("protocol")] = "_shunt", [option_name("preproxy_enabled")] = true, [option_name("default_node")] = v.id })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- [[ 分流模块 End ]]
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("address"), translate("Address (Support Domain Name)"))
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("port"), translate("Port"))
|
||||||
|
o.datatype = "port"
|
||||||
|
|
||||||
|
local protocols = s.fields[option_name("protocol")].keylist
|
||||||
|
if #protocols > 0 then
|
||||||
|
for index, value in ipairs(protocols) do
|
||||||
|
if not value:find("_") then
|
||||||
|
s.fields[option_name("address")]:depends({ [option_name("protocol")] = value })
|
||||||
|
s.fields[option_name("port")]:depends({ [option_name("protocol")] = value })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("shadowtls_version"), translate("Version"))
|
||||||
|
o.default = "1"
|
||||||
|
o:value("1", "ShadowTLS v1")
|
||||||
|
o:value("2", "ShadowTLS v2")
|
||||||
|
o:value("3", "ShadowTLS v3")
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowtls" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("username"), translate("Username"))
|
||||||
|
o:depends({ [option_name("protocol")] = "http" })
|
||||||
|
o:depends({ [option_name("protocol")] = "socks" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("password"), translate("Password"))
|
||||||
|
o.password = true
|
||||||
|
o:depends({ [option_name("protocol")] = "http" })
|
||||||
|
o:depends({ [option_name("protocol")] = "socks" })
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowsocksr" })
|
||||||
|
o:depends({ [option_name("protocol")] = "trojan" })
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowtls", [option_name("shadowtls_version")] = "2" })
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowtls", [option_name("shadowtls_version")] = "3" })
|
||||||
|
o:depends({ [option_name("protocol")] = "tuic" })
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("security"), translate("Encrypt Method"))
|
||||||
|
for a, t in ipairs(security_list) do o:value(t) end
|
||||||
|
o:depends({ [option_name("protocol")] = "vmess" })
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("ss_method"), translate("Encrypt Method"))
|
||||||
|
o.not_rewrite = true
|
||||||
|
for a, t in ipairs(ss_method_new_list) do o:value(t) end
|
||||||
|
for a, t in ipairs(ss_method_old_list) do o:value(t) end
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
|
function o.cfgvalue(self, section)
|
||||||
|
return m:get(section, "method")
|
||||||
|
end
|
||||||
|
function o.write(self, section, value)
|
||||||
|
if s.fields["type"]:formvalue(arg[1]) == type_name then
|
||||||
|
m:set(section, "method", value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if singbox_tags:find("with_shadowsocksr") then
|
||||||
|
o = s:option(ListValue, option_name("ssr_method"), translate("Encrypt Method"))
|
||||||
|
o.not_rewrite = true
|
||||||
|
for a, t in ipairs(ss_method_old_list) do o:value(t) end
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowsocksr" })
|
||||||
|
function o.cfgvalue(self, section)
|
||||||
|
return m:get(section, "method")
|
||||||
|
end
|
||||||
|
function o.write(self, section, value)
|
||||||
|
if s.fields["type"]:formvalue(arg[1]) == type_name then
|
||||||
|
m:set(section, "method", value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local ssr_protocol_list = {
|
||||||
|
"origin", "verify_simple", "verify_deflate", "verify_sha1", "auth_simple",
|
||||||
|
"auth_sha1", "auth_sha1_v2", "auth_sha1_v4", "auth_aes128_md5",
|
||||||
|
"auth_aes128_sha1", "auth_chain_a", "auth_chain_b", "auth_chain_c",
|
||||||
|
"auth_chain_d", "auth_chain_e", "auth_chain_f"
|
||||||
|
}
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("ssr_protocol"), translate("Protocol"))
|
||||||
|
for a, t in ipairs(ssr_protocol_list) do o:value(t) end
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowsocksr" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("ssr_protocol_param"), translate("Protocol_param"))
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowsocksr" })
|
||||||
|
|
||||||
|
local ssr_obfs_list = {
|
||||||
|
"plain", "http_simple", "http_post", "random_head", "tls_simple",
|
||||||
|
"tls1.0_session_auth", "tls1.2_ticket_auth"
|
||||||
|
}
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("ssr_obfs"), translate("Obfs"))
|
||||||
|
for a, t in ipairs(ssr_obfs_list) do o:value(t) end
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowsocksr" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("ssr_obfs_param"), translate("Obfs_param"))
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowsocksr" })
|
||||||
|
end
|
||||||
|
|
||||||
|
o = s:option(Flag, option_name("uot"), translate("UDP over TCP"), translate("Need Xray-core or sing-box as server side."))
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("ss_method")] = "2022-blake3-aes-128-gcm" })
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("ss_method")] = "2022-blake3-aes-256-gcm" })
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowsocks", [option_name("ss_method")] = "2022-blake3-chacha20-poly1305" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("uuid"), translate("ID"))
|
||||||
|
o.password = true
|
||||||
|
o:depends({ [option_name("protocol")] = "vmess" })
|
||||||
|
o:depends({ [option_name("protocol")] = "vless" })
|
||||||
|
o:depends({ [option_name("protocol")] = "tuic" })
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("flow"), translate("flow"))
|
||||||
|
o.default = ""
|
||||||
|
o:value("", translate("Disable"))
|
||||||
|
o:value("xtls-rprx-vision")
|
||||||
|
o:depends({ [option_name("protocol")] = "vless", [option_name("tls")] = true })
|
||||||
|
|
||||||
|
if singbox_tags:find("with_quic") then
|
||||||
|
o = s:option(Value, option_name("hysteria_obfs"), translate("Obfs Password"))
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria" })
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("hysteria_auth_type"), translate("Auth Type"))
|
||||||
|
o:value("disable", translate("Disable"))
|
||||||
|
o:value("string", translate("STRING"))
|
||||||
|
o:value("base64", translate("BASE64"))
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("hysteria_auth_password"), translate("Auth Password"))
|
||||||
|
o.password = true
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria", [option_name("hysteria_auth_type")] = "string"})
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria", [option_name("hysteria_auth_type")] = "base64"})
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("hysteria_up_mbps"), translate("Max upload Mbps"))
|
||||||
|
o.default = "10"
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("hysteria_down_mbps"), translate("Max download Mbps"))
|
||||||
|
o.default = "50"
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("hysteria_recv_window_conn"), translate("QUIC stream receive window"))
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("hysteria_recv_window"), translate("QUIC connection receive window"))
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria" })
|
||||||
|
|
||||||
|
o = s:option(Flag, option_name("hysteria_disable_mtu_discovery"), translate("Disable MTU detection"))
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria" })
|
||||||
|
end
|
||||||
|
|
||||||
|
if singbox_tags:find("with_quic") then
|
||||||
|
o = s:option(ListValue, option_name("tuic_congestion_control"), translate("Congestion control algorithm"))
|
||||||
|
o.default = "cubic"
|
||||||
|
o:value("bbr", translate("BBR"))
|
||||||
|
o:value("cubic", translate("CUBIC"))
|
||||||
|
o:value("new_reno", translate("New Reno"))
|
||||||
|
o:depends({ [option_name("protocol")] = "tuic" })
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("tuic_udp_relay_mode"), translate("UDP relay mode"))
|
||||||
|
o.default = "native"
|
||||||
|
o:value("native", translate("native"))
|
||||||
|
o:value("quic", translate("QUIC"))
|
||||||
|
o:depends({ [option_name("protocol")] = "tuic" })
|
||||||
|
|
||||||
|
--[[
|
||||||
|
o = s:option(Flag, option_name("tuic_udp_over_stream"), translate("UDP over stream"))
|
||||||
|
o:depends({ [option_name("protocol")] = "tuic" })
|
||||||
|
]]--
|
||||||
|
|
||||||
|
o = s:option(Flag, option_name("tuic_zero_rtt_handshake"), translate("Enable 0-RTT QUIC handshake"))
|
||||||
|
o.default = 0
|
||||||
|
o:depends({ [option_name("protocol")] = "tuic" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("tuic_heartbeat"), translate("Heartbeat interval(second)"))
|
||||||
|
o.datatype = "uinteger"
|
||||||
|
o.default = "3"
|
||||||
|
o:depends({ [option_name("protocol")] = "tuic" })
|
||||||
|
end
|
||||||
|
|
||||||
|
if singbox_tags:find("with_quic") then
|
||||||
|
o = s:option(Value, option_name("hysteria2_up_mbps"), translate("Max upload Mbps"))
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria2" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("hysteria2_down_mbps"), translate("Max download Mbps"))
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria2" })
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("hysteria2_obfs_type"), translate("Obfs Type"))
|
||||||
|
o:value("", translate("Disable"))
|
||||||
|
o:value("salamander")
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria2" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("hysteria2_obfs_password"), translate("Obfs Password"))
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria2" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("hysteria2_auth_password"), translate("Auth Password"))
|
||||||
|
o.password = true
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria2"})
|
||||||
|
end
|
||||||
|
|
||||||
|
o = s:option(Flag, option_name("tls"), translate("TLS"))
|
||||||
|
o.default = 0
|
||||||
|
o:depends({ [option_name("protocol")] = "vmess" })
|
||||||
|
o:depends({ [option_name("protocol")] = "vless" })
|
||||||
|
o:depends({ [option_name("protocol")] = "socks" })
|
||||||
|
o:depends({ [option_name("protocol")] = "trojan" })
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowtls" })
|
||||||
|
|
||||||
|
if singbox_tags:find("with_reality") then
|
||||||
|
o = s:option(Flag, option_name("reality"), translate("REALITY"))
|
||||||
|
o.default = 0
|
||||||
|
o:depends({ [option_name("protocol")] = "vless", [option_name("tls")] = true })
|
||||||
|
|
||||||
|
-- [[ REALITY部分 ]] --
|
||||||
|
o = s:option(Value, option_name("reality_publicKey"), translate("Public Key"))
|
||||||
|
o:depends({ [option_name("tls")] = true, [option_name("reality")] = true })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("reality_shortId"), translate("Short Id"))
|
||||||
|
o:depends({ [option_name("tls")] = true, [option_name("reality")] = true })
|
||||||
|
end
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("alpn"), translate("alpn"))
|
||||||
|
o.default = "default"
|
||||||
|
o:value("default", translate("Default"))
|
||||||
|
o:value("h2,http/1.1")
|
||||||
|
o:value("h2")
|
||||||
|
o:value("http/1.1")
|
||||||
|
o:depends({ [option_name("tls")] = true })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("tls_serverName"), translate("Domain"))
|
||||||
|
o:depends({ [option_name("tls")] = true })
|
||||||
|
|
||||||
|
o = s:option(Flag, option_name("tls_allowInsecure"), translate("allowInsecure"), translate("Whether unsafe connections are allowed. When checked, Certificate validation will be skipped."))
|
||||||
|
o.default = "0"
|
||||||
|
o:depends({ [option_name("tls")] = true })
|
||||||
|
|
||||||
|
if singbox_tags:find("with_utls") then
|
||||||
|
o = s:option(Flag, option_name("utls"), translate("uTLS"))
|
||||||
|
o.default = "0"
|
||||||
|
o:depends({ [option_name("tls")] = true, [option_name("reality")] = false })
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("fingerprint"), translate("Finger Print"))
|
||||||
|
o:value("chrome")
|
||||||
|
o:value("firefox")
|
||||||
|
o:value("edge")
|
||||||
|
o:value("safari")
|
||||||
|
o:value("360")
|
||||||
|
o:value("qq")
|
||||||
|
o:value("ios")
|
||||||
|
o:value("android")
|
||||||
|
o:value("random")
|
||||||
|
o:value("randomized")
|
||||||
|
o.default = "chrome"
|
||||||
|
o:depends({ [option_name("tls")] = true, [option_name("utls")] = true })
|
||||||
|
o:depends({ [option_name("tls")] = true, [option_name("reality")] = true })
|
||||||
|
end
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("transport"), translate("Transport"))
|
||||||
|
o:value("tcp", "TCP")
|
||||||
|
o:value("http", "HTTP")
|
||||||
|
o:value("ws", "WebSocket")
|
||||||
|
if singbox_tags:find("with_quic") then
|
||||||
|
o:value("quic", "QUIC")
|
||||||
|
end
|
||||||
|
if singbox_tags:find("with_grpc") then
|
||||||
|
o:value("grpc", "gRPC")
|
||||||
|
end
|
||||||
|
o:depends({ [option_name("protocol")] = "vmess" })
|
||||||
|
o:depends({ [option_name("protocol")] = "vless" })
|
||||||
|
o:depends({ [option_name("protocol")] = "socks" })
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
|
o:depends({ [option_name("protocol")] = "trojan" })
|
||||||
|
|
||||||
|
if singbox_tags:find("with_wireguard") then
|
||||||
|
o = s:option(Value, option_name("wireguard_public_key"), translate("Public Key"))
|
||||||
|
o:depends({ [option_name("protocol")] = "wireguard" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("wireguard_secret_key"), translate("Private Key"))
|
||||||
|
o:depends({ [option_name("protocol")] = "wireguard" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("wireguard_preSharedKey"), translate("Pre shared key"))
|
||||||
|
o:depends({ [option_name("protocol")] = "wireguard" })
|
||||||
|
|
||||||
|
o = s:option(DynamicList, option_name("wireguard_local_address"), translate("Local Address"))
|
||||||
|
o:depends({ [option_name("protocol")] = "wireguard" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("wireguard_mtu"), translate("MTU"))
|
||||||
|
o.default = "1420"
|
||||||
|
o:depends({ [option_name("protocol")] = "wireguard" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("wireguard_reserved"), translate("Reserved"), translate("Decimal numbers separated by \",\" or Base64-encoded strings."))
|
||||||
|
o:depends({ [option_name("protocol")] = "wireguard" })
|
||||||
|
end
|
||||||
|
|
||||||
|
-- [[ HTTP部分 ]]--
|
||||||
|
o = s:option(Value, option_name("http_host"), translate("HTTP Host"))
|
||||||
|
o:depends({ [option_name("transport")] = "http" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("http_path"), translate("HTTP Path"))
|
||||||
|
o.placeholder = "/"
|
||||||
|
o:depends({ [option_name("transport")] = "http" })
|
||||||
|
|
||||||
|
o = s:option(Flag, option_name("http_h2_health_check"), translate("Health check"))
|
||||||
|
o:depends({ [option_name("tls")] = true, [option_name("transport")] = "http" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("http_h2_read_idle_timeout"), translate("Idle timeout"))
|
||||||
|
o.default = "10"
|
||||||
|
o:depends({ [option_name("tls")] = true, [option_name("transport")] = "http", [option_name("http_h2_health_check")] = true })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("http_h2_health_check_timeout"), translate("Health check timeout"))
|
||||||
|
o.default = "15"
|
||||||
|
o:depends({ [option_name("tls")] = true, [option_name("transport")] = "http", [option_name("http_h2_health_check")] = true })
|
||||||
|
|
||||||
|
-- [[ WebSocket部分 ]]--
|
||||||
|
o = s:option(Value, option_name("ws_host"), translate("WebSocket Host"))
|
||||||
|
o:depends({ [option_name("transport")] = "ws" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("ws_path"), translate("WebSocket Path"))
|
||||||
|
o.placeholder = "/"
|
||||||
|
o:depends({ [option_name("transport")] = "ws" })
|
||||||
|
|
||||||
|
o = s:option(Flag, option_name("ws_enableEarlyData"), translate("Enable early data"))
|
||||||
|
o:depends({ [option_name("transport")] = "ws" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("ws_maxEarlyData"), translate("Early data length"))
|
||||||
|
o.default = "1024"
|
||||||
|
o:depends({ [option_name("ws_enableEarlyData")] = true })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("ws_earlyDataHeaderName"), translate("Early data header name"), translate("Recommended value: Sec-WebSocket-Protocol"))
|
||||||
|
o:depends({ [option_name("ws_enableEarlyData")] = true })
|
||||||
|
|
||||||
|
-- [[ gRPC部分 ]]--
|
||||||
|
if singbox_tags:find("with_grpc") then
|
||||||
|
o = s:option(Value, option_name("grpc_serviceName"), "ServiceName")
|
||||||
|
o:depends({ [option_name("transport")] = "grpc" })
|
||||||
|
|
||||||
|
o = s:option(Flag, option_name("grpc_health_check"), translate("Health check"))
|
||||||
|
o:depends({ [option_name("transport")] = "grpc" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("grpc_idle_timeout"), translate("Idle timeout"))
|
||||||
|
o.default = "10"
|
||||||
|
o:depends({ [option_name("grpc_health_check")] = true })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("grpc_health_check_timeout"), translate("Health check timeout"))
|
||||||
|
o.default = "20"
|
||||||
|
o:depends({ [option_name("grpc_health_check")] = true })
|
||||||
|
|
||||||
|
o = s:option(Flag, option_name("grpc_permit_without_stream"), translate("Permit without stream"))
|
||||||
|
o.default = "0"
|
||||||
|
o:depends({ [option_name("grpc_health_check")] = true })
|
||||||
|
end
|
||||||
|
|
||||||
|
-- [[ Mux ]]--
|
||||||
|
o = s:option(Flag, option_name("mux"), translate("Mux"))
|
||||||
|
o.rmempty = false
|
||||||
|
o:depends({ [option_name("protocol")] = "vmess" })
|
||||||
|
o:depends({ [option_name("protocol")] = "vless", [option_name("flow")] = "" })
|
||||||
|
o:depends({ [option_name("protocol")] = "http" })
|
||||||
|
o:depends({ [option_name("protocol")] = "socks" })
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
|
o:depends({ [option_name("protocol")] = "trojan" })
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("mux_type"), translate("Mux"))
|
||||||
|
o:value("smux")
|
||||||
|
o:value("yamux")
|
||||||
|
o:value("h2mux")
|
||||||
|
o:depends({ [option_name("mux")] = true })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("mux_concurrency"), translate("Mux concurrency"))
|
||||||
|
o.default = 8
|
||||||
|
o:depends({ [option_name("mux")] = true })
|
||||||
|
|
||||||
|
for key, value in pairs(s.fields) do
|
||||||
|
if key:find(option_prefix) == 1 then
|
||||||
|
if not s.fields[key].not_rewrite then
|
||||||
|
s.fields[key].cfgvalue = rm_prefix_cfgvalue
|
||||||
|
s.fields[key].write = rm_prefix_write
|
||||||
|
s.fields[key].remove = rm_prefix_remove
|
||||||
|
end
|
||||||
|
|
||||||
|
local deps = s.fields[key].deps
|
||||||
|
if #deps > 0 then
|
||||||
|
for index, value in ipairs(deps) do
|
||||||
|
deps[index]["type"] = type_name
|
||||||
|
end
|
||||||
|
else
|
||||||
|
s.fields[key]:depends({ type = type_name })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -45,15 +45,8 @@ e = t:option(DummyValue, "type", translate("Type"))
|
|||||||
e.cfgvalue = function(t, n)
|
e.cfgvalue = function(t, n)
|
||||||
local v = Value.cfgvalue(t, n)
|
local v = Value.cfgvalue(t, n)
|
||||||
if v then
|
if v then
|
||||||
if v == "V2ray" or v == "Xray" then
|
if v == "sing-box" or v == "Xray" then
|
||||||
local protocol = m:get(n, "protocol")
|
local protocol = m:get(n, "protocol")
|
||||||
if protocol == "vmess" then
|
|
||||||
protocol = "VMess"
|
|
||||||
elseif protocol == "vless" then
|
|
||||||
protocol = "VLESS"
|
|
||||||
else
|
|
||||||
protocol = protocol:gsub("^%l",string.upper)
|
|
||||||
end
|
|
||||||
return v .. " -> " .. protocol
|
return v .. " -> " .. protocol
|
||||||
end
|
end
|
||||||
return v
|
return v
|
||||||
|
@ -2,10 +2,12 @@ local m, s = ...
|
|||||||
|
|
||||||
local api = require "luci.passwall2.api"
|
local api = require "luci.passwall2.api"
|
||||||
|
|
||||||
if not api.is_finded("xray") and not api.is_finded("v2ray")then
|
if not api.is_finded("xray") then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local type_name = "Xray"
|
||||||
|
|
||||||
local option_prefix = "xray_"
|
local option_prefix = "xray_"
|
||||||
|
|
||||||
local function option_name(name)
|
local function option_name(name)
|
||||||
@ -18,52 +20,20 @@ local function rm_prefix_cfgvalue(self, section)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
local function rm_prefix_write(self, section, value)
|
local function rm_prefix_write(self, section, value)
|
||||||
if s.fields["type"]:formvalue(arg[1]) == "Xray" or s.fields["type"]:formvalue(arg[1]) == "V2ray" then
|
if s.fields["type"]:formvalue(arg[1]) == type_name then
|
||||||
if self.option:find(option_prefix) == 1 then
|
if self.option:find(option_prefix) == 1 then
|
||||||
m:set(section, self.option:sub(1 + #option_prefix), value)
|
m:set(section, self.option:sub(1 + #option_prefix), value)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local function rm_prefix_remove(self, section, value)
|
local function rm_prefix_remove(self, section, value)
|
||||||
if s.fields["type"]:formvalue(arg[1]) == "Xray" or s.fields["type"]:formvalue(arg[1]) == "V2ray" then
|
if s.fields["type"]:formvalue(arg[1]) == type_name then
|
||||||
if self.option:find(option_prefix) == 1 then
|
if self.option:find(option_prefix) == 1 then
|
||||||
m:del(section, self.option:sub(1 + #option_prefix))
|
m:del(section, self.option:sub(1 + #option_prefix))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function add_xray_depends(o, field, value)
|
|
||||||
local deps = { type = "Xray" }
|
|
||||||
if field then
|
|
||||||
if type(field) == "string" then
|
|
||||||
deps[field] = value
|
|
||||||
else
|
|
||||||
for key, value in pairs(field) do
|
|
||||||
deps[key] = value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
o:depends(deps)
|
|
||||||
end
|
|
||||||
|
|
||||||
local function add_v2ray_depends(o, field, value)
|
|
||||||
local deps = { type = "V2ray" }
|
|
||||||
if field then
|
|
||||||
if type(field) == "string" then
|
|
||||||
deps[field] = value
|
|
||||||
else
|
|
||||||
for key, value in pairs(field) do
|
|
||||||
deps[key] = value
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
o:depends(deps)
|
|
||||||
end
|
|
||||||
|
|
||||||
local v_ss_method_list = {
|
|
||||||
"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305"
|
|
||||||
}
|
|
||||||
|
|
||||||
local x_ss_method_list = {
|
local x_ss_method_list = {
|
||||||
"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "xchacha20-poly1305", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "xchacha20-poly1305", "2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
||||||
}
|
}
|
||||||
@ -74,12 +44,7 @@ local header_type_list = {
|
|||||||
|
|
||||||
-- [[ Xray ]]
|
-- [[ Xray ]]
|
||||||
|
|
||||||
if api.is_finded("v2ray") then
|
s.fields["type"]:value(type_name, "Xray")
|
||||||
s.fields["type"]:value("V2ray", translate("V2ray"))
|
|
||||||
end
|
|
||||||
if api.is_finded("xray") then
|
|
||||||
s.fields["type"]:value("Xray", translate("Xray"))
|
|
||||||
end
|
|
||||||
|
|
||||||
o = s:option(ListValue, option_name("protocol"), translate("Protocol"))
|
o = s:option(ListValue, option_name("protocol"), translate("Protocol"))
|
||||||
o:value("vmess", "Vmess")
|
o:value("vmess", "Vmess")
|
||||||
@ -89,13 +54,9 @@ o:value("socks", "Socks")
|
|||||||
o:value("shadowsocks", "Shadowsocks")
|
o:value("shadowsocks", "Shadowsocks")
|
||||||
o:value("trojan", "Trojan")
|
o:value("trojan", "Trojan")
|
||||||
o:value("dokodemo-door", "dokodemo-door")
|
o:value("dokodemo-door", "dokodemo-door")
|
||||||
add_xray_depends(o)
|
|
||||||
add_v2ray_depends(o)
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("port"), translate("Listen Port"))
|
o = s:option(Value, option_name("port"), translate("Listen Port"))
|
||||||
o.datatype = "port"
|
o.datatype = "port"
|
||||||
add_xray_depends(o)
|
|
||||||
add_v2ray_depends(o)
|
|
||||||
|
|
||||||
o = s:option(Flag, option_name("auth"), translate("Auth"))
|
o = s:option(Flag, option_name("auth"), translate("Auth"))
|
||||||
o.validate = function(self, value, t)
|
o.validate = function(self, value, t)
|
||||||
@ -108,60 +69,38 @@ o.validate = function(self, value, t)
|
|||||||
end
|
end
|
||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "socks" })
|
o:depends({ [option_name("protocol")] = "socks" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "http" })
|
o:depends({ [option_name("protocol")] = "http" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "socks" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "http" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("username"), translate("Username"))
|
o = s:option(Value, option_name("username"), translate("Username"))
|
||||||
add_xray_depends(o, { [option_name("auth")] = true })
|
o:depends({ [option_name("auth")] = true })
|
||||||
add_v2ray_depends(o, { [option_name("auth")] = true })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("password"), translate("Password"))
|
o = s:option(Value, option_name("password"), translate("Password"))
|
||||||
o.password = true
|
o.password = true
|
||||||
add_xray_depends(o, { [option_name("auth")] = true })
|
o:depends({ [option_name("auth")] = true })
|
||||||
add_v2ray_depends(o, { [option_name("auth")] = true })
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
|
||||||
|
|
||||||
o = s:option(ListValue, option_name("d_protocol"), translate("Destination protocol"))
|
o = s:option(ListValue, option_name("d_protocol"), translate("Destination protocol"))
|
||||||
o:value("tcp", "TCP")
|
o:value("tcp", "TCP")
|
||||||
o:value("udp", "UDP")
|
o:value("udp", "UDP")
|
||||||
o:value("tcp,udp", "TCP,UDP")
|
o:value("tcp,udp", "TCP,UDP")
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "dokodemo-door" })
|
o:depends({ [option_name("protocol")] = "dokodemo-door" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "dokodemo-door" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("d_address"), translate("Destination address"))
|
o = s:option(Value, option_name("d_address"), translate("Destination address"))
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "dokodemo-door" })
|
o:depends({ [option_name("protocol")] = "dokodemo-door" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "dokodemo-door" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("d_port"), translate("Destination port"))
|
o = s:option(Value, option_name("d_port"), translate("Destination port"))
|
||||||
o.datatype = "port"
|
o.datatype = "port"
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "dokodemo-door" })
|
o:depends({ [option_name("protocol")] = "dokodemo-door" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "dokodemo-door" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("decryption"), translate("Encrypt Method"))
|
o = s:option(Value, option_name("decryption"), translate("Encrypt Method"))
|
||||||
o.default = "none"
|
o.default = "none"
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vless" })
|
o:depends({ [option_name("protocol")] = "vless" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vless" })
|
|
||||||
|
|
||||||
o = s:option(ListValue, option_name("v_ss_method"), translate("Encrypt Method"))
|
|
||||||
o.not_rewrite = true
|
|
||||||
for a, t in ipairs(v_ss_method_list) do o:value(t) end
|
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
|
||||||
function o.cfgvalue(self, section)
|
|
||||||
return m:get(section, "method")
|
|
||||||
end
|
|
||||||
function o.write(self, section, value)
|
|
||||||
if s.fields["type"]:formvalue(arg[1]) == "V2ray" then
|
|
||||||
m:set(section, "method", value)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
o = s:option(ListValue, option_name("x_ss_method"), translate("Encrypt Method"))
|
o = s:option(ListValue, option_name("x_ss_method"), translate("Encrypt Method"))
|
||||||
o.not_rewrite = true
|
o.not_rewrite = true
|
||||||
for a, t in ipairs(x_ss_method_list) do o:value(t) end
|
for a, t in ipairs(x_ss_method_list) do o:value(t) end
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
function o.cfgvalue(self, section)
|
function o.cfgvalue(self, section)
|
||||||
return m:get(section, "method")
|
return m:get(section, "method")
|
||||||
end
|
end
|
||||||
@ -172,33 +111,33 @@ function o.write(self, section, value)
|
|||||||
end
|
end
|
||||||
|
|
||||||
o = s:option(Flag, option_name("iv_check"), translate("IV Check"))
|
o = s:option(Flag, option_name("iv_check"), translate("IV Check"))
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
|
||||||
|
|
||||||
o = s:option(ListValue, option_name("ss_network"), translate("Transport"))
|
o = s:option(ListValue, option_name("ss_network"), translate("Transport"))
|
||||||
o.default = "tcp,udp"
|
o.default = "tcp,udp"
|
||||||
o:value("tcp", "TCP")
|
o:value("tcp", "TCP")
|
||||||
o:value("udp", "UDP")
|
o:value("udp", "UDP")
|
||||||
o:value("tcp,udp", "TCP,UDP")
|
o:value("tcp,udp", "TCP,UDP")
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
|
||||||
|
|
||||||
o = s:option(Flag, option_name("udp_forward"), translate("UDP Forward"))
|
o = s:option(Flag, option_name("udp_forward"), translate("UDP Forward"))
|
||||||
o.default = "1"
|
o.default = "1"
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "socks" })
|
o:depends({ [option_name("protocol")] = "socks" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "socks" })
|
|
||||||
|
|
||||||
o = s:option(DynamicList, option_name("uuid"), translate("ID") .. "/" .. translate("Password"))
|
o = s:option(DynamicList, option_name("uuid"), translate("ID") .. "/" .. translate("Password"))
|
||||||
for i = 1, 3 do
|
for i = 1, 3 do
|
||||||
o:value(api.gen_uuid(1))
|
o:value(api.gen_uuid(1))
|
||||||
end
|
end
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vmess" })
|
o:depends({ [option_name("protocol")] = "vmess" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vless" })
|
o:depends({ [option_name("protocol")] = "vless" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "trojan" })
|
o:depends({ [option_name("protocol")] = "trojan" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vmess" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vless" })
|
o = s:option(ListValue, option_name("flow"), translate("flow"))
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "trojan" })
|
o.default = ""
|
||||||
|
o:value("", translate("Disable"))
|
||||||
|
o:value("xtls-rprx-vision")
|
||||||
|
o:depends({ [option_name("protocol")] = "vless" })
|
||||||
|
|
||||||
o = s:option(Flag, option_name("tls"), translate("TLS"))
|
o = s:option(Flag, option_name("tls"), translate("TLS"))
|
||||||
o.default = 0
|
o.default = 0
|
||||||
@ -214,44 +153,29 @@ o.validate = function(self, value, t)
|
|||||||
return value
|
return value
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vmess" })
|
o:depends({ [option_name("protocol")] = "vmess" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vless" })
|
o:depends({ [option_name("protocol")] = "vless" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "socks" })
|
o:depends({ [option_name("protocol")] = "socks" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "trojan" })
|
o:depends({ [option_name("protocol")] = "trojan" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vmess" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vless" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "socks" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "trojan" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("tlsflow"), translate("flow"))
|
|
||||||
o.default = ""
|
|
||||||
o:value("", translate("Disable"))
|
|
||||||
o:value("xtls-rprx-vision")
|
|
||||||
o:value("xtls-rprx-vision-udp443")
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vless", [option_name("tls")] = true })
|
|
||||||
|
|
||||||
o = s:option(ListValue, option_name("alpn"), translate("alpn"))
|
o = s:option(ListValue, option_name("alpn"), translate("alpn"))
|
||||||
o.default = "h2,http/1.1"
|
o.default = "h2,http/1.1"
|
||||||
o:value("h2,http/1.1")
|
o:value("h2,http/1.1")
|
||||||
o:value("h2")
|
o:value("h2")
|
||||||
o:value("http/1.1")
|
o:value("http/1.1")
|
||||||
add_v2ray_depends(o, { [option_name("tls")] = true })
|
o:depends({ [option_name("tls")] = true })
|
||||||
add_xray_depends(o, { [option_name("tls")] = true })
|
|
||||||
|
|
||||||
-- o = s:option(Value, option_name("minversion"), translate("minversion"))
|
-- o = s:option(Value, option_name("minversion"), translate("minversion"))
|
||||||
-- o.default = "1.3"
|
-- o.default = "1.3"
|
||||||
-- o:value("1.3")
|
-- o:value("1.3")
|
||||||
--add_v2ray_depends(o, { [option_name("tls")] = true })
|
--o:depends({ [option_name("tls")] = true })
|
||||||
--add_xray_depends(o, { [option_name("tls")] = true })
|
|
||||||
|
|
||||||
-- [[ TLS部分 ]] --
|
-- [[ TLS部分 ]] --
|
||||||
|
|
||||||
o = s:option(FileUpload, option_name("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem")
|
o = s:option(FileUpload, option_name("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"
|
o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem"
|
||||||
add_v2ray_depends(o, { [option_name("tls")] = true })
|
o:depends({ [option_name("tls")] = true })
|
||||||
add_xray_depends(o, { [option_name("tls")] = true })
|
|
||||||
o.validate = function(self, value, t)
|
o.validate = function(self, value, t)
|
||||||
if value and value ~= "" then
|
if value and value ~= "" then
|
||||||
if not nixio.fs.access(value) then
|
if not nixio.fs.access(value) then
|
||||||
@ -265,8 +189,7 @@ end
|
|||||||
|
|
||||||
o = s:option(FileUpload, option_name("tls_keyFile"), translate("Private key absolute path"), translate("as:") .. "/etc/ssl/private.key")
|
o = s:option(FileUpload, option_name("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"
|
o.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key"
|
||||||
add_v2ray_depends(o, { [option_name("tls")] = true })
|
o:depends({ [option_name("tls")] = true })
|
||||||
add_xray_depends(o, { [option_name("tls")] = true })
|
|
||||||
o.validate = function(self, value, t)
|
o.validate = function(self, value, t)
|
||||||
if value and value ~= "" then
|
if value and value ~= "" then
|
||||||
if not nixio.fs.access(value) then
|
if not nixio.fs.access(value) then
|
||||||
@ -286,36 +209,27 @@ o:value("h2", "HTTP/2")
|
|||||||
o:value("ds", "DomainSocket")
|
o:value("ds", "DomainSocket")
|
||||||
o:value("quic", "QUIC")
|
o:value("quic", "QUIC")
|
||||||
o:value("grpc", "gRPC")
|
o:value("grpc", "gRPC")
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vmess" })
|
o:depends({ [option_name("protocol")] = "vmess" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vless" })
|
o:depends({ [option_name("protocol")] = "vless" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "socks" })
|
o:depends({ [option_name("protocol")] = "socks" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "trojan" })
|
o:depends({ [option_name("protocol")] = "trojan" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vmess" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vless" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "socks" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "trojan" })
|
|
||||||
|
|
||||||
-- [[ WebSocket部分 ]]--
|
-- [[ WebSocket部分 ]]--
|
||||||
|
|
||||||
o = s:option(Value, option_name("ws_host"), translate("WebSocket Host"))
|
o = s:option(Value, option_name("ws_host"), translate("WebSocket Host"))
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "ws" })
|
o:depends({ [option_name("transport")] = "ws" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "ws" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("ws_path"), translate("WebSocket Path"))
|
o = s:option(Value, option_name("ws_path"), translate("WebSocket Path"))
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "ws" })
|
o:depends({ [option_name("transport")] = "ws" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "ws" })
|
|
||||||
|
|
||||||
-- [[ HTTP/2部分 ]]--
|
-- [[ HTTP/2部分 ]]--
|
||||||
|
|
||||||
o = s:option(Value, option_name("h2_host"), translate("HTTP/2 Host"))
|
o = s:option(Value, option_name("h2_host"), translate("HTTP/2 Host"))
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "h2" })
|
o:depends({ [option_name("transport")] = "h2" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "h2" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("h2_path"), translate("HTTP/2 Path"))
|
o = s:option(Value, option_name("h2_path"), translate("HTTP/2 Path"))
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "h2" })
|
o:depends({ [option_name("transport")] = "h2" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "h2" })
|
|
||||||
|
|
||||||
-- [[ TCP部分 ]]--
|
-- [[ TCP部分 ]]--
|
||||||
|
|
||||||
@ -323,141 +237,111 @@ add_xray_depends(o, { [option_name("transport")] = "h2" })
|
|||||||
o = s:option(ListValue, option_name("tcp_guise"), translate("Camouflage Type"))
|
o = s:option(ListValue, option_name("tcp_guise"), translate("Camouflage Type"))
|
||||||
o:value("none", "none")
|
o:value("none", "none")
|
||||||
o:value("http", "http")
|
o:value("http", "http")
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "tcp" })
|
o:depends({ [option_name("transport")] = "tcp" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "tcp" })
|
|
||||||
|
|
||||||
-- HTTP域名
|
-- HTTP域名
|
||||||
o = s:option(DynamicList, option_name("tcp_guise_http_host"), translate("HTTP Host"))
|
o = s:option(DynamicList, option_name("tcp_guise_http_host"), translate("HTTP Host"))
|
||||||
add_v2ray_depends(o, { [option_name("tcp_guise")] = "http" })
|
o:depends({ [option_name("tcp_guise")] = "http" })
|
||||||
add_xray_depends(o, { [option_name("tcp_guise")] = "http" })
|
|
||||||
|
|
||||||
-- HTTP路径
|
-- HTTP路径
|
||||||
o = s:option(DynamicList, option_name("tcp_guise_http_path"), translate("HTTP Path"))
|
o = s:option(DynamicList, option_name("tcp_guise_http_path"), translate("HTTP Path"))
|
||||||
add_v2ray_depends(o, { [option_name("tcp_guise")] = "http" })
|
o:depends({ [option_name("tcp_guise")] = "http" })
|
||||||
add_xray_depends(o, { [option_name("tcp_guise")] = "http" })
|
|
||||||
|
|
||||||
-- [[ mKCP部分 ]]--
|
-- [[ mKCP部分 ]]--
|
||||||
|
|
||||||
o = s:option(ListValue, option_name("mkcp_guise"), translate("Camouflage Type"), translate('<br />none: default, no masquerade, data sent is packets with no characteristics.<br />srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).<br />utp: packets disguised as uTP will be recognized as bittorrent downloaded data.<br />wechat-video: packets disguised as WeChat video calls.<br />dtls: disguised as DTLS 1.2 packet.<br />wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)'))
|
o = s:option(ListValue, option_name("mkcp_guise"), translate("Camouflage Type"), translate('<br />none: default, no masquerade, data sent is packets with no characteristics.<br />srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).<br />utp: packets disguised as uTP will be recognized as bittorrent downloaded data.<br />wechat-video: packets disguised as WeChat video calls.<br />dtls: disguised as DTLS 1.2 packet.<br />wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)'))
|
||||||
for a, t in ipairs(header_type_list) do o:value(t) end
|
for a, t in ipairs(header_type_list) do o:value(t) end
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
o:depends({ [option_name("transport")] = "mkcp" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("mkcp_mtu"), translate("KCP MTU"))
|
o = s:option(Value, option_name("mkcp_mtu"), translate("KCP MTU"))
|
||||||
o.default = "1350"
|
o.default = "1350"
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
o:depends({ [option_name("transport")] = "mkcp" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("mkcp_tti"), translate("KCP TTI"))
|
o = s:option(Value, option_name("mkcp_tti"), translate("KCP TTI"))
|
||||||
o.default = "20"
|
o.default = "20"
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
o:depends({ [option_name("transport")] = "mkcp" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("mkcp_uplinkCapacity"), translate("KCP uplinkCapacity"))
|
o = s:option(Value, option_name("mkcp_uplinkCapacity"), translate("KCP uplinkCapacity"))
|
||||||
o.default = "5"
|
o.default = "5"
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
o:depends({ [option_name("transport")] = "mkcp" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("mkcp_downlinkCapacity"), translate("KCP downlinkCapacity"))
|
o = s:option(Value, option_name("mkcp_downlinkCapacity"), translate("KCP downlinkCapacity"))
|
||||||
o.default = "20"
|
o.default = "20"
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
o:depends({ [option_name("transport")] = "mkcp" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
|
||||||
|
|
||||||
o = s:option(Flag, option_name("mkcp_congestion"), translate("KCP Congestion"))
|
o = s:option(Flag, option_name("mkcp_congestion"), translate("KCP Congestion"))
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
o:depends({ [option_name("transport")] = "mkcp" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("mkcp_readBufferSize"), translate("KCP readBufferSize"))
|
o = s:option(Value, option_name("mkcp_readBufferSize"), translate("KCP readBufferSize"))
|
||||||
o.default = "1"
|
o.default = "1"
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
o:depends({ [option_name("transport")] = "mkcp" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("mkcp_writeBufferSize"), translate("KCP writeBufferSize"))
|
o = s:option(Value, option_name("mkcp_writeBufferSize"), translate("KCP writeBufferSize"))
|
||||||
o.default = "1"
|
o.default = "1"
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
o:depends({ [option_name("transport")] = "mkcp" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("mkcp_seed"), translate("KCP Seed"))
|
o = s:option(Value, option_name("mkcp_seed"), translate("KCP Seed"))
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
o:depends({ [option_name("transport")] = "mkcp" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
|
||||||
|
|
||||||
-- [[ DomainSocket部分 ]]--
|
-- [[ DomainSocket部分 ]]--
|
||||||
|
|
||||||
o = s:option(Value, option_name("ds_path"), "Path", translate("A legal file path. This file must not exist before running."))
|
o = s:option(Value, option_name("ds_path"), "Path", translate("A legal file path. This file must not exist before running."))
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "ds" })
|
o:depends({ [option_name("transport")] = "ds" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "ds" })
|
|
||||||
|
|
||||||
-- [[ QUIC部分 ]]--
|
-- [[ QUIC部分 ]]--
|
||||||
o = s:option(ListValue, option_name("quic_security"), translate("Encrypt Method"))
|
o = s:option(ListValue, option_name("quic_security"), translate("Encrypt Method"))
|
||||||
o:value("none")
|
o:value("none")
|
||||||
o:value("aes-128-gcm")
|
o:value("aes-128-gcm")
|
||||||
o:value("chacha20-poly1305")
|
o:value("chacha20-poly1305")
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "quic" })
|
o:depends({ [option_name("transport")] = "quic" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "quic" })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("quic_key"), translate("Encrypt Method") .. translate("Key"))
|
o = s:option(Value, option_name("quic_key"), translate("Encrypt Method") .. translate("Key"))
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "quic" })
|
o:depends({ [option_name("transport")] = "quic" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "quic" })
|
|
||||||
|
|
||||||
o = s:option(ListValue, option_name("quic_guise"), translate("Camouflage Type"))
|
o = s:option(ListValue, option_name("quic_guise"), translate("Camouflage Type"))
|
||||||
for a, t in ipairs(header_type_list) do o:value(t) end
|
for a, t in ipairs(header_type_list) do o:value(t) end
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "quic" })
|
o:depends({ [option_name("transport")] = "quic" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "quic" })
|
|
||||||
|
|
||||||
-- [[ gRPC部分 ]]--
|
-- [[ gRPC部分 ]]--
|
||||||
o = s:option(Value, option_name("grpc_serviceName"), "ServiceName")
|
o = s:option(Value, option_name("grpc_serviceName"), "ServiceName")
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "grpc" })
|
o:depends({ [option_name("transport")] = "grpc" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "grpc" })
|
|
||||||
|
|
||||||
o = s:option(Flag, option_name("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 = s:option(Flag, option_name("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."))
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "tcp" })
|
o:depends({ [option_name("transport")] = "tcp" })
|
||||||
add_v2ray_depends(o, { [option_name("transport")] = "ws" })
|
o:depends({ [option_name("transport")] = "ws" })
|
||||||
add_xray_depends(o, { [option_name("transport")] = "tcp" })
|
|
||||||
add_xray_depends(o, { [option_name("transport")] = "ws" })
|
|
||||||
|
|
||||||
-- [[ Fallback部分 ]]--
|
-- [[ Fallback部分 ]]--
|
||||||
o = s:option(Flag, option_name("fallback"), translate("Fallback"))
|
o = s:option(Flag, option_name("fallback"), translate("Fallback"))
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "vless", [option_name("transport")] = "tcp" })
|
o:depends({ [option_name("protocol")] = "vless", [option_name("transport")] = "tcp" })
|
||||||
add_v2ray_depends(o, { [option_name("protocol")] = "trojan", [option_name("transport")] = "tcp" })
|
o:depends({ [option_name("protocol")] = "trojan", [option_name("transport")] = "tcp" })
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "vless", [option_name("transport")] = "tcp" })
|
|
||||||
add_xray_depends(o, { [option_name("protocol")] = "trojan", [option_name("transport")] = "tcp" })
|
|
||||||
|
|
||||||
--[[
|
--[[
|
||||||
o = s:option(Value, option_name("fallback_alpn"), "Fallback alpn")
|
o = s:option(Value, option_name("fallback_alpn"), "Fallback alpn")
|
||||||
add_v2ray_depends(o, { [option_name("fallback")] = true })
|
o:depends({ [option_name("fallback")] = true })
|
||||||
add_xray_depends(o, { [option_name("fallback")] = true })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("fallback_path"), "Fallback path")
|
o = s:option(Value, option_name("fallback_path"), "Fallback path")
|
||||||
add_v2ray_depends(o, { [option_name("fallback")] = true })
|
o:depends({ [option_name("fallback")] = true })
|
||||||
add_xray_depends(o, { [option_name("fallback")] = true })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("fallback_dest"), "Fallback dest")
|
o = s:option(Value, option_name("fallback_dest"), "Fallback dest")
|
||||||
add_v2ray_depends(o, { [option_name("fallback")] = true })
|
o:depends({ [option_name("fallback")] = true })
|
||||||
add_xray_depends(o, { [option_name("fallback")] = true })
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("fallback_xver"), "Fallback xver")
|
o = s:option(Value, option_name("fallback_xver"), "Fallback xver")
|
||||||
o.default = 0
|
o.default = 0
|
||||||
add_v2ray_depends(o, { [option_name("fallback")] = true })
|
o:depends({ [option_name("fallback")] = true })
|
||||||
add_xray_depends(o, { [option_name("fallback")] = true })
|
|
||||||
]]--
|
]]--
|
||||||
|
|
||||||
o = s:option(DynamicList, option_name("fallback_list"), "Fallback", translate("dest,path"))
|
o = s:option(DynamicList, option_name("fallback_list"), "Fallback", translate("dest,path"))
|
||||||
add_v2ray_depends(o, { [option_name("fallback")] = true })
|
o:depends({ [option_name("fallback")] = true })
|
||||||
add_xray_depends(o, { [option_name("fallback")] = true })
|
|
||||||
|
|
||||||
o = s:option(Flag, option_name("bind_local"), translate("Bind Local"), translate("When selected, it can only be accessed locally, It is recommended to turn on when using reverse proxies or be fallback."))
|
o = s:option(Flag, option_name("bind_local"), translate("Bind Local"), translate("When selected, it can only be accessed locally, It is recommended to turn on when using reverse proxies or be fallback."))
|
||||||
o.default = "0"
|
o.default = "0"
|
||||||
add_v2ray_depends(o)
|
|
||||||
add_xray_depends(o)
|
|
||||||
|
|
||||||
o = s:option(Flag, option_name("accept_lan"), translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!"))
|
o = s:option(Flag, option_name("accept_lan"), translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!"))
|
||||||
o.default = "0"
|
o.default = "0"
|
||||||
add_v2ray_depends(o)
|
|
||||||
add_xray_depends(o)
|
|
||||||
|
|
||||||
local nodes_table = {}
|
local nodes_table = {}
|
||||||
for k, e in ipairs(api.get_valid_nodes()) do
|
for k, e in ipairs(api.get_valid_nodes()) do
|
||||||
if e.node_type == "normal" and (e.type == "V2ray" or e.type == "Xray") then
|
if e.node_type == "normal" and e.type == type_name then
|
||||||
nodes_table[#nodes_table + 1] = {
|
nodes_table[#nodes_table + 1] = {
|
||||||
id = e[".name"],
|
id = e[".name"],
|
||||||
remarks = e["remark"]
|
remarks = e["remark"]
|
||||||
@ -472,45 +356,32 @@ o:value("_http", translate("Custom HTTP"))
|
|||||||
o:value("_iface", translate("Custom Interface") .. " (Only Support Xray)")
|
o:value("_iface", translate("Custom Interface") .. " (Only Support Xray)")
|
||||||
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
|
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
|
||||||
o.default = "nil"
|
o.default = "nil"
|
||||||
add_v2ray_depends(o)
|
|
||||||
add_xray_depends(o)
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("outbound_node_address"), translate("Address (Support Domain Name)"))
|
o = s:option(Value, option_name("outbound_node_address"), translate("Address (Support Domain Name)"))
|
||||||
add_v2ray_depends(o, { [option_name("outbound_node")] = "_socks"})
|
o:depends({ [option_name("outbound_node")] = "_socks"})
|
||||||
add_v2ray_depends(o, { [option_name("outbound_node")] = "_http"})
|
o:depends({ [option_name("outbound_node")] = "_http"})
|
||||||
add_xray_depends(o, { [option_name("outbound_node")] = "_socks"})
|
|
||||||
add_xray_depends(o, { [option_name("outbound_node")] = "_http"})
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("outbound_node_port"), translate("Port"))
|
o = s:option(Value, option_name("outbound_node_port"), translate("Port"))
|
||||||
o.datatype = "port"
|
o.datatype = "port"
|
||||||
add_v2ray_depends(o, { [option_name("outbound_node")] = "_socks"})
|
o:depends({ [option_name("outbound_node")] = "_socks"})
|
||||||
add_v2ray_depends(o, { [option_name("outbound_node")] = "_http"})
|
o:depends({ [option_name("outbound_node")] = "_http"})
|
||||||
add_xray_depends(o, { [option_name("outbound_node")] = "_socks"})
|
|
||||||
add_xray_depends(o, { [option_name("outbound_node")] = "_http"})
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("outbound_node_username"), translate("Username"))
|
o = s:option(Value, option_name("outbound_node_username"), translate("Username"))
|
||||||
add_v2ray_depends(o, { [option_name("outbound_node")] = "_socks"})
|
o:depends({ [option_name("outbound_node")] = "_socks"})
|
||||||
add_v2ray_depends(o, { [option_name("outbound_node")] = "_http"})
|
o:depends({ [option_name("outbound_node")] = "_http"})
|
||||||
add_xray_depends(o, { [option_name("outbound_node")] = "_socks"})
|
|
||||||
add_xray_depends(o, { [option_name("outbound_node")] = "_http"})
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("outbound_node_password"), translate("Password"))
|
o = s:option(Value, option_name("outbound_node_password"), translate("Password"))
|
||||||
o.password = true
|
o.password = true
|
||||||
add_v2ray_depends(o, { [option_name("outbound_node")] = "_socks"})
|
o:depends({ [option_name("outbound_node")] = "_socks"})
|
||||||
add_v2ray_depends(o, { [option_name("outbound_node")] = "_http"})
|
o:depends({ [option_name("outbound_node")] = "_http"})
|
||||||
add_xray_depends(o, { [option_name("outbound_node")] = "_socks"})
|
|
||||||
add_xray_depends(o, { [option_name("outbound_node")] = "_http"})
|
|
||||||
|
|
||||||
o = s:option(Value, option_name("outbound_node_iface"), translate("Interface"))
|
o = s:option(Value, option_name("outbound_node_iface"), translate("Interface"))
|
||||||
o.default = "eth1"
|
o.default = "eth1"
|
||||||
add_v2ray_depends(o, { [option_name("outbound_node")] = "_iface"})
|
o:depends({ [option_name("outbound_node")] = "_iface"})
|
||||||
add_xray_depends(o, { [option_name("outbound_node")] = "_iface"})
|
|
||||||
|
|
||||||
o = s:option(Flag, option_name("log"), translate("Log"))
|
o = s:option(Flag, option_name("log"), translate("Log"))
|
||||||
o.default = "1"
|
o.default = "1"
|
||||||
o.rmempty = false
|
o.rmempty = false
|
||||||
add_v2ray_depends(o)
|
|
||||||
add_xray_depends(o)
|
|
||||||
|
|
||||||
o = s:option(ListValue, option_name("loglevel"), translate("Log Level"))
|
o = s:option(ListValue, option_name("loglevel"), translate("Log Level"))
|
||||||
o.default = "warning"
|
o.default = "warning"
|
||||||
@ -518,8 +389,7 @@ o:value("debug")
|
|||||||
o:value("info")
|
o:value("info")
|
||||||
o:value("warning")
|
o:value("warning")
|
||||||
o:value("error")
|
o:value("error")
|
||||||
add_v2ray_depends(o, { [option_name("log")] = true })
|
o:depends({ [option_name("log")] = true })
|
||||||
add_xray_depends(o, { [option_name("log")] = true })
|
|
||||||
|
|
||||||
for key, value in pairs(s.fields) do
|
for key, value in pairs(s.fields) do
|
||||||
if key:find(option_prefix) == 1 then
|
if key:find(option_prefix) == 1 then
|
||||||
@ -529,4 +399,13 @@ for key, value in pairs(s.fields) do
|
|||||||
s.fields[key].remove = rm_prefix_remove
|
s.fields[key].remove = rm_prefix_remove
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local deps = s.fields[key].deps
|
||||||
|
if #deps > 0 then
|
||||||
|
for index, value in ipairs(deps) do
|
||||||
|
deps[index]["type"] = type_name
|
||||||
|
end
|
||||||
|
else
|
||||||
|
s.fields[key]:depends({ type = type_name })
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -0,0 +1,377 @@
|
|||||||
|
local m, s = ...
|
||||||
|
|
||||||
|
local api = require "luci.passwall2.api"
|
||||||
|
|
||||||
|
if not api.is_finded("sing-box")then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local singbox_tags = luci.sys.exec(api.finded("sing-box") .. " version | grep 'Tags:' | awk '{print $2}'")
|
||||||
|
|
||||||
|
local type_name = "sing-box"
|
||||||
|
|
||||||
|
local option_prefix = "singbox_"
|
||||||
|
|
||||||
|
local function option_name(name)
|
||||||
|
return option_prefix .. name
|
||||||
|
end
|
||||||
|
|
||||||
|
local function rm_prefix_cfgvalue(self, section)
|
||||||
|
if self.option:find(option_prefix) == 1 then
|
||||||
|
return m:get(section, self.option:sub(1 + #option_prefix))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local function rm_prefix_write(self, section, value)
|
||||||
|
if s.fields["type"]:formvalue(arg[1]) == type_name then
|
||||||
|
if self.option:find(option_prefix) == 1 then
|
||||||
|
m:set(section, self.option:sub(1 + #option_prefix), value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
local function rm_prefix_remove(self, section, value)
|
||||||
|
if s.fields["type"]:formvalue(arg[1]) == type_name then
|
||||||
|
if self.option:find(option_prefix) == 1 then
|
||||||
|
m:del(section, self.option:sub(1 + #option_prefix))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local ss_method_list = {
|
||||||
|
"none", "aes-128-gcm", "aes-192-gcm", "aes-256-gcm", "chacha20-ietf-poly1305", "xchacha20-ietf-poly1305",
|
||||||
|
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
||||||
|
}
|
||||||
|
|
||||||
|
-- [[ Sing-Box ]]
|
||||||
|
|
||||||
|
s.fields["type"]:value(type_name, "Sing-Box")
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("protocol"), translate("Protocol"))
|
||||||
|
o:value("mixed", "Mixed")
|
||||||
|
o:value("socks", "Socks")
|
||||||
|
o:value("http", "HTTP")
|
||||||
|
o:value("shadowsocks", "Shadowsocks")
|
||||||
|
o:value("vmess", "Vmess")
|
||||||
|
o:value("vless", "VLESS")
|
||||||
|
o:value("trojan", "Trojan")
|
||||||
|
o:value("naive", "Naive")
|
||||||
|
if singbox_tags:find("with_quic") then
|
||||||
|
o:value("hysteria", "Hysteria")
|
||||||
|
end
|
||||||
|
if singbox_tags:find("with_quic") then
|
||||||
|
o:value("tuic", "TUIC")
|
||||||
|
end
|
||||||
|
if singbox_tags:find("with_quic") then
|
||||||
|
o:value("hysteria2", "Hysteria2")
|
||||||
|
end
|
||||||
|
o:value("direct", "Direct")
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("port"), translate("Listen Port"))
|
||||||
|
o.datatype = "port"
|
||||||
|
|
||||||
|
o = s:option(Flag, option_name("auth"), translate("Auth"))
|
||||||
|
o.validate = function(self, value, t)
|
||||||
|
if value and value == "1" then
|
||||||
|
local user_v = s.fields[option_name("username")]:formvalue(t) or ""
|
||||||
|
local pass_v = s.fields[option_name("password")]:formvalue(t) or ""
|
||||||
|
if user_v == "" or pass_v == "" then
|
||||||
|
return nil, translate("Username and Password must be used together!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return value
|
||||||
|
end
|
||||||
|
o:depends({ [option_name("protocol")] = "mixed" })
|
||||||
|
o:depends({ [option_name("protocol")] = "socks" })
|
||||||
|
o:depends({ [option_name("protocol")] = "http" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("username"), translate("Username"))
|
||||||
|
o:depends({ [option_name("auth")] = true })
|
||||||
|
o:depends({ [option_name("protocol")] = "naive" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("password"), translate("Password"))
|
||||||
|
o.password = true
|
||||||
|
o:depends({ [option_name("auth")] = true })
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
|
o:depends({ [option_name("protocol")] = "naive" })
|
||||||
|
o:depends({ [option_name("protocol")] = "tuic" })
|
||||||
|
|
||||||
|
if singbox_tags:find("with_quic") then
|
||||||
|
o = s:option(Value, option_name("hysteria_up_mbps"), translate("Max upload Mbps"))
|
||||||
|
o.default = "100"
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("hysteria_down_mbps"), translate("Max download Mbps"))
|
||||||
|
o.default = "100"
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("hysteria_obfs"), translate("Obfs Password"))
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria" })
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("hysteria_auth_type"), translate("Auth Type"))
|
||||||
|
o:value("disable", translate("Disable"))
|
||||||
|
o:value("string", translate("STRING"))
|
||||||
|
o:value("base64", translate("BASE64"))
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("hysteria_auth_password"), translate("Auth Password"))
|
||||||
|
o.password = true
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria", [option_name("hysteria_auth_type")] = "string"})
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria", [option_name("hysteria_auth_type")] = "base64"})
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("hysteria_recv_window_conn"), translate("QUIC stream receive window"))
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("hysteria_recv_window_client"), translate("QUIC connection receive window"))
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("hysteria_max_conn_client"), translate("QUIC concurrent bidirectional streams"))
|
||||||
|
o.default = "1024"
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria" })
|
||||||
|
|
||||||
|
o = s:option(Flag, option_name("hysteria_disable_mtu_discovery"), translate("Disable MTU detection"))
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria" })
|
||||||
|
end
|
||||||
|
|
||||||
|
if singbox_tags:find("with_quic") then
|
||||||
|
o = s:option(ListValue, option_name("tuic_congestion_control"), translate("Congestion control algorithm"))
|
||||||
|
o.default = "cubic"
|
||||||
|
o:value("bbr", translate("BBR"))
|
||||||
|
o:value("cubic", translate("CUBIC"))
|
||||||
|
o:value("new_reno", translate("New Reno"))
|
||||||
|
o:depends({ [option_name("protocol")] = "tuic" })
|
||||||
|
|
||||||
|
o = s:option(Flag, option_name("tuic_zero_rtt_handshake"), translate("Enable 0-RTT QUIC handshake"))
|
||||||
|
o.default = 0
|
||||||
|
o:depends({ [option_name("protocol")] = "tuic" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("tuic_heartbeat"), translate("Heartbeat interval(second)"))
|
||||||
|
o.datatype = "uinteger"
|
||||||
|
o.default = "3"
|
||||||
|
o:depends({ [option_name("protocol")] = "tuic" })
|
||||||
|
end
|
||||||
|
|
||||||
|
if singbox_tags:find("with_quic") then
|
||||||
|
o = s:option(Flag, option_name("hysteria2_ignore_client_bandwidth"), translate("Commands the client to use the BBR flow control algorithm"))
|
||||||
|
o.default = 0
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria2" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("hysteria2_up_mbps"), translate("Max upload Mbps"))
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria2", [option_name("hysteria2_ignore_client_bandwidth")] = false })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("hysteria2_down_mbps"), translate("Max download Mbps"))
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria2", [option_name("hysteria2_ignore_client_bandwidth")] = false })
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("hysteria2_obfs_type"), translate("Obfs Type"))
|
||||||
|
o:value("", translate("Disable"))
|
||||||
|
o:value("salamander")
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria2" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("hysteria2_obfs_password"), translate("Obfs Password"))
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria2" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("hysteria2_auth_password"), translate("Auth Password"))
|
||||||
|
o.password = true
|
||||||
|
o:depends({ [option_name("protocol")] = "hysteria2"})
|
||||||
|
end
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("d_protocol"), translate("Destination protocol"))
|
||||||
|
o:value("tcp", "TCP")
|
||||||
|
o:value("udp", "UDP")
|
||||||
|
o:value("tcp,udp", "TCP,UDP")
|
||||||
|
o:depends({ [option_name("protocol")] = "direct" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("d_address"), translate("Destination address"))
|
||||||
|
o:depends({ [option_name("protocol")] = "direct" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("d_port"), translate("Destination port"))
|
||||||
|
o.datatype = "port"
|
||||||
|
o:depends({ [option_name("protocol")] = "direct" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("decryption"), translate("Encrypt Method"))
|
||||||
|
o.default = "none"
|
||||||
|
o:depends({ [option_name("protocol")] = "vless" })
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("ss_method"), translate("Encrypt Method"))
|
||||||
|
o.not_rewrite = true
|
||||||
|
for a, t in ipairs(ss_method_list) do o:value(t) end
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
|
function o.cfgvalue(self, section)
|
||||||
|
return m:get(section, "method")
|
||||||
|
end
|
||||||
|
function o.write(self, section, value)
|
||||||
|
if s.fields["type"]:formvalue(arg[1]) == type_name then
|
||||||
|
m:set(section, "method", value)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
o = s:option(DynamicList, option_name("uuid"), translate("ID") .. "/" .. translate("Password"))
|
||||||
|
for i = 1, 3 do
|
||||||
|
o:value(api.gen_uuid(1))
|
||||||
|
end
|
||||||
|
o:depends({ [option_name("protocol")] = "vmess" })
|
||||||
|
o:depends({ [option_name("protocol")] = "vless" })
|
||||||
|
o:depends({ [option_name("protocol")] = "trojan" })
|
||||||
|
o:depends({ [option_name("protocol")] = "tuic" })
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("flow"), translate("flow"))
|
||||||
|
o.default = ""
|
||||||
|
o:value("", translate("Disable"))
|
||||||
|
o:value("xtls-rprx-vision")
|
||||||
|
o:depends({ [option_name("protocol")] = "vless" })
|
||||||
|
|
||||||
|
o = s:option(Flag, option_name("tls"), translate("TLS"))
|
||||||
|
o.default = 0
|
||||||
|
o.validate = function(self, value, t)
|
||||||
|
if value then
|
||||||
|
if value == "1" then
|
||||||
|
local ca = s.fields[option_name("tls_certificateFile")]:formvalue(t) or ""
|
||||||
|
local key = s.fields[option_name("tls_keyFile")]:formvalue(t) or ""
|
||||||
|
if ca == "" or key == "" then
|
||||||
|
return nil, translate("Public key and Private key path can not be empty!")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
o:depends({ [option_name("protocol")] = "http" })
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
|
o:depends({ [option_name("protocol")] = "vmess" })
|
||||||
|
o:depends({ [option_name("protocol")] = "vless" })
|
||||||
|
o:depends({ [option_name("protocol")] = "trojan" })
|
||||||
|
|
||||||
|
-- [[ TLS部分 ]] --
|
||||||
|
|
||||||
|
o = s:option(FileUpload, option_name("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"
|
||||||
|
o:depends({ [option_name("tls")] = true })
|
||||||
|
o.validate = function(self, value, t)
|
||||||
|
if value and value ~= "" then
|
||||||
|
if not nixio.fs.access(value) then
|
||||||
|
return nil, translate("Can't find this file!")
|
||||||
|
else
|
||||||
|
return value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
o = s:option(FileUpload, option_name("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"
|
||||||
|
o:depends({ [option_name("tls")] = true })
|
||||||
|
o.validate = function(self, value, t)
|
||||||
|
if value and value ~= "" then
|
||||||
|
if not nixio.fs.access(value) then
|
||||||
|
return nil, translate("Can't find this file!")
|
||||||
|
else
|
||||||
|
return value
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("transport"), translate("Transport"))
|
||||||
|
o:value("tcp", "TCP")
|
||||||
|
o:value("http", "HTTP")
|
||||||
|
o:value("ws", "WebSocket")
|
||||||
|
o:value("quic", "QUIC")
|
||||||
|
o:value("grpc", "gRPC")
|
||||||
|
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||||
|
o:depends({ [option_name("protocol")] = "vmess" })
|
||||||
|
o:depends({ [option_name("protocol")] = "vless" })
|
||||||
|
o:depends({ [option_name("protocol")] = "trojan" })
|
||||||
|
|
||||||
|
-- [[ HTTP部分 ]]--
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("http_host"), translate("HTTP Host"))
|
||||||
|
o:depends({ [option_name("transport")] = "http" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("http_path"), translate("HTTP Path"))
|
||||||
|
o:depends({ [option_name("transport")] = "http" })
|
||||||
|
|
||||||
|
-- [[ WebSocket部分 ]]--
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("ws_host"), translate("WebSocket Host"))
|
||||||
|
o:depends({ [option_name("transport")] = "ws" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("ws_path"), translate("WebSocket Path"))
|
||||||
|
o:depends({ [option_name("transport")] = "ws" })
|
||||||
|
|
||||||
|
-- [[ gRPC部分 ]]--
|
||||||
|
o = s:option(Value, option_name("grpc_serviceName"), "ServiceName")
|
||||||
|
o:depends({ [option_name("transport")] = "grpc" })
|
||||||
|
|
||||||
|
o = s:option(Flag, option_name("bind_local"), translate("Bind Local"), translate("When selected, it can only be accessed locally, It is recommended to turn on when using reverse proxies or be fallback."))
|
||||||
|
o.default = "0"
|
||||||
|
|
||||||
|
o = s:option(Flag, option_name("accept_lan"), translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!"))
|
||||||
|
o.default = "0"
|
||||||
|
|
||||||
|
local nodes_table = {}
|
||||||
|
for k, e in ipairs(api.get_valid_nodes()) do
|
||||||
|
if e.node_type == "normal" and e.type == type_name then
|
||||||
|
nodes_table[#nodes_table + 1] = {
|
||||||
|
id = e[".name"],
|
||||||
|
remarks = e["remark"]
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("outbound_node"), translate("outbound node"))
|
||||||
|
o:value("nil", translate("Close"))
|
||||||
|
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.default = "nil"
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("outbound_node_address"), translate("Address (Support Domain Name)"))
|
||||||
|
o:depends({ [option_name("outbound_node")] = "_socks" })
|
||||||
|
o:depends({ [option_name("outbound_node")] = "_http" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("outbound_node_port"), translate("Port"))
|
||||||
|
o.datatype = "port"
|
||||||
|
o:depends({ [option_name("outbound_node")] = "_socks" })
|
||||||
|
o:depends({ [option_name("outbound_node")] = "_http" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("outbound_node_username"), translate("Username"))
|
||||||
|
o:depends({ [option_name("outbound_node")] = "_socks" })
|
||||||
|
o:depends({ [option_name("outbound_node")] = "_http" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("outbound_node_password"), translate("Password"))
|
||||||
|
o.password = true
|
||||||
|
o:depends({ [option_name("outbound_node")] = "_socks" })
|
||||||
|
o:depends({ [option_name("outbound_node")] = "_http" })
|
||||||
|
|
||||||
|
o = s:option(Value, option_name("outbound_node_iface"), translate("Interface"))
|
||||||
|
o.default = "eth1"
|
||||||
|
o:depends({ [option_name("outbound_node")] = "_iface" })
|
||||||
|
|
||||||
|
o = s:option(Flag, option_name("log"), translate("Log"))
|
||||||
|
o.default = "1"
|
||||||
|
o.rmempty = false
|
||||||
|
|
||||||
|
o = s:option(ListValue, option_name("loglevel"), translate("Log Level"))
|
||||||
|
o.default = "info"
|
||||||
|
o:value("debug")
|
||||||
|
o:value("info")
|
||||||
|
o:value("warn")
|
||||||
|
o:value("error")
|
||||||
|
o:depends({ [option_name("log")] = true })
|
||||||
|
|
||||||
|
for key, value in pairs(s.fields) do
|
||||||
|
if key:find(option_prefix) == 1 then
|
||||||
|
if not s.fields[key].not_rewrite then
|
||||||
|
s.fields[key].cfgvalue = rm_prefix_cfgvalue
|
||||||
|
s.fields[key].write = rm_prefix_write
|
||||||
|
s.fields[key].remove = rm_prefix_remove
|
||||||
|
end
|
||||||
|
|
||||||
|
local deps = s.fields[key].deps
|
||||||
|
if #deps > 0 then
|
||||||
|
for index, value in ipairs(deps) do
|
||||||
|
deps[index]["type"] = type_name
|
||||||
|
end
|
||||||
|
else
|
||||||
|
s.fields[key]:depends({ type = type_name })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -282,7 +282,7 @@ function get_valid_nodes()
|
|||||||
local address = e.address
|
local address = e.address
|
||||||
if is_ip(address) or datatypes.hostname(address) then
|
if is_ip(address) or datatypes.hostname(address) then
|
||||||
local type = e.type
|
local type = e.type
|
||||||
if (type == "V2ray" or type == "Xray") and e.protocol then
|
if (type == "sing-box" or type == "Xray") and e.protocol then
|
||||||
local protocol = e.protocol
|
local protocol = e.protocol
|
||||||
if protocol == "vmess" then
|
if protocol == "vmess" then
|
||||||
protocol = "VMess"
|
protocol = "VMess"
|
||||||
@ -314,7 +314,7 @@ function get_node_remarks(n)
|
|||||||
remarks = "%s:[%s] " % {n.type .. " " .. i18n.translatef(n.protocol), n.remarks}
|
remarks = "%s:[%s] " % {n.type .. " " .. i18n.translatef(n.protocol), n.remarks}
|
||||||
else
|
else
|
||||||
local type2 = n.type
|
local type2 = n.type
|
||||||
if (n.type == "V2ray" or n.type == "Xray") and n.protocol then
|
if (n.type == "sing-box" or n.type == "Xray") and n.protocol then
|
||||||
local protocol = n.protocol
|
local protocol = n.protocol
|
||||||
if protocol == "vmess" then
|
if protocol == "vmess" then
|
||||||
protocol = "VMess"
|
protocol = "VMess"
|
||||||
@ -381,8 +381,12 @@ function get_customed_path(e)
|
|||||||
return uci_get_type("global_app", e .. "_file")
|
return uci_get_type("global_app", e .. "_file")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function finded(e)
|
||||||
|
return luci.sys.exec('echo -n $(type -t -p "/bin/%s" -p "/usr/bin/%s" -p "%s" "%s" | head -n1)' % {e, e, get_customed_path(e), e})
|
||||||
|
end
|
||||||
|
|
||||||
function is_finded(e)
|
function is_finded(e)
|
||||||
return luci.sys.exec('type -t -p "/bin/%s" -p "/usr/bin/%s" -p "%s" "%s"' % {e, e, get_customed_path(e), e}) ~= "" and true or false
|
return finded(e) ~= "" and true or false
|
||||||
end
|
end
|
||||||
|
|
||||||
function clone(org)
|
function clone(org)
|
||||||
|
@ -33,13 +33,26 @@ _M.hysteria = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_M.v2ray = {
|
_M.singbox = {
|
||||||
name = "V2ray",
|
name = "Sing-Box",
|
||||||
repo = "v2fly/v2ray-core",
|
repo = "SagerNet/sing-box",
|
||||||
|
get_url = gh_pre_release_url,
|
||||||
|
cmd_version = "version | awk '{print $3}' | sed -n 1P",
|
||||||
|
zipped = true,
|
||||||
|
default_path = "/usr/bin/sing-box",
|
||||||
|
match_fmt_str = "linux%%-%s",
|
||||||
|
file_tree = {
|
||||||
|
x86_64 = "amd64"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_M.xray = {
|
||||||
|
name = "Xray",
|
||||||
|
repo = "XTLS/Xray-core",
|
||||||
get_url = gh_pre_release_url,
|
get_url = gh_pre_release_url,
|
||||||
cmd_version = "version | awk '{print $2}' | sed -n 1P",
|
cmd_version = "version | awk '{print $2}' | sed -n 1P",
|
||||||
zipped = true,
|
zipped = true,
|
||||||
default_path = "/usr/bin/v2ray",
|
default_path = "/usr/bin/xray",
|
||||||
match_fmt_str = "linux%%-%s",
|
match_fmt_str = "linux%%-%s",
|
||||||
file_tree = {
|
file_tree = {
|
||||||
x86_64 = "64",
|
x86_64 = "64",
|
||||||
@ -49,15 +62,4 @@ _M.v2ray = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_M.xray = {
|
|
||||||
name = "Xray",
|
|
||||||
repo = "XTLS/Xray-core",
|
|
||||||
get_url = gh_pre_release_url,
|
|
||||||
cmd_version = _M.v2ray.cmd_version,
|
|
||||||
zipped = true,
|
|
||||||
default_path = "/usr/bin/xray",
|
|
||||||
match_fmt_str = _M.v2ray.match_fmt_str,
|
|
||||||
file_tree = _M.v2ray.file_tree
|
|
||||||
}
|
|
||||||
|
|
||||||
return _M
|
return _M
|
||||||
|
@ -144,12 +144,12 @@ local function start()
|
|||||||
elseif type == "SS-Rust" then
|
elseif type == "SS-Rust" then
|
||||||
config = require(require_dir .. "util_shadowsocks").gen_config_server(user)
|
config = require(require_dir .. "util_shadowsocks").gen_config_server(user)
|
||||||
bin = ln_run("/usr/bin/ssserver", "ssserver", "-c " .. config_file, log_path)
|
bin = ln_run("/usr/bin/ssserver", "ssserver", "-c " .. config_file, log_path)
|
||||||
elseif type == "V2ray" then
|
|
||||||
config = require(require_dir .. "util_xray").gen_config_server(user)
|
|
||||||
bin = ln_run(api.get_app_path("v2ray"), "v2ray", "run -c " .. config_file, log_path)
|
|
||||||
elseif type == "Xray" then
|
elseif type == "Xray" then
|
||||||
config = require(require_dir .. "util_xray").gen_config_server(user)
|
config = require(require_dir .. "util_xray").gen_config_server(user)
|
||||||
bin = ln_run(api.get_app_path("xray"), "xray", "run -c " .. config_file, log_path)
|
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)
|
||||||
|
bin = ln_run(api.get_app_path("singbox"), "sing-box", "run -c " .. config_file, log_path)
|
||||||
elseif type == "Brook" then
|
elseif type == "Brook" then
|
||||||
local brook_protocol = user.protocol
|
local brook_protocol = user.protocol
|
||||||
local brook_password = user.password
|
local brook_password = user.password
|
||||||
|
1533
luci-app-passwall2/luasrc/passwall2/util_sing-box.lua
Normal file
1533
luci-app-passwall2/luasrc/passwall2/util_sing-box.lua
Normal file
File diff suppressed because it is too large
Load Diff
@ -47,8 +47,8 @@ function gen_outbound(flag, node, tag, proxy_table)
|
|||||||
proxy_tag = proxy_table.tag or "nil"
|
proxy_tag = proxy_table.tag or "nil"
|
||||||
end
|
end
|
||||||
|
|
||||||
if node.type == "V2ray" or node.type == "Xray" then
|
if node.type == "Xray" then
|
||||||
if node.type == "Xray" and node.tlsflow == "xtls-rprx-vision" then
|
if node.flow == "xtls-rprx-vision" then
|
||||||
else
|
else
|
||||||
proxy = 0
|
proxy = 0
|
||||||
if proxy_tag ~= "nil" then
|
if proxy_tag ~= "nil" then
|
||||||
@ -60,7 +60,7 @@ function gen_outbound(flag, node, tag, proxy_table)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if node.type ~= "V2ray" and node.type ~= "Xray" then
|
if node.type ~= "Xray" then
|
||||||
local relay_port = node.port
|
local relay_port = node.port
|
||||||
new_port = get_new_port()
|
new_port = get_new_port()
|
||||||
local config_file = string.format("%s_%s_%s.json", flag, tag, new_port)
|
local config_file = string.format("%s_%s_%s.json", flag, tag, new_port)
|
||||||
@ -87,10 +87,10 @@ function gen_outbound(flag, node, tag, proxy_table)
|
|||||||
node.stream_security = "none"
|
node.stream_security = "none"
|
||||||
end
|
end
|
||||||
|
|
||||||
if node.type == "V2ray" or node.type == "Xray" then
|
if node.type == "Xray" then
|
||||||
if node.tls and node.tls == "1" then
|
if node.tls and node.tls == "1" then
|
||||||
node.stream_security = "tls"
|
node.stream_security = "tls"
|
||||||
if node.type == "Xray" and node.reality and node.reality == "1" then
|
if node.reality and node.reality == "1" then
|
||||||
node.stream_security = "reality"
|
node.stream_security = "reality"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -133,7 +133,7 @@ function gen_outbound(flag, node, tag, proxy_table)
|
|||||||
tlsSettings = (node.stream_security == "tls") and {
|
tlsSettings = (node.stream_security == "tls") and {
|
||||||
serverName = node.tls_serverName,
|
serverName = node.tls_serverName,
|
||||||
allowInsecure = (node.tls_allowInsecure == "1") and true or false,
|
allowInsecure = (node.tls_allowInsecure == "1") and true or false,
|
||||||
fingerprint = (node.type == "Xray" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or nil
|
fingerprint = (node.type == "Xray" and node.utls == "1" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or nil
|
||||||
} or nil,
|
} or nil,
|
||||||
realitySettings = (node.stream_security == "reality") and {
|
realitySettings = (node.stream_security == "reality") and {
|
||||||
serverName = node.tls_serverName,
|
serverName = node.tls_serverName,
|
||||||
@ -204,7 +204,7 @@ function gen_outbound(flag, node, tag, proxy_table)
|
|||||||
level = 0,
|
level = 0,
|
||||||
security = (node.protocol == "vmess") and node.security or nil,
|
security = (node.protocol == "vmess") and node.security or nil,
|
||||||
encryption = node.encryption or "none",
|
encryption = node.encryption or "none",
|
||||||
flow = (node.protocol == "vless" and node.tls == '1' and node.tlsflow) and node.tlsflow or nil
|
flow = (node.protocol == "vless" and node.tls == '1' and node.flow) and node.flow or nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -267,7 +267,7 @@ function gen_config_server(node)
|
|||||||
for i = 1, #node.uuid do
|
for i = 1, #node.uuid do
|
||||||
clients[i] = {
|
clients[i] = {
|
||||||
id = node.uuid[i],
|
id = node.uuid[i],
|
||||||
flow = ("vless" == node.protocol and "1" == node.tls and node.tlsflow) and node.tlsflow or nil
|
flow = ("vless" == node.protocol and "1" == node.tls and node.flow) and node.flow or nil
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
settings = {
|
settings = {
|
||||||
@ -760,10 +760,10 @@ function gen_config(var)
|
|||||||
else
|
else
|
||||||
if proxy then
|
if proxy then
|
||||||
local pre_proxy = nil
|
local pre_proxy = nil
|
||||||
if _node.type ~= "V2ray" and _node.type ~= "Xray" then
|
if _node.type ~= "Xray" then
|
||||||
pre_proxy = true
|
pre_proxy = true
|
||||||
end
|
end
|
||||||
if _node.type == "Xray" and _node.tlsflow == "xtls-rprx-vision" then
|
if _node.type == "Xray" and _node.flow == "xtls-rprx-vision" then
|
||||||
pre_proxy = true
|
pre_proxy = true
|
||||||
end
|
end
|
||||||
if pre_proxy then
|
if pre_proxy then
|
||||||
|
@ -91,7 +91,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="pure-u-2-3">
|
<div class="pure-u-2-3">
|
||||||
<h4 id="status_node">V2ray<br /><span class="red"><%:NOT RUNNING%></span></h4>
|
<h4 id="status_node">Xray<br /><span class="red"><%:NOT RUNNING%></span></h4>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -145,7 +145,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
|||||||
if (true) {
|
if (true) {
|
||||||
var status_node = document.getElementById('status_node');
|
var status_node = document.getElementById('status_node');
|
||||||
if (status_node) {
|
if (status_node) {
|
||||||
var text = 'V2ray<br />';
|
var text = 'Xray<br />';
|
||||||
if (data["global_status"])
|
if (data["global_status"])
|
||||||
text += '<span class="green"><%:RUNNING%></span>';
|
text += '<span class="green"><%:RUNNING%></span>';
|
||||||
else
|
else
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
<%+cbi/valueheader%>
|
<%+cbi/valueheader%>
|
||||||
<%
|
<%
|
||||||
local api = require "luci.passwall2.api"
|
local api = require "luci.passwall2.api"
|
||||||
local has_v2ray = api.is_finded("v2ray")
|
|
||||||
local has_xray = api.is_finded("xray")
|
local has_xray = api.is_finded("xray")
|
||||||
-%>
|
-%>
|
||||||
<script type="text/javascript">//<![CDATA[
|
<script type="text/javascript">//<![CDATA[
|
||||||
@ -141,7 +140,7 @@ local has_xray = api.is_finded("xray")
|
|||||||
} else if (v_type === "Hysteria") {
|
} else if (v_type === "Hysteria") {
|
||||||
dom_prefix = "hysteria_"
|
dom_prefix = "hysteria_"
|
||||||
protocol = "hysteria"
|
protocol = "hysteria"
|
||||||
} else if (v_type === "V2ray" || v_type === "Xray") {
|
} else if (v_type === "Xray") {
|
||||||
dom_prefix = "xray_"
|
dom_prefix = "xray_"
|
||||||
}
|
}
|
||||||
var _address = ""
|
var _address = ""
|
||||||
@ -230,7 +229,7 @@ local has_xray = api.is_finded("xray")
|
|||||||
"&protoparam=" + b64encsafe(v_protocol_param.value) +
|
"&protoparam=" + b64encsafe(v_protocol_param.value) +
|
||||||
"&remarks=" + b64encutf8safe(v_alias.value);
|
"&remarks=" + b64encutf8safe(v_alias.value);
|
||||||
url = b64encsafe(ssr_str);
|
url = b64encsafe(ssr_str);
|
||||||
} else if ((v_type === "V2ray" || v_type === "Xray") && opt.get(dom_prefix + "protocol").value === "vmess") {
|
} else if (v_type === "Xray" && opt.get(dom_prefix + "protocol").value === "vmess") {
|
||||||
protocol = "vmess";
|
protocol = "vmess";
|
||||||
var info = {};
|
var info = {};
|
||||||
info.v = "2";
|
info.v = "2";
|
||||||
@ -275,7 +274,7 @@ local has_xray = api.is_finded("xray")
|
|||||||
info.sni = opt.get(dom_prefix + "tls_serverName").value;
|
info.sni = opt.get(dom_prefix + "tls_serverName").value;
|
||||||
}
|
}
|
||||||
url = b64EncodeUnicode(JSON.stringify(info));
|
url = b64EncodeUnicode(JSON.stringify(info));
|
||||||
} else if ((v_type === "V2ray" || v_type === "Xray") && opt.get(dom_prefix + "protocol").value === "vless") {
|
} else if (v_type === "Xray" && opt.get(dom_prefix + "protocol").value === "vless") {
|
||||||
protocol = "vless";
|
protocol = "vless";
|
||||||
var v_password = opt.get(dom_prefix + "uuid");
|
var v_password = opt.get(dom_prefix + "uuid");
|
||||||
var v_port = opt.get(dom_prefix + "port");
|
var v_port = opt.get(dom_prefix + "port");
|
||||||
@ -328,8 +327,8 @@ local has_xray = api.is_finded("xray")
|
|||||||
params += opt.query("sid", "reality_shortId");
|
params += opt.query("sid", "reality_shortId");
|
||||||
params += opt.query("spx", "reality_spiderX");
|
params += opt.query("spx", "reality_spiderX");
|
||||||
}
|
}
|
||||||
if (opt.get(dom_prefix + "tlsflow") && opt.get(dom_prefix + "tlsflow").value) {
|
if (opt.get(dom_prefix + "flow") && opt.get(dom_prefix + "flow").value) {
|
||||||
let v_flow = opt.get(dom_prefix + "tlsflow").value;
|
let v_flow = opt.get(dom_prefix + "flow").value;
|
||||||
params += "&flow=" + v_flow;
|
params += "&flow=" + v_flow;
|
||||||
}
|
}
|
||||||
params += "&security=" + v_security;
|
params += "&security=" + v_security;
|
||||||
@ -341,7 +340,7 @@ local has_xray = api.is_finded("xray")
|
|||||||
params = params.substring(1);
|
params = params.substring(1);
|
||||||
}
|
}
|
||||||
url += params;
|
url += params;
|
||||||
} else if (((v_type === "V2ray" || v_type === "Xray") && opt.get(dom_prefix + "protocol").value === "trojan")) {
|
} else if ((v_type === "Xray" && opt.get(dom_prefix + "protocol").value === "trojan")) {
|
||||||
protocol = "trojan";
|
protocol = "trojan";
|
||||||
var v_password = opt.get(dom_prefix + "password");
|
var v_password = opt.get(dom_prefix + "password");
|
||||||
var v_port = opt.get(dom_prefix + "port");
|
var v_port = opt.get(dom_prefix + "port");
|
||||||
@ -649,9 +648,7 @@ local has_xray = api.is_finded("xray")
|
|||||||
queryParam[decodeURIComponent(params[0]).toLowerCase()] = decodeURIComponent(params[1] || '');
|
queryParam[decodeURIComponent(params[0]).toLowerCase()] = decodeURIComponent(params[1] || '');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
<% if has_v2ray then %>
|
<% if has_xray then %>
|
||||||
opt.set('type', "V2ray");
|
|
||||||
<% elseif has_xray then %>
|
|
||||||
opt.set('type', "Xray");
|
opt.set('type', "Xray");
|
||||||
<% end %>
|
<% end %>
|
||||||
opt.set(dom_prefix + 'protocol', "trojan");
|
opt.set(dom_prefix + 'protocol', "trojan");
|
||||||
@ -670,9 +667,7 @@ local has_xray = api.is_finded("xray")
|
|||||||
dom_prefix = "xray_"
|
dom_prefix = "xray_"
|
||||||
var sstr = b64DecodeUnicode(ssu[1]);
|
var sstr = b64DecodeUnicode(ssu[1]);
|
||||||
var ploc = sstr.indexOf("/?");
|
var ploc = sstr.indexOf("/?");
|
||||||
<% if has_v2ray then %>
|
<% if has_xray then %>
|
||||||
opt.set('type', "V2ray");
|
|
||||||
<% elseif has_xray then %>
|
|
||||||
opt.set('type', "Xray");
|
opt.set('type', "Xray");
|
||||||
<% end %>
|
<% end %>
|
||||||
opt.set(dom_prefix + 'protocol', "vmess");
|
opt.set(dom_prefix + 'protocol', "vmess");
|
||||||
@ -723,8 +718,6 @@ local has_xray = api.is_finded("xray")
|
|||||||
dom_prefix = "xray_"
|
dom_prefix = "xray_"
|
||||||
<% if has_xray then %>
|
<% if has_xray then %>
|
||||||
opt.set('type', "Xray");
|
opt.set('type', "Xray");
|
||||||
<% elseif has_v2ray then %>
|
|
||||||
opt.set('type', "V2ray");
|
|
||||||
<% end %>
|
<% end %>
|
||||||
opt.set(dom_prefix + 'protocol', "vless");
|
opt.set(dom_prefix + 'protocol', "vless");
|
||||||
var m = parseNodeUrl(ssrurl);
|
var m = parseNodeUrl(ssrurl);
|
||||||
@ -753,7 +746,7 @@ local has_xray = api.is_finded("xray")
|
|||||||
if (queryParam.security == "tls") {
|
if (queryParam.security == "tls") {
|
||||||
opt.set(dom_prefix + 'tls', true);
|
opt.set(dom_prefix + 'tls', true);
|
||||||
opt.set('reality', false)
|
opt.set('reality', false)
|
||||||
opt.set(dom_prefix + 'tlsflow', queryParam.flow || '');
|
opt.set(dom_prefix + 'flow', queryParam.flow || '');
|
||||||
opt.set(dom_prefix + 'tls_serverName', queryParam.sni || '');
|
opt.set(dom_prefix + 'tls_serverName', queryParam.sni || '');
|
||||||
opt.set(dom_prefix + 'tls_allowInsecure', true);
|
opt.set(dom_prefix + 'tls_allowInsecure', true);
|
||||||
if (queryParam.allowinsecure === '0') {
|
if (queryParam.allowinsecure === '0') {
|
||||||
@ -767,7 +760,7 @@ local has_xray = api.is_finded("xray")
|
|||||||
if (queryParam.security == "reality") {
|
if (queryParam.security == "reality") {
|
||||||
opt.set(dom_prefix + 'tls', true);
|
opt.set(dom_prefix + 'tls', true);
|
||||||
opt.set('reality', true)
|
opt.set('reality', true)
|
||||||
opt.set(dom_prefix + 'tlsflow', queryParam.flow || '');
|
opt.set(dom_prefix + 'flow', queryParam.flow || '');
|
||||||
opt.set(dom_prefix + 'tls_serverName', queryParam.sni || '');
|
opt.set(dom_prefix + 'tls_serverName', queryParam.sni || '');
|
||||||
if (queryParam.fp && queryParam.fp.trim() != "") {
|
if (queryParam.fp && queryParam.fp.trim() != "") {
|
||||||
opt.set('reality_fingerprint', queryParam.fp);
|
opt.set('reality_fingerprint', queryParam.fp);
|
||||||
|
@ -8,7 +8,7 @@ local node = api.uci_get_type("global", "node", "nil")
|
|||||||
if node ~= "nil" then
|
if node ~= "nil" then
|
||||||
local node_type = api.uci_get_type_id(node, "type")
|
local node_type = api.uci_get_type_id(node, "type")
|
||||||
local node_protocol = api.uci_get_type_id(node, "protocol")
|
local node_protocol = api.uci_get_type_id(node, "protocol")
|
||||||
if (node_type == "V2ray" or node_type == "Xray") and node_protocol == "_shunt" then
|
if node_type == "Xray" and node_protocol == "_shunt" then
|
||||||
default_node_type = node_protocol
|
default_node_type = node_protocol
|
||||||
uci:foreach("passwall2", "shunt_rules", function(e)
|
uci:foreach("passwall2", "shunt_rules", function(e)
|
||||||
if e[".name"] and e.remarks then
|
if e[".name"] and e.remarks then
|
||||||
|
@ -412,6 +412,9 @@ msgstr "传输层插件"
|
|||||||
msgid "Shadowsocks secondary encryption"
|
msgid "Shadowsocks secondary encryption"
|
||||||
msgstr "Shadowsocks 二次加密"
|
msgstr "Shadowsocks 二次加密"
|
||||||
|
|
||||||
|
msgid "Obfs Type"
|
||||||
|
msgstr "混淆类型"
|
||||||
|
|
||||||
msgid "Obfs Password"
|
msgid "Obfs Password"
|
||||||
msgstr "混淆密码"
|
msgstr "混淆密码"
|
||||||
|
|
||||||
@ -421,6 +424,9 @@ msgstr "认证类型"
|
|||||||
msgid "Auth Password"
|
msgid "Auth Password"
|
||||||
msgstr "认证密码"
|
msgstr "认证密码"
|
||||||
|
|
||||||
|
msgid "Commands the client to use the BBR flow control algorithm"
|
||||||
|
msgstr "命令客户端使用 BBR 流量控制算法"
|
||||||
|
|
||||||
msgid "Max upload Mbps"
|
msgid "Max upload Mbps"
|
||||||
msgstr "最大上行(Mbps)"
|
msgstr "最大上行(Mbps)"
|
||||||
|
|
||||||
@ -433,6 +439,9 @@ msgstr "QUIC 流接收窗口"
|
|||||||
msgid "QUIC connection receive window"
|
msgid "QUIC connection receive window"
|
||||||
msgstr "QUIC 连接接收窗口"
|
msgstr "QUIC 连接接收窗口"
|
||||||
|
|
||||||
|
msgid "QUIC concurrent bidirectional streams"
|
||||||
|
msgstr "QUIC 并发双向流的最大数量"
|
||||||
|
|
||||||
msgid "Disable MTU detection"
|
msgid "Disable MTU detection"
|
||||||
msgstr "禁用 MTU 检测"
|
msgstr "禁用 MTU 检测"
|
||||||
|
|
||||||
@ -694,6 +703,9 @@ msgstr "启用自定义规则地址"
|
|||||||
msgid "Rule status"
|
msgid "Rule status"
|
||||||
msgstr "规则版本"
|
msgstr "规则版本"
|
||||||
|
|
||||||
|
msgid "Manually update"
|
||||||
|
msgstr "手动更新"
|
||||||
|
|
||||||
msgid "Enable auto update rules"
|
msgid "Enable auto update rules"
|
||||||
msgstr "开启自动更新规则"
|
msgstr "开启自动更新规则"
|
||||||
|
|
||||||
@ -946,9 +958,6 @@ msgstr "从文件中加载 IP: 形如'ext:file:tag',必须以ext:(小写)
|
|||||||
msgid "Clear logs"
|
msgid "Clear logs"
|
||||||
msgstr "清空日志"
|
msgstr "清空日志"
|
||||||
|
|
||||||
msgid "Only recommend to use with VLESS-TCP-XTLS-Vision."
|
|
||||||
msgstr "只推荐与 VLESS-TCP-XTLS-Vision 搭配使用。"
|
|
||||||
|
|
||||||
msgid "Password"
|
msgid "Password"
|
||||||
msgstr "密码"
|
msgstr "密码"
|
||||||
|
|
||||||
@ -1003,9 +1012,6 @@ msgstr "使用TLS"
|
|||||||
msgid "Naiveproxy Protocol"
|
msgid "Naiveproxy Protocol"
|
||||||
msgstr "Naiveproxy协议"
|
msgstr "Naiveproxy协议"
|
||||||
|
|
||||||
msgid "V2ray Protocol"
|
|
||||||
msgstr "V2ray协议"
|
|
||||||
|
|
||||||
msgid "User Level"
|
msgid "User Level"
|
||||||
msgstr "用户等级(level)"
|
msgstr "用户等级(level)"
|
||||||
|
|
||||||
@ -1336,9 +1342,15 @@ msgstr "缓冲区大小"
|
|||||||
msgid "Buffer size for every connection (kB)"
|
msgid "Buffer size for every connection (kB)"
|
||||||
msgstr "每一个连接的缓冲区大小(kB)"
|
msgstr "每一个连接的缓冲区大小(kB)"
|
||||||
|
|
||||||
|
msgid "Custom geoip Path"
|
||||||
|
msgstr "自定义geoip文件路径"
|
||||||
|
|
||||||
msgid "Custom geoip URL"
|
msgid "Custom geoip URL"
|
||||||
msgstr "自定义geoip文件更新链接"
|
msgstr "自定义geoip文件更新链接"
|
||||||
|
|
||||||
|
msgid "Custom geosite Path"
|
||||||
|
msgstr "自定义geosite文件路径"
|
||||||
|
|
||||||
msgid "Custom geosite URL"
|
msgid "Custom geosite URL"
|
||||||
msgstr "自定义geosite文件更新链接"
|
msgstr "自定义geosite文件更新链接"
|
||||||
|
|
||||||
@ -1353,3 +1365,9 @@ msgstr "端口跳跃时间 "
|
|||||||
|
|
||||||
msgid "Additional ports for hysteria hop"
|
msgid "Additional ports for hysteria hop"
|
||||||
msgstr "端口跳跃额外端口"
|
msgstr "端口跳跃额外端口"
|
||||||
|
|
||||||
|
msgid "Override the connection destination address"
|
||||||
|
msgstr "覆盖连接目标地址"
|
||||||
|
|
||||||
|
msgid "Override the connection destination address with the sniffed domain."
|
||||||
|
msgstr "用探测出的域名覆盖连接目标地址。"
|
||||||
|
@ -56,6 +56,17 @@ global_xray=$(uci -q get passwall2.@global_xray[0])
|
|||||||
uci -q commit passwall2
|
uci -q commit passwall2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
global_singbox=$(uci -q get passwall2.@global_singbox[0])
|
||||||
|
[ -z "${global_singbox}" ] && {
|
||||||
|
cfgid=$(uci add passwall2 global_singbox)
|
||||||
|
uci -q set passwall2.${cfgid}.sniff_override_destination=1
|
||||||
|
uci -q set passwall2.${cfgid}.geoip_path="/tmp/singbox/geoip.db"
|
||||||
|
uci -q set passwall2.${cfgid}.geoip_url="https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db"
|
||||||
|
uci -q set passwall2.${cfgid}.geosite_path="/tmp/singbox/geosite.db"
|
||||||
|
uci -q set passwall2.${cfgid}.geosite_url="https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db"
|
||||||
|
uci -q commit passwall2
|
||||||
|
}
|
||||||
|
|
||||||
rm -f /tmp/luci-indexcache
|
rm -f /tmp/luci-indexcache
|
||||||
rm -rf /tmp/luci-modulecache/
|
rm -rf /tmp/luci-modulecache/
|
||||||
killall -HUP rpcd 2>/dev/null
|
killall -HUP rpcd 2>/dev/null
|
||||||
|
@ -33,6 +33,8 @@ config global_forwarding
|
|||||||
option use_nft '0'
|
option use_nft '0'
|
||||||
option tcp_proxy_way 'redirect'
|
option tcp_proxy_way 'redirect'
|
||||||
option ipv6_tproxy '0'
|
option ipv6_tproxy '0'
|
||||||
|
|
||||||
|
config global_xray
|
||||||
option sniffing '1'
|
option sniffing '1'
|
||||||
option route_only '0'
|
option route_only '0'
|
||||||
|
|
||||||
@ -46,10 +48,10 @@ config global_rules
|
|||||||
option v2ray_location_asset '/usr/share/v2ray/'
|
option v2ray_location_asset '/usr/share/v2ray/'
|
||||||
|
|
||||||
config global_app
|
config global_app
|
||||||
option v2ray_file '/usr/bin/v2ray'
|
|
||||||
option xray_file '/usr/bin/xray'
|
option xray_file '/usr/bin/xray'
|
||||||
option brook_file '/usr/bin/brook'
|
option brook_file '/usr/bin/brook'
|
||||||
option hysteria_file '/usr/bin/hysteria'
|
option hysteria_file '/usr/bin/hysteria'
|
||||||
|
option singbox_file '/usr/bin/sing-box'
|
||||||
|
|
||||||
config global_subscribe
|
config global_subscribe
|
||||||
option filter_keyword_mode '1'
|
option filter_keyword_mode '1'
|
||||||
@ -58,6 +60,13 @@ config global_subscribe
|
|||||||
list filter_discard_list 'QQ群'
|
list filter_discard_list 'QQ群'
|
||||||
list filter_discard_list '官网'
|
list filter_discard_list '官网'
|
||||||
|
|
||||||
|
config global_singbox
|
||||||
|
option sniff_override_destination '1'
|
||||||
|
option geoip_path '/tmp/singbox/geoip.db'
|
||||||
|
option geoip_url 'https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db'
|
||||||
|
option geosite_path '/tmp/singbox/geosite.db'
|
||||||
|
option geosite_url 'https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db'
|
||||||
|
|
||||||
config nodes 'myshunt'
|
config nodes 'myshunt'
|
||||||
option remarks '分流总节点'
|
option remarks '分流总节点'
|
||||||
option type 'Xray'
|
option type 'Xray'
|
||||||
@ -229,7 +238,7 @@ config shunt_rules 'China'
|
|||||||
|
|
||||||
config shunt_rules 'QUIC'
|
config shunt_rules 'QUIC'
|
||||||
option remarks 'QUIC'
|
option remarks 'QUIC'
|
||||||
option port '80,443'
|
option port '443'
|
||||||
option network 'udp'
|
option network 'udp'
|
||||||
|
|
||||||
config shunt_rules 'UDP'
|
config shunt_rules 'UDP'
|
||||||
|
@ -27,6 +27,7 @@ ENABLED_ACLS=0
|
|||||||
PROXY_IPV6=0
|
PROXY_IPV6=0
|
||||||
PROXY_IPV6_UDP=0
|
PROXY_IPV6_UDP=0
|
||||||
LUA_UTIL_PATH=/usr/lib/lua/luci/passwall2
|
LUA_UTIL_PATH=/usr/lib/lua/luci/passwall2
|
||||||
|
UTIL_SINGBOX=$LUA_UTIL_PATH/util_sing-box.lua
|
||||||
UTIL_SS=$LUA_UTIL_PATH/util_shadowsocks.lua
|
UTIL_SS=$LUA_UTIL_PATH/util_shadowsocks.lua
|
||||||
UTIL_XRAY=$LUA_UTIL_PATH/util_xray.lua
|
UTIL_XRAY=$LUA_UTIL_PATH/util_xray.lua
|
||||||
UTIL_NAIVE=$LUA_UTIL_PATH/util_naiveproxy.lua
|
UTIL_NAIVE=$LUA_UTIL_PATH/util_naiveproxy.lua
|
||||||
@ -283,21 +284,16 @@ lua_api() {
|
|||||||
echo $(lua -e "local api = require 'luci.passwall2.api' print(api.${func})")
|
echo $(lua -e "local api = require 'luci.passwall2.api' print(api.${func})")
|
||||||
}
|
}
|
||||||
|
|
||||||
run_v2ray() {
|
run_xray() {
|
||||||
local flag node redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
|
local flag node redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
|
||||||
local dns_listen_port direct_dns_protocol direct_dns_udp_server direct_dns_tcp_server direct_dns_doh direct_dns_client_ip direct_dns_query_strategy remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_fakedns remote_dns_query_strategy dns_cache
|
local dns_listen_port direct_dns_protocol direct_dns_udp_server direct_dns_tcp_server direct_dns_doh direct_dns_client_ip direct_dns_query_strategy remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_fakedns remote_dns_query_strategy dns_cache
|
||||||
local loglevel log_file config_file
|
local loglevel log_file config_file
|
||||||
local _extra_param=""
|
local _extra_param=""
|
||||||
eval_set_val $@
|
eval_set_val $@
|
||||||
local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
||||||
if [ "$type" != "v2ray" ] && [ "$type" != "xray" ]; then
|
if [ "$type" != "xray" ]; then
|
||||||
local bin=$(first_type $(config_t_get global_app xray_file) xray)
|
local bin=$(first_type $(config_t_get global_app xray_file) xray)
|
||||||
if [ -n "$bin" ]; then
|
[ -n "$bin" ] && type="xray"
|
||||||
type="xray"
|
|
||||||
else
|
|
||||||
bin=$(first_type $(config_t_get global_app v2ray_file) v2ray)
|
|
||||||
[ -n "$bin" ] && type="v2ray"
|
|
||||||
fi
|
|
||||||
fi
|
fi
|
||||||
[ -z "$type" ] && return 1
|
[ -z "$type" ] && return 1
|
||||||
[ -n "$log_file" ] || local log_file="/dev/null"
|
[ -n "$log_file" ] || local log_file="/dev/null"
|
||||||
@ -412,6 +408,162 @@ run_v2ray() {
|
|||||||
ln_run "$(first_type $(config_t_get global_app ${type}_file) ${type})" ${type} $log_file run -c "$config_file"
|
ln_run "$(first_type $(config_t_get global_app ${type}_file) ${type})" ${type} $log_file run -c "$config_file"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
run_singbox() {
|
||||||
|
local flag node redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
|
||||||
|
local dns_listen_port direct_dns_protocol direct_dns_udp_server direct_dns_tcp_server direct_dns_doh direct_dns_client_ip direct_dns_query_strategy remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_dns_client_ip remote_fakedns remote_dns_query_strategy dns_cache
|
||||||
|
local loglevel log_file config_file
|
||||||
|
local _extra_param=""
|
||||||
|
eval_set_val $@
|
||||||
|
local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
||||||
|
[ -z "$type" ] && return 1
|
||||||
|
[ -n "$log_file" ] || local log_file="/dev/null"
|
||||||
|
_extra_param="${_extra_param} -log 1 -logfile ${log_file}"
|
||||||
|
if [ "$log_file" = "/dev/null" ]; then
|
||||||
|
_extra_param="${_extra_param} -log 0"
|
||||||
|
else
|
||||||
|
_extra_param="${_extra_param} -log 1 -logfile ${log_file}"
|
||||||
|
fi
|
||||||
|
[ -z "$loglevel" ] && local loglevel=$(config_t_get global loglevel "warn")
|
||||||
|
[ "$loglevel" = "warning" ] && loglevel="warn"
|
||||||
|
_extra_param="${_extra_param} -loglevel $loglevel"
|
||||||
|
|
||||||
|
_extra_param="${_extra_param} -tags $($(first_type $(config_t_get global_app singbox_file) sing-box) version | grep 'Tags:' | awk '{print $2}')"
|
||||||
|
|
||||||
|
[ -n "$flag" ] && pgrep -af "$TMP_BIN_PATH" | awk -v P1="${flag}" 'BEGIN{IGNORECASE=1}$0~P1{print $1}' | xargs kill -9 >/dev/null 2>&1
|
||||||
|
[ -n "$flag" ] && _extra_param="${_extra_param} -flag $flag"
|
||||||
|
[ -n "$socks_address" ] && _extra_param="${_extra_param} -local_socks_address $socks_address"
|
||||||
|
[ -n "$socks_port" ] && _extra_param="${_extra_param} -local_socks_port $socks_port"
|
||||||
|
[ -n "$socks_username" ] && [ -n "$socks_password" ] && _extra_param="${_extra_param} -local_socks_username $socks_username -local_socks_password $socks_password"
|
||||||
|
[ -n "$http_address" ] && _extra_param="${_extra_param} -local_http_address $http_address"
|
||||||
|
[ -n "$http_port" ] && _extra_param="${_extra_param} -local_http_port $http_port"
|
||||||
|
[ -n "$http_username" ] && [ -n "$http_password" ] && _extra_param="${_extra_param} -local_http_username $http_username -local_http_password $http_password"
|
||||||
|
|
||||||
|
[ -n "$dns_listen_port" ] && {
|
||||||
|
V2RAY_DNS_DIRECT_ARGS="-dns_out_tag direct"
|
||||||
|
V2RAY_DNS_DIRECT_CONFIG="${TMP_PATH}/${flag}_dns_direct.json"
|
||||||
|
V2RAY_DNS_DIRECT_LOG="${TMP_PATH}/${flag}_dns_direct.log"
|
||||||
|
V2RAY_DNS_DIRECT_ARGS="${V2RAY_DNS_DIRECT_ARGS} -log 1 -logfile ${V2RAY_DNS_DIRECT_LOG}"
|
||||||
|
dns_direct_listen_port=$(get_new_port $(expr $dns_listen_port + 1) udp)
|
||||||
|
V2RAY_DNS_DIRECT_ARGS="${V2RAY_DNS_DIRECT_ARGS} -dns_listen_port ${dns_direct_listen_port}"
|
||||||
|
[ "$direct_dns_protocol" = "auto" ] && {
|
||||||
|
direct_dns_protocol="udp"
|
||||||
|
direct_dns_udp_server=${AUTO_DNS}
|
||||||
|
direct_dns_query_strategy="UseIP"
|
||||||
|
}
|
||||||
|
case "$direct_dns_protocol" in
|
||||||
|
udp)
|
||||||
|
local _dns=$(get_first_dns direct_dns_udp_server 53 | sed 's/#/:/g')
|
||||||
|
local _dns_address=$(echo ${_dns} | awk -F ':' '{print $1}')
|
||||||
|
local _dns_port=$(echo ${_dns} | awk -F ':' '{print $2}')
|
||||||
|
V2RAY_DNS_DIRECT_ARGS="${V2RAY_DNS_DIRECT_ARGS} -direct_dns_server ${_dns_address} -direct_dns_port ${_dns_port} -direct_dns_udp_server ${_dns_address}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
[ -n "$direct_dns_query_strategy" ] && V2RAY_DNS_DIRECT_ARGS="${V2RAY_DNS_DIRECT_ARGS} -dns_query_strategy ${direct_dns_query_strategy}"
|
||||||
|
[ -n "$direct_dns_client_ip" ] && V2RAY_DNS_DIRECT_ARGS="${V2RAY_DNS_DIRECT_ARGS} -dns_client_ip ${direct_dns_client_ip}"
|
||||||
|
|
||||||
|
lua $UTIL_SINGBOX gen_dns_config ${V2RAY_DNS_DIRECT_ARGS} > $V2RAY_DNS_DIRECT_CONFIG
|
||||||
|
ln_run "$(first_type $(config_t_get global_app singbox_file) sing-box)" "sing-box" "/dev/null" run -c "$V2RAY_DNS_DIRECT_CONFIG"
|
||||||
|
|
||||||
|
direct_dnsmasq_listen_port=$(get_new_port $(expr $dns_direct_listen_port + 1) udp)
|
||||||
|
local set_flag="${flag}"
|
||||||
|
local direct_ipset_conf=$TMP_PATH/dnsmasq_${flag}_direct.conf
|
||||||
|
[ -n "$(echo ${flag} | grep '^acl')" ] && {
|
||||||
|
direct_ipset_conf=${TMP_ACL_PATH}/${sid}/dnsmasq_${flag}_direct.conf
|
||||||
|
set_flag=$(echo ${flag} | awk -F '_' '{print $2}')
|
||||||
|
}
|
||||||
|
if [ "${nftflag}" = "1" ]; then
|
||||||
|
local direct_nftset="4#inet#fw4#passwall2_${set_flag}_whitelist,6#inet#fw4#passwall2_${set_flag}_whitelist6"
|
||||||
|
else
|
||||||
|
local direct_ipset="passwall2_${set_flag}_whitelist,passwall2_${set_flag}_whitelist6"
|
||||||
|
fi
|
||||||
|
run_ipset_dnsmasq listen_port=${direct_dnsmasq_listen_port} server_dns=127.0.0.1#${dns_direct_listen_port} ipset="${direct_ipset}" nftset="${direct_nftset}" config_file=${direct_ipset_conf}
|
||||||
|
|
||||||
|
_extra_param="${_extra_param} -direct_dns_port ${direct_dnsmasq_listen_port} -direct_dns_udp_server 127.0.0.1 -direct_dns_query_strategy ${direct_dns_query_strategy}"
|
||||||
|
|
||||||
|
:<<eof
|
||||||
|
V2RAY_DNS_REMOTE_ARGS="-dns_out_tag remote"
|
||||||
|
V2RAY_DNS_REMOTE_CONFIG="${TMP_PATH}/${flag}_dns_remote.json"
|
||||||
|
V2RAY_DNS_REMOTE_LOG="${TMP_PATH}/${flag}_dns_remote.log"
|
||||||
|
V2RAY_DNS_REMOTE_ARGS="${V2RAY_DNS_REMOTE_ARGS} -log 1 -logfile ${V2RAY_DNS_REMOTE_LOG}"
|
||||||
|
dns_remote_listen_port=$(get_new_port $(expr $direct_dnsmasq_listen_port + 1) udp)
|
||||||
|
V2RAY_DNS_REMOTE_ARGS="${V2RAY_DNS_REMOTE_ARGS} -dns_listen_port ${dns_remote_listen_port}"
|
||||||
|
case "$remote_dns_protocol" in
|
||||||
|
udp)
|
||||||
|
local _dns=$(get_first_dns remote_dns_udp_server 53 | sed 's/#/:/g')
|
||||||
|
local _dns_address=$(echo ${_dns} | awk -F ':' '{print $1}')
|
||||||
|
local _dns_port=$(echo ${_dns} | awk -F ':' '{print $2}')
|
||||||
|
V2RAY_DNS_REMOTE_ARGS="${V2RAY_DNS_REMOTE_ARGS} -remote_dns_server ${_dns_address} -remote_dns_port ${_dns_port} -remote_dns_udp_server ${_dns_address}"
|
||||||
|
;;
|
||||||
|
tcp)
|
||||||
|
local _dns=$(get_first_dns remote_dns_tcp_server 53 | sed 's/#/:/g')
|
||||||
|
local _dns_address=$(echo ${_dns} | awk -F ':' '{print $1}')
|
||||||
|
local _dns_port=$(echo ${_dns} | awk -F ':' '{print $2}')
|
||||||
|
V2RAY_DNS_REMOTE_ARGS="${V2RAY_DNS_REMOTE_ARGS} -remote_dns_server ${_dns_address} -remote_dns_port ${_dns_port} -remote_dns_tcp_server tcp://${_dns}"
|
||||||
|
;;
|
||||||
|
doh)
|
||||||
|
local _doh_url=$(echo $remote_dns_doh | awk -F ',' '{print $1}')
|
||||||
|
local _doh_host_port=$(lua_api "get_domain_from_url(\"${_doh_url}\")")
|
||||||
|
#local _doh_host_port=$(echo $_doh_url | sed "s/https:\/\///g" | awk -F '/' '{print $1}')
|
||||||
|
local _doh_host=$(echo $_doh_host_port | awk -F ':' '{print $1}')
|
||||||
|
local is_ip=$(lua_api "is_ip(\"${_doh_host}\")")
|
||||||
|
local _doh_port=$(echo $_doh_host_port | awk -F ':' '{print $2}')
|
||||||
|
[ -z "${_doh_port}" ] && _doh_port=443
|
||||||
|
local _doh_bootstrap=$(echo $remote_dns_doh | cut -d ',' -sf 2-)
|
||||||
|
[ "${is_ip}" = "true" ] && _doh_bootstrap=${_doh_host}
|
||||||
|
[ -n "$_doh_bootstrap" ] && V2RAY_DNS_REMOTE_ARGS="${V2RAY_DNS_REMOTE_ARGS} -remote_dns_server ${_doh_bootstrap}"
|
||||||
|
V2RAY_DNS_REMOTE_ARGS="${V2RAY_DNS_REMOTE_ARGS} -remote_dns_port ${_doh_port} -remote_dns_doh_url ${_doh_url} -remote_dns_doh_host ${_doh_host}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
[ -n "$remote_dns_query_strategy" ] && V2RAY_DNS_REMOTE_ARGS="${V2RAY_DNS_REMOTE_ARGS} -dns_query_strategy ${remote_dns_query_strategy}"
|
||||||
|
[ -n "$remote_dns_client_ip" ] && V2RAY_DNS_REMOTE_ARGS="${V2RAY_DNS_REMOTE_ARGS} -dns_client_ip ${remote_dns_client_ip}"
|
||||||
|
|
||||||
|
V2RAY_DNS_REMOTE_ARGS="${V2RAY_DNS_REMOTE_ARGS} -remote_dns_outbound_socks_address 127.0.0.1 -remote_dns_outbound_socks_port ${socks_port}"
|
||||||
|
lua $UTIL_SINGBOX gen_dns_config ${V2RAY_DNS_REMOTE_ARGS} > $V2RAY_DNS_REMOTE_CONFIG
|
||||||
|
ln_run "$(first_type $(config_t_get global_app singbox_file) sing-box)" "sing-box" "/dev/null" run -c "$V2RAY_DNS_REMOTE_CONFIG"
|
||||||
|
|
||||||
|
_extra_param="${_extra_param} -remote_dns_port ${dns_remote_listen_port} -remote_dns_udp_server 127.0.0.1"
|
||||||
|
eof
|
||||||
|
|
||||||
|
case "$remote_dns_protocol" in
|
||||||
|
udp)
|
||||||
|
local _dns=$(get_first_dns remote_dns_udp_server 53 | sed 's/#/:/g')
|
||||||
|
local _dns_address=$(echo ${_dns} | awk -F ':' '{print $1}')
|
||||||
|
local _dns_port=$(echo ${_dns} | awk -F ':' '{print $2}')
|
||||||
|
_extra_param="${_extra_param} -remote_dns_port ${_dns_port} -remote_dns_udp_server ${_dns_address}"
|
||||||
|
;;
|
||||||
|
tcp)
|
||||||
|
local _dns=$(get_first_dns remote_dns_tcp_server 53 | sed 's/#/:/g')
|
||||||
|
local _dns_address=$(echo ${_dns} | awk -F ':' '{print $1}')
|
||||||
|
local _dns_port=$(echo ${_dns} | awk -F ':' '{print $2}')
|
||||||
|
_extra_param="${_extra_param} -remote_dns_server ${_dns_address} -remote_dns_port ${_dns_port} -remote_dns_tcp_server tcp://${_dns}"
|
||||||
|
;;
|
||||||
|
doh)
|
||||||
|
local _doh_url=$(echo $remote_dns_doh | awk -F ',' '{print $1}')
|
||||||
|
local _doh_host_port=$(lua_api "get_domain_from_url(\"${_doh_url}\")")
|
||||||
|
#local _doh_host_port=$(echo $_doh_url | sed "s/https:\/\///g" | awk -F '/' '{print $1}')
|
||||||
|
local _doh_host=$(echo $_doh_host_port | awk -F ':' '{print $1}')
|
||||||
|
local is_ip=$(lua_api "is_ip(\"${_doh_host}\")")
|
||||||
|
local _doh_port=$(echo $_doh_host_port | awk -F ':' '{print $2}')
|
||||||
|
[ -z "${_doh_port}" ] && _doh_port=443
|
||||||
|
local _doh_bootstrap=$(echo $remote_dns_doh | cut -d ',' -sf 2-)
|
||||||
|
[ "${is_ip}" = "true" ] && _doh_bootstrap=${_doh_host}
|
||||||
|
[ -n "$_doh_bootstrap" ] && _extra_param="${_extra_param} -remote_dns_server ${_doh_bootstrap}"
|
||||||
|
_extra_param="${_extra_param} -remote_dns_port ${_doh_port} -remote_dns_doh_url ${_doh_url} -remote_dns_doh_host ${_doh_host}"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
[ -n "$remote_dns_query_strategy" ] && _extra_param="${_extra_param} -remote_dns_query_strategy ${remote_dns_query_strategy}"
|
||||||
|
|
||||||
|
[ -n "$dns_listen_port" ] && _extra_param="${_extra_param} -dns_listen_port ${dns_listen_port}"
|
||||||
|
[ -n "$dns_cache" ] && _extra_param="${_extra_param} -dns_cache ${dns_cache}"
|
||||||
|
[ "$remote_fakedns" = "1" ] && _extra_param="${_extra_param} -remote_dns_fake 1"
|
||||||
|
}
|
||||||
|
|
||||||
|
lua $UTIL_SINGBOX gen_config -node $node -redir_port $redir_port -tcp_proxy_way $tcp_proxy_way ${_extra_param} > $config_file
|
||||||
|
ln_run "$(first_type $(config_t_get global_app singbox_file) sing-box)" "sing-box" "${log_file}" run -c "$config_file"
|
||||||
|
}
|
||||||
|
|
||||||
run_socks() {
|
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
|
||||||
eval_set_val $@
|
eval_set_val $@
|
||||||
@ -444,7 +596,7 @@ run_socks() {
|
|||||||
error_msg="某种原因,此 Socks 服务的相关配置已失联,启动中止!"
|
error_msg="某种原因,此 Socks 服务的相关配置已失联,启动中止!"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ "$type" == "v2ray" ] || [ "$type" == "xray" ]; then
|
if [ "$type" == "sing-box" ] || [ "$type" == "xray" ]; then
|
||||||
local protocol=$(config_n_get $node protocol)
|
local protocol=$(config_n_get $node protocol)
|
||||||
if [ "$protocol" == "_balancing" ] || [ "$protocol" == "_shunt" ] || [ "$protocol" == "_iface" ]; then
|
if [ "$protocol" == "_balancing" ] || [ "$protocol" == "_shunt" ] || [ "$protocol" == "_iface" ]; then
|
||||||
unset error_msg
|
unset error_msg
|
||||||
@ -458,7 +610,15 @@ run_socks() {
|
|||||||
[ "$bind" != "127.0.0.1" ] && echolog " - Socks节点:[$remarks]${tmp},启动 ${bind}:${socks_port}"
|
[ "$bind" != "127.0.0.1" ] && echolog " - Socks节点:[$remarks]${tmp},启动 ${bind}:${socks_port}"
|
||||||
|
|
||||||
case "$type" in
|
case "$type" in
|
||||||
v2ray|\
|
sing-box)
|
||||||
|
[ "$http_port" != "0" ] && {
|
||||||
|
http_flag=1
|
||||||
|
config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g")
|
||||||
|
local _extra_param="-local_http_port $http_port"
|
||||||
|
}
|
||||||
|
lua $UTIL_SINGBOX gen_config -flag SOCKS_$flag -node $node -local_socks_port $socks_port ${_extra_param} > $config_file
|
||||||
|
ln_run "$(first_type $(config_t_get global_app singbox_file) sing-box)" "sing-box" $log_file run -c "$config_file"
|
||||||
|
;;
|
||||||
xray)
|
xray)
|
||||||
[ "$http_port" != "0" ] && {
|
[ "$http_port" != "0" ] && {
|
||||||
http_flag=1
|
http_flag=1
|
||||||
@ -466,7 +626,7 @@ run_socks() {
|
|||||||
local _extra_param="-local_http_port $http_port"
|
local _extra_param="-local_http_port $http_port"
|
||||||
}
|
}
|
||||||
lua $UTIL_XRAY gen_config -flag SOCKS_$flag -node $node -local_socks_port $socks_port ${_extra_param} > $config_file
|
lua $UTIL_XRAY gen_config -flag SOCKS_$flag -node $node -local_socks_port $socks_port ${_extra_param} > $config_file
|
||||||
ln_run "$(first_type $(config_t_get global_app ${type}_file) ${type})" ${type} $log_file run -c "$config_file"
|
ln_run "$(first_type $(config_t_get global_app xray_file) xray)" "xray" $log_file run -c "$config_file"
|
||||||
;;
|
;;
|
||||||
naiveproxy)
|
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
|
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
|
||||||
@ -520,17 +680,19 @@ run_socks() {
|
|||||||
esac
|
esac
|
||||||
|
|
||||||
# http to socks
|
# http to socks
|
||||||
[ -z "$http_flag" ] && [ "$http_port" != "0" ] && [ -n "$http_config_file" ] && [ "$type" != "v2ray" ] && [ "$type" != "xray" ] && [ "$type" != "socks" ] && {
|
[ -z "$http_flag" ] && [ "$http_port" != "0" ] && [ -n "$http_config_file" ] && [ "$type" != "sing-box" ] && [ "$type" != "xray" ] && [ "$type" != "socks" ] && {
|
||||||
local bin=$(first_type $(config_t_get global_app v2ray_file) v2ray)
|
local bin=$(first_type $(config_t_get global_app singbox_file) sing-box)
|
||||||
if [ -n "$bin" ]; then
|
if [ -n "$bin" ]; then
|
||||||
type="v2ray"
|
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"
|
||||||
else
|
else
|
||||||
bin=$(first_type $(config_t_get global_app xray_file) xray)
|
bin=$(first_type $(config_t_get global_app xray_file) xray)
|
||||||
[ -n "$bin" ] && type="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"
|
||||||
fi
|
fi
|
||||||
[ -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"
|
|
||||||
}
|
}
|
||||||
unset http_flag
|
unset http_flag
|
||||||
}
|
}
|
||||||
@ -646,7 +808,8 @@ run_global() {
|
|||||||
node_http_port=$(config_t_get global node_http_port 0)
|
node_http_port=$(config_t_get global node_http_port 0)
|
||||||
[ "$node_http_port" != "0" ] && V2RAY_ARGS="${V2RAY_ARGS} http_port=${node_http_port}"
|
[ "$node_http_port" != "0" ] && V2RAY_ARGS="${V2RAY_ARGS} http_port=${node_http_port}"
|
||||||
|
|
||||||
run_v2ray $V2RAY_ARGS
|
[ "${TYPE}" = "xray" ] && run_xray $V2RAY_ARGS
|
||||||
|
[ "${TYPE}" = "sing-box" ] && run_singbox $V2RAY_ARGS
|
||||||
}
|
}
|
||||||
|
|
||||||
start_socks() {
|
start_socks() {
|
||||||
@ -897,7 +1060,10 @@ acl_app() {
|
|||||||
config_file=$TMP_ACL_PATH/${node}_TCP_UDP_DNS_${redir_port}.json
|
config_file=$TMP_ACL_PATH/${node}_TCP_UDP_DNS_${redir_port}.json
|
||||||
dns_port=$(get_new_port $(expr $dns_port + 1))
|
dns_port=$(get_new_port $(expr $dns_port + 1))
|
||||||
local acl_socks_port=$(get_new_port $(expr $redir_port + $index))
|
local acl_socks_port=$(get_new_port $(expr $redir_port + $index))
|
||||||
run_v2ray flag=acl_$sid node=$node redir_port=$redir_port socks_address=127.0.0.1 socks_port=$acl_socks_port dns_listen_port=${dns_port} direct_dns_protocol=${direct_dns_protocol} direct_dns_udp_server=${direct_dns} direct_dns_tcp_server=${direct_dns} direct_dns_doh="${direct_dns}" direct_dns_client_ip=${direct_dns_client_ip} direct_dns_query_strategy=${direct_dns_query_strategy} remote_dns_protocol=${remote_dns_protocol} remote_dns_tcp_server=${remote_dns} remote_dns_udp_server=${remote_dns} remote_dns_doh="${remote_dns}" remote_dns_client_ip=${remote_dns_client_ip} remote_fakedns=${remote_fakedns} remote_dns_query_strategy=${remote_dns_query_strategy} config_file=${config_file}
|
local run_func
|
||||||
|
[ "${TYPE}" = "xray" ] && run_func="run_xray"
|
||||||
|
[ "${TYPE}" = "sing-box" ] && run_func="run_singbox"
|
||||||
|
${run_func} flag=acl_$sid node=$node redir_port=$redir_port socks_address=127.0.0.1 socks_port=$acl_socks_port dns_listen_port=${dns_port} direct_dns_protocol=${direct_dns_protocol} direct_dns_udp_server=${direct_dns} direct_dns_tcp_server=${direct_dns} direct_dns_doh="${direct_dns}" direct_dns_client_ip=${direct_dns_client_ip} direct_dns_query_strategy=${direct_dns_query_strategy} remote_dns_protocol=${remote_dns_protocol} remote_dns_tcp_server=${remote_dns} remote_dns_udp_server=${remote_dns} remote_dns_doh="${remote_dns}" remote_dns_client_ip=${remote_dns_client_ip} remote_fakedns=${remote_fakedns} remote_dns_query_strategy=${remote_dns_query_strategy} config_file=${config_file}
|
||||||
fi
|
fi
|
||||||
dnsmasq_port=$(get_new_port $(expr $dnsmasq_port + 1))
|
dnsmasq_port=$(get_new_port $(expr $dnsmasq_port + 1))
|
||||||
redirect_dns_port=$dnsmasq_port
|
redirect_dns_port=$dnsmasq_port
|
||||||
|
@ -12,7 +12,7 @@ local arg1 = arg[1]
|
|||||||
local reboot = 0
|
local reboot = 0
|
||||||
local geoip_update = 0
|
local geoip_update = 0
|
||||||
local geosite_update = 0
|
local geosite_update = 0
|
||||||
local v2ray_asset_location = ucic:get_first(name, 'global_rules', "v2ray_location_asset", "/usr/share/v2ray/")
|
local asset_location = ucic:get_first(name, 'global_rules', "v2ray_location_asset", "/usr/share/v2ray/")
|
||||||
|
|
||||||
-- Custom geo file
|
-- Custom geo file
|
||||||
local geoip_api = ucic:get_first(name, 'global_rules', "geoip_url", "https://api.github.com/repos/Loyalsoldier/v2ray-rules-dat/releases/latest")
|
local geoip_api = ucic:get_first(name, 'global_rules', "geoip_url", "https://api.github.com/repos/Loyalsoldier/v2ray-rules-dat/releases/latest")
|
||||||
@ -61,8 +61,8 @@ local function fetch_geoip()
|
|||||||
f:write(content:gsub("geoip.dat", "/tmp/geoip.dat"), "")
|
f:write(content:gsub("geoip.dat", "/tmp/geoip.dat"), "")
|
||||||
f:close()
|
f:close()
|
||||||
|
|
||||||
if nixio.fs.access(v2ray_asset_location .. "geoip.dat") then
|
if nixio.fs.access(asset_location .. "geoip.dat") then
|
||||||
luci.sys.call(string.format("cp -f %s %s", v2ray_asset_location .. "geoip.dat", "/tmp/geoip.dat"))
|
luci.sys.call(string.format("cp -f %s %s", asset_location .. "geoip.dat", "/tmp/geoip.dat"))
|
||||||
if luci.sys.call('sha256sum -c /tmp/geoip.dat.sha256sum > /dev/null 2>&1') == 0 then
|
if luci.sys.call('sha256sum -c /tmp/geoip.dat.sha256sum > /dev/null 2>&1') == 0 then
|
||||||
log("geoip 版本一致,无需更新。")
|
log("geoip 版本一致,无需更新。")
|
||||||
return 1
|
return 1
|
||||||
@ -72,7 +72,7 @@ local function fetch_geoip()
|
|||||||
if v2.name and v2.name == "geoip.dat" then
|
if v2.name and v2.name == "geoip.dat" then
|
||||||
sret = curl(v2.browser_download_url, "/tmp/geoip.dat")
|
sret = curl(v2.browser_download_url, "/tmp/geoip.dat")
|
||||||
if luci.sys.call('sha256sum -c /tmp/geoip.dat.sha256sum > /dev/null 2>&1') == 0 then
|
if luci.sys.call('sha256sum -c /tmp/geoip.dat.sha256sum > /dev/null 2>&1') == 0 then
|
||||||
luci.sys.call(string.format("mkdir -p %s && cp -f %s %s", v2ray_asset_location, "/tmp/geoip.dat", v2ray_asset_location .. "geoip.dat"))
|
luci.sys.call(string.format("mkdir -p %s && cp -f %s %s", asset_location, "/tmp/geoip.dat", asset_location .. "geoip.dat"))
|
||||||
reboot = 1
|
reboot = 1
|
||||||
log("geoip 更新成功。")
|
log("geoip 更新成功。")
|
||||||
return 1
|
return 1
|
||||||
@ -112,8 +112,8 @@ local function fetch_geosite()
|
|||||||
f:write(content:gsub("geosite.dat", "/tmp/geosite.dat"), "")
|
f:write(content:gsub("geosite.dat", "/tmp/geosite.dat"), "")
|
||||||
f:close()
|
f:close()
|
||||||
|
|
||||||
if nixio.fs.access(v2ray_asset_location .. "geosite.dat") then
|
if nixio.fs.access(asset_location .. "geosite.dat") then
|
||||||
luci.sys.call(string.format("cp -f %s %s", v2ray_asset_location .. "geosite.dat", "/tmp/geosite.dat"))
|
luci.sys.call(string.format("cp -f %s %s", asset_location .. "geosite.dat", "/tmp/geosite.dat"))
|
||||||
if luci.sys.call('sha256sum -c /tmp/geosite.dat.sha256sum > /dev/null 2>&1') == 0 then
|
if luci.sys.call('sha256sum -c /tmp/geosite.dat.sha256sum > /dev/null 2>&1') == 0 then
|
||||||
log("geosite 版本一致,无需更新。")
|
log("geosite 版本一致,无需更新。")
|
||||||
return 1
|
return 1
|
||||||
@ -123,7 +123,7 @@ local function fetch_geosite()
|
|||||||
if v2.name and v2.name == "geosite.dat" then
|
if v2.name and v2.name == "geosite.dat" then
|
||||||
sret = curl(v2.browser_download_url, "/tmp/geosite.dat")
|
sret = curl(v2.browser_download_url, "/tmp/geosite.dat")
|
||||||
if luci.sys.call('sha256sum -c /tmp/geosite.dat.sha256sum > /dev/null 2>&1') == 0 then
|
if luci.sys.call('sha256sum -c /tmp/geosite.dat.sha256sum > /dev/null 2>&1') == 0 then
|
||||||
luci.sys.call(string.format("mkdir -p %s && cp -f %s %s", v2ray_asset_location, "/tmp/geosite.dat", v2ray_asset_location .. "geosite.dat"))
|
luci.sys.call(string.format("mkdir -p %s && cp -f %s %s", asset_location, "/tmp/geosite.dat", asset_location .. "geosite.dat"))
|
||||||
reboot = 1
|
reboot = 1
|
||||||
log("geosite 更新成功。")
|
log("geosite 更新成功。")
|
||||||
return 1
|
return 1
|
||||||
|
@ -23,7 +23,7 @@ uci:revert(appname)
|
|||||||
|
|
||||||
local has_ss = api.is_finded("ss-redir")
|
local has_ss = api.is_finded("ss-redir")
|
||||||
local has_ss_rust = api.is_finded("sslocal")
|
local has_ss_rust = api.is_finded("sslocal")
|
||||||
local has_v2ray = api.is_finded("v2ray")
|
local has_singbox = api.is_finded("sing-box")
|
||||||
local has_xray = api.is_finded("xray")
|
local has_xray = api.is_finded("xray")
|
||||||
local allowInsecure_default = true
|
local allowInsecure_default = true
|
||||||
local ss_aead_type_default = uci:get(appname, "@global_subscribe[0]", "ss_aead_type") or "shadowsocks-libev"
|
local ss_aead_type_default = uci:get(appname, "@global_subscribe[0]", "ss_aead_type") or "shadowsocks-libev"
|
||||||
@ -387,10 +387,12 @@ local function processData(szType, content, add_mode, add_from)
|
|||||||
result.remarks = base64Decode(params.remarks)
|
result.remarks = base64Decode(params.remarks)
|
||||||
elseif szType == 'vmess' then
|
elseif szType == 'vmess' then
|
||||||
local info = jsonParse(content)
|
local info = jsonParse(content)
|
||||||
result.type = 'V2ray'
|
|
||||||
if has_xray then
|
if has_xray then
|
||||||
result.type = 'Xray'
|
result.type = 'Xray'
|
||||||
end
|
end
|
||||||
|
if has_singbox then
|
||||||
|
result.type = 'sing-box'
|
||||||
|
end
|
||||||
result.address = info.add
|
result.address = info.add
|
||||||
result.port = info.port
|
result.port = info.port
|
||||||
result.protocol = 'vmess'
|
result.protocol = 'vmess'
|
||||||
@ -532,13 +534,9 @@ local function processData(szType, content, add_mode, add_from)
|
|||||||
if method:lower() == "chacha20-poly1305" then
|
if method:lower() == "chacha20-poly1305" then
|
||||||
result.method = "chacha20-ietf-poly1305"
|
result.method = "chacha20-ietf-poly1305"
|
||||||
end
|
end
|
||||||
elseif ss_aead_type_default == "v2ray" and has_v2ray and not result.plugin then
|
elseif ss_aead_type_default == "sing-box" and has_singbox and not result.plugin then
|
||||||
result.type = 'V2ray'
|
result.type = 'sing-box'
|
||||||
result.protocol = 'shadowsocks'
|
result.protocol = 'shadowsocks'
|
||||||
result.transport = 'tcp'
|
|
||||||
if method:lower() == "chacha20-ietf-poly1305" then
|
|
||||||
result.method = "chacha20-poly1305"
|
|
||||||
end
|
|
||||||
elseif ss_aead_type_default == "xray" and has_xray and not result.plugin then
|
elseif ss_aead_type_default == "xray" and has_xray and not result.plugin then
|
||||||
result.type = 'Xray'
|
result.type = 'Xray'
|
||||||
result.protocol = 'shadowsocks'
|
result.protocol = 'shadowsocks'
|
||||||
@ -557,10 +555,12 @@ local function processData(szType, content, add_mode, add_from)
|
|||||||
content = content:sub(0, idx_sp - 1)
|
content = content:sub(0, idx_sp - 1)
|
||||||
end
|
end
|
||||||
result.remarks = UrlDecode(alias)
|
result.remarks = UrlDecode(alias)
|
||||||
result.type = 'V2ray'
|
|
||||||
if has_xray then
|
if has_xray then
|
||||||
result.type = 'Xray'
|
result.type = 'Xray'
|
||||||
end
|
end
|
||||||
|
if has_singbox then
|
||||||
|
result.type = 'sing-box'
|
||||||
|
end
|
||||||
result.protocol = 'trojan'
|
result.protocol = 'trojan'
|
||||||
if content:find("@") then
|
if content:find("@") then
|
||||||
local Info = split(content, "@")
|
local Info = split(content, "@")
|
||||||
@ -622,10 +622,12 @@ local function processData(szType, content, add_mode, add_from)
|
|||||||
result.group = content.airport
|
result.group = content.airport
|
||||||
result.remarks = content.remarks
|
result.remarks = content.remarks
|
||||||
elseif szType == "vless" then
|
elseif szType == "vless" then
|
||||||
result.type = 'V2ray'
|
|
||||||
if has_xray then
|
if has_xray then
|
||||||
result.type = 'Xray'
|
result.type = 'Xray'
|
||||||
end
|
end
|
||||||
|
if has_singbox then
|
||||||
|
result.type = 'sing-box'
|
||||||
|
end
|
||||||
result.protocol = "vless"
|
result.protocol = "vless"
|
||||||
local alias = ""
|
local alias = ""
|
||||||
if content:find("#") then
|
if content:find("#") then
|
||||||
@ -699,10 +701,11 @@ local function processData(szType, content, add_mode, add_from)
|
|||||||
|
|
||||||
result.encryption = params.encryption or "none"
|
result.encryption = params.encryption or "none"
|
||||||
|
|
||||||
|
result.flow = params.flow or nil
|
||||||
|
|
||||||
result.tls = "0"
|
result.tls = "0"
|
||||||
if params.security == "tls" or params.security == "reality" then
|
if params.security == "tls" or params.security == "reality" then
|
||||||
result.tls = "1"
|
result.tls = "1"
|
||||||
result.tlsflow = params.flow or nil
|
|
||||||
result.tls_serverName = (params.sni and params.sni ~= "") and params.sni or params.host
|
result.tls_serverName = (params.sni and params.sni ~= "") and params.sni or params.host
|
||||||
result.fingerprint = (params.fp and params.fp ~= "") and params.fp or "chrome"
|
result.fingerprint = (params.fp and params.fp ~= "") and params.fp or "chrome"
|
||||||
if params.security == "reality" then
|
if params.security == "reality" then
|
||||||
|
Loading…
Reference in New Issue
Block a user