mirror of
https://github.com/kenzok8/small-package.git
synced 2026-02-06 23:08:07 +08:00
update 2023-09-07 16:21:36
This commit is contained in:
@@ -5,14 +5,14 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=UnblockNeteaseMusic
|
||||
PKG_BASE_VERSION:=0.27.3
|
||||
PKG_BASE_VERSION:=0.27.4
|
||||
PKG_RELEASE:=$(AUTORELEASE)
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/UnblockNeteaseMusic/server.git
|
||||
PKG_SOURCE_DATE:=2022-10-09
|
||||
PKG_SOURCE_VERSION:=253dc89329ebd16ff22175d9d0ab9382ed8aaccc
|
||||
PKG_MIRROR_HASH:=fc8f6bc74530a8583f54980d1e607473778dd8e8d1f4679a028205aaf621b21d
|
||||
PKG_MIRROR_HASH:=8d8868ba077c0abb4e84daf64a78c943c365bbeb96e7052af12aaf1f8e7dcf56
|
||||
|
||||
PKG_VERSION:=$(PKG_BASE_VERSION)-$(PKG_SOURCE_DATE)-$(call version_abbrev,$(PKG_SOURCE_VERSION))
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall
|
||||
PKG_VERSION:=4.69-4
|
||||
PKG_VERSION:=4.70-1
|
||||
PKG_RELEASE:=
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
@@ -23,10 +23,10 @@ PKG_CONFIG_DEPENDS:= \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Client \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_ShadowsocksR_Libev_Server \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_SingBox \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Trojan_GO \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Trojan_Plus \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_tuic_client \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Geodata \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin \
|
||||
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Xray \
|
||||
@@ -50,10 +50,10 @@ 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_Server:shadowsocksr-libev-ssr-server \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs:simple-obfs \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_SingBox:sing-box \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan_GO:trojan-go \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_Trojan_Plus:trojan-plus \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_tuic_client:tuic-client \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray:v2ray-core \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Geodata:v2ray-geoip \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Geodata:v2ray-geosite \
|
||||
+PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Plugin:v2ray-plugin \
|
||||
@@ -136,6 +136,10 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_Simple_Obfs
|
||||
bool "Include Simple-Obfs (Shadowsocks Plugin)"
|
||||
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_Trojan_GO
|
||||
bool "Include Trojan-GO"
|
||||
default n
|
||||
@@ -149,10 +153,6 @@ config PACKAGE_$(PKG_NAME)_INCLUDE_tuic_client
|
||||
depends on aarch64||arm||i386||x86_64
|
||||
default n
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray
|
||||
bool "Include V2ray"
|
||||
default y if aarch64||arm||i386||x86_64
|
||||
|
||||
config PACKAGE_$(PKG_NAME)_INCLUDE_V2ray_Geodata
|
||||
bool "Include V2ray_Geodata"
|
||||
default n
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
local api = require "luci.passwall.api"
|
||||
local appname = api.appname
|
||||
local sys = api.sys
|
||||
local has_v2ray = api.is_finded("v2ray")
|
||||
local has_xray = api.is_finded("xray")
|
||||
local has_singbox = api.finded_com("singbox")
|
||||
local has_xray = api.finded_com("xray")
|
||||
local has_chnlist = api.fs.access("/usr/share/passwall/rules/chnlist")
|
||||
|
||||
m = Map(appname)
|
||||
@@ -232,6 +232,9 @@ o:depends({ tcp_node = "default", ['!reverse'] = true })
|
||||
if api.is_finded("dns2socks") then
|
||||
o:value("dns2socks", "dns2socks")
|
||||
end
|
||||
if has_singbox then
|
||||
o:value("sing-box", "Sing-Box")
|
||||
end
|
||||
if has_xray then
|
||||
o:value("xray", "Xray")
|
||||
end
|
||||
@@ -239,6 +242,7 @@ end
|
||||
o = s:option(ListValue, "v2ray_dns_mode", " ")
|
||||
o:value("tcp", "TCP")
|
||||
o:value("doh", "DoH")
|
||||
o:depends("dns_mode", "sing-box")
|
||||
o:depends("dns_mode", "xray")
|
||||
|
||||
---- DNS Forward
|
||||
@@ -254,7 +258,7 @@ o:value("208.67.222.222", "208.67.222.222 (OpenDNS)")
|
||||
o:depends("dns_mode", "dns2socks")
|
||||
o:depends("v2ray_dns_mode", "tcp")
|
||||
|
||||
if has_v2ray or has_xray then
|
||||
if has_singbox or has_xray then
|
||||
o = s:option(Value, "remote_dns_doh", translate("Remote DNS DoH"))
|
||||
o:value("https://1.1.1.1/dns-query", "CloudFlare")
|
||||
o:value("https://1.1.1.2/dns-query", "CloudFlare-Security")
|
||||
@@ -289,11 +293,14 @@ if has_v2ray or has_xray then
|
||||
return nil, translate("DoH request address") .. " " .. translate("Format must be:") .. " URL,IP"
|
||||
end
|
||||
o:depends("v2ray_dns_mode", "doh")
|
||||
end
|
||||
|
||||
o = s:option(Value, "dns_client_ip", translate("EDNS Client Subnet"))
|
||||
o.datatype = "ipaddr"
|
||||
o:depends("v2ray_dns_mode", "doh")
|
||||
if has_xray then
|
||||
o = s:option(Value, "dns_client_ip", translate("EDNS Client Subnet"))
|
||||
o.datatype = "ipaddr"
|
||||
o:depends({dns_mode = "xray", v2ray_dns_mode = "tcp"})
|
||||
o:depends({dns_mode = "xray", v2ray_dns_mode = "doh"})
|
||||
end
|
||||
end
|
||||
|
||||
if api.is_finded("chinadns-ng") then
|
||||
o = s:option(Flag, "chinadns_ng", translate("ChinaDNS-NG"), translate("The effect is better, but will increase the memory."))
|
||||
|
||||
@@ -2,8 +2,8 @@ local api = require "luci.passwall.api"
|
||||
local appname = api.appname
|
||||
local uci = api.uci
|
||||
local datatypes = api.datatypes
|
||||
local has_v2ray = api.is_finded("v2ray")
|
||||
local has_xray = api.is_finded("xray")
|
||||
local has_singbox = api.finded_com("singbox")
|
||||
local has_xray = api.finded_com("xray")
|
||||
local has_chnlist = api.fs.access("/usr/share/passwall/rules/chnlist")
|
||||
|
||||
m = Map(appname)
|
||||
@@ -94,7 +94,7 @@ udp_node:value("nil", translate("Close"))
|
||||
udp_node:value("tcp", translate("Same as the tcp node"))
|
||||
|
||||
-- 分流
|
||||
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 balancing_list = {}
|
||||
local shunt_list = {}
|
||||
@@ -127,10 +127,10 @@ if (has_v2ray or has_xray) and #nodes_table > 0 then
|
||||
if #normal_list > 0 then
|
||||
for k, v in pairs(shunt_list) do
|
||||
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"))
|
||||
if has_v2ray then
|
||||
type:value("V2ray", translate("V2ray"))
|
||||
if has_singbox then
|
||||
type:value("sing-box", "Sing-Box")
|
||||
end
|
||||
if has_xray then
|
||||
type:value("Xray", translate("Xray"))
|
||||
@@ -159,7 +159,7 @@ if (has_v2ray or has_xray) and #nodes_table > 0 then
|
||||
o.cfgvalue = get_cfgvalue(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("tcp_node", v.id)
|
||||
else
|
||||
type:depends("tcp_node", "hide") --不存在的依赖,即始终隐藏
|
||||
@@ -247,7 +247,7 @@ tcp_node_socks_port.default = 1070
|
||||
tcp_node_socks_port.datatype = "port"
|
||||
tcp_node_socks_port:depends({ tcp_node = "nil", ["!reverse"] = true })
|
||||
--[[
|
||||
if has_v2ray or has_xray then
|
||||
if has_singbox or has_xray then
|
||||
tcp_node_http_port = s:taboption("Main", Value, "tcp_node_http_port", translate("TCP Node") .. " HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use"))
|
||||
tcp_node_http_port.default = 0
|
||||
tcp_node_http_port.datatype = "port"
|
||||
@@ -270,6 +270,9 @@ end
|
||||
if api.is_finded("dns2socks") then
|
||||
dns_mode:value("dns2socks", "dns2socks")
|
||||
end
|
||||
if has_singbox then
|
||||
dns_mode:value("sing-box", "Sing-Box")
|
||||
end
|
||||
if has_xray then
|
||||
dns_mode:value("xray", "Xray")
|
||||
end
|
||||
@@ -279,6 +282,7 @@ o = s:taboption("DNS", ListValue, "v2ray_dns_mode", " ")
|
||||
o:value("tcp", "TCP")
|
||||
o:value("doh", "DoH")
|
||||
o:value("fakedns", "FakeDNS")
|
||||
o:depends("dns_mode", "sing-box")
|
||||
o:depends("dns_mode", "xray")
|
||||
o.validate = function(self, value, t)
|
||||
if value == "fakedns" then
|
||||
@@ -337,12 +341,14 @@ o = s:taboption("DNS", Value, "dns_client_ip", translate("EDNS Client Subnet"))
|
||||
o.description = translate("Notify the DNS server when the DNS query is notified, the location of the client (cannot be a private IP address).") .. "<br />" ..
|
||||
translate("This feature requires the DNS server to support the Edns Client Subnet (RFC7871).")
|
||||
o.datatype = "ipaddr"
|
||||
o:depends("v2ray_dns_mode", "tcp")
|
||||
o:depends("v2ray_dns_mode", "doh")
|
||||
o:depends({dns_mode = "xray", v2ray_dns_mode = "tcp"})
|
||||
o:depends({dns_mode = "xray", v2ray_dns_mode = "doh"})
|
||||
|
||||
o = s:taboption("DNS", Flag, "dns_cache", translate("Cache Resolved"))
|
||||
o.default = "1"
|
||||
o:depends({dns_mode = "dns2socks"})
|
||||
o:depends({dns_mode = "sing-box", v2ray_dns_mode = "tcp"})
|
||||
o:depends({dns_mode = "sing-box", v2ray_dns_mode = "doh"})
|
||||
o:depends({dns_mode = "xray", v2ray_dns_mode = "tcp"})
|
||||
o:depends({dns_mode = "xray", v2ray_dns_mode = "doh"})
|
||||
o.rmempty = false
|
||||
@@ -352,6 +358,8 @@ if api.is_finded("chinadns-ng") then
|
||||
o.default = "0"
|
||||
o:depends({dns_mode = "dns2socks"})
|
||||
o:depends({dns_mode = "dns2tcp"})
|
||||
o:depends({dns_mode = "sing-box", v2ray_dns_mode = "tcp"})
|
||||
o:depends({dns_mode = "sing-box", v2ray_dns_mode = "doh"})
|
||||
o:depends({dns_mode = "xray", v2ray_dns_mode = "tcp"})
|
||||
o:depends({dns_mode = "xray", v2ray_dns_mode = "doh"})
|
||||
o:depends({dns_mode = "udp"})
|
||||
@@ -447,7 +455,7 @@ o.rmempty = false
|
||||
o = s:taboption("log", Flag, "close_log_udp", translatef("%s Node Log Close", "UDP"))
|
||||
o.rmempty = false
|
||||
|
||||
loglevel = s:taboption("log", ListValue, "loglevel", "V2ray/Xray " .. translate("Log Level"))
|
||||
loglevel = s:taboption("log", ListValue, "loglevel", "Sing-Box/Xray " .. translate("Log Level"))
|
||||
loglevel.default = "warning"
|
||||
loglevel:value("debug")
|
||||
loglevel:value("info")
|
||||
@@ -519,7 +527,7 @@ o.default = n + 1080
|
||||
o.datatype = "port"
|
||||
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.default = 0
|
||||
o.datatype = "port"
|
||||
@@ -529,7 +537,7 @@ for k, v in pairs(nodes_table) do
|
||||
tcp_node:value(v.id, v["remark"])
|
||||
udp_node:value(v.id, v["remark"])
|
||||
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"])
|
||||
end
|
||||
else
|
||||
|
||||
@@ -94,7 +94,7 @@ o.cfgvalue = function(t, n)
|
||||
local remarks = m:get(n, "remarks") 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)
|
||||
if type == "V2ray" or type == "Xray" then
|
||||
if type == "sing-box" or type == "Xray" then
|
||||
local protocol = m:get(n, "protocol")
|
||||
if protocol == "_balancing" then
|
||||
protocol = translate("Balancing")
|
||||
|
||||
@@ -3,9 +3,9 @@ local appname = api.appname
|
||||
local has_ss = api.is_finded("ss-redir")
|
||||
local has_ss_rust = api.is_finded("sslocal")
|
||||
local has_trojan_plus = api.is_finded("trojan-plus")
|
||||
local has_v2ray = api.is_finded("v2ray")
|
||||
local has_xray = api.is_finded("xray")
|
||||
local has_trojan_go = api.is_finded("trojan-go")
|
||||
local has_singbox = api.finded_com("singbox")
|
||||
local has_xray = api.finded_com("xray")
|
||||
local has_trojan_go = api.finded_com("trojan-go")
|
||||
local ss_aead_type = {}
|
||||
local trojan_type = {}
|
||||
if has_ss then
|
||||
@@ -17,9 +17,9 @@ end
|
||||
if has_trojan_plus then
|
||||
trojan_type[#trojan_type + 1] = "trojan-plus"
|
||||
end
|
||||
if has_v2ray then
|
||||
trojan_type[#trojan_type + 1] = "v2ray"
|
||||
ss_aead_type[#ss_aead_type + 1] = "v2ray"
|
||||
if has_singbox then
|
||||
trojan_type[#trojan_type + 1] = "sing-box"
|
||||
ss_aead_type[#ss_aead_type + 1] = "sing-box"
|
||||
end
|
||||
if has_xray then
|
||||
trojan_type[#trojan_type + 1] = "xray"
|
||||
|
||||
@@ -4,9 +4,9 @@ local sys = api.sys
|
||||
local has_ss = api.is_finded("ss-redir")
|
||||
local has_ss_rust = api.is_finded("sslocal")
|
||||
local has_trojan_plus = api.is_finded("trojan-plus")
|
||||
local has_v2ray = api.is_finded("v2ray")
|
||||
local has_xray = api.is_finded("xray")
|
||||
local has_trojan_go = api.is_finded("trojan-go")
|
||||
local has_singbox = api.finded_com("singbox")
|
||||
local has_xray = api.finded_com("xray")
|
||||
local has_trojan_go = api.finded_com("trojan-go")
|
||||
local ss_aead_type = {}
|
||||
local trojan_type = {}
|
||||
if has_ss then
|
||||
@@ -18,9 +18,9 @@ end
|
||||
if has_trojan_plus then
|
||||
trojan_type[#trojan_type + 1] = "trojan-plus"
|
||||
end
|
||||
if has_v2ray then
|
||||
trojan_type[#trojan_type + 1] = "v2ray"
|
||||
ss_aead_type[#ss_aead_type + 1] = "v2ray"
|
||||
if has_singbox then
|
||||
trojan_type[#trojan_type + 1] = "sing-box"
|
||||
ss_aead_type[#ss_aead_type + 1] = "sing-box"
|
||||
end
|
||||
if has_xray then
|
||||
trojan_type[#trojan_type + 1] = "xray"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
local api = require "luci.passwall.api"
|
||||
local appname = api.appname
|
||||
local fs = api.fs
|
||||
local has_v2ray = api.is_finded("v2ray")
|
||||
local has_xray = api.is_finded("xray")
|
||||
local has_singbox = api.finded_com("singbox")
|
||||
local has_xray = api.finded_com("xray")
|
||||
local has_fw3 = api.is_finded("fw3")
|
||||
local has_fw4 = api.is_finded("fw4")
|
||||
|
||||
@@ -80,9 +80,9 @@ o:value("disable", translate("No patterns are used"))
|
||||
|
||||
---- UDP Proxy Drop Ports
|
||||
o = s:option(Value, "udp_proxy_drop_ports", translate("UDP Proxy Drop Ports"))
|
||||
o.default = "80,443"
|
||||
o.default = "443"
|
||||
o:value("disable", translate("No patterns are used"))
|
||||
o:value("80,443", translate("QUIC"))
|
||||
o:value("443", translate("QUIC"))
|
||||
|
||||
---- TCP Redir Ports
|
||||
o = s:option(Value, "tcp_redir_ports", translate("TCP Redir Ports"))
|
||||
@@ -140,8 +140,8 @@ o = s:option(Flag, "accept_icmpv6", translate("Hijacking ICMPv6 (IPv6 PING)"))
|
||||
o:depends("ipv6_tproxy", true)
|
||||
o.default = 0
|
||||
|
||||
if has_v2ray or has_xray then
|
||||
s = m:section(TypedSection, "global_xray", "V2Ray/Xray " .. translate("Settings"))
|
||||
if has_xray then
|
||||
s = m:section(TypedSection, "global_xray", "Xray " .. translate("Settings"))
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
|
||||
@@ -171,4 +171,34 @@ if has_v2ray or has_xray then
|
||||
o.datatype = "uinteger"
|
||||
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
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
local api = require "luci.passwall.api"
|
||||
local appname = api.appname
|
||||
local has_v2ray = api.is_finded("v2ray")
|
||||
local has_xray = api.is_finded("xray")
|
||||
local has_xray = api.finded_com("xray")
|
||||
|
||||
m = Map(appname)
|
||||
-- [[ Rule Settings ]]--
|
||||
@@ -61,12 +60,12 @@ for e = 0, 23 do o:value(e, e .. translate("oclock")) end
|
||||
o.default = 0
|
||||
o:depends("auto_update", true)
|
||||
|
||||
if has_v2ray or has_xray then
|
||||
if has_xray then
|
||||
o = s:option(Value, "v2ray_location_asset", translate("Location of V2ray/Xray asset"), translate("This variable specifies a directory where geoip.dat and geosite.dat files are."))
|
||||
o.default = "/usr/share/v2ray/"
|
||||
o.rmempty = false
|
||||
|
||||
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.anonymous = false
|
||||
s.addremove = true
|
||||
|
||||
@@ -2,7 +2,7 @@ local api = require "luci.passwall.api"
|
||||
local appname = api.appname
|
||||
local datatypes = api.datatypes
|
||||
|
||||
m = Map(appname, "V2ray/Xray " .. translate("Shunt Rule"))
|
||||
m = Map(appname, "Xray " .. translate("Shunt Rule"))
|
||||
m.redirect = api.url()
|
||||
|
||||
s = m:section(NamedSection, arg[1], "shunt_rules", "")
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
local api = require "luci.passwall.api"
|
||||
local appname = api.appname
|
||||
local uci = api.uci
|
||||
local has_v2ray = api.is_finded("v2ray")
|
||||
local has_xray = api.is_finded("xray")
|
||||
local has_xray = api.finded_com("xray")
|
||||
|
||||
m = Map(appname)
|
||||
|
||||
@@ -54,7 +53,7 @@ o.default = n + 1080
|
||||
o.datatype = "port"
|
||||
o.rmempty = false
|
||||
|
||||
if has_v2ray or has_xray then
|
||||
if has_xray then
|
||||
o = s:option(Value, "http_port", "HTTP " .. translate("Listen Port") .. " " .. translate("0 is not use"))
|
||||
o.default = 0
|
||||
o.datatype = "port"
|
||||
|
||||
@@ -2,7 +2,7 @@ local m, s = ...
|
||||
|
||||
local api = require "luci.passwall.api"
|
||||
|
||||
if not api.is_finded("brook") then
|
||||
if not api.finded_com("brook") then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ local m, s = ...
|
||||
|
||||
local api = require "luci.passwall.api"
|
||||
|
||||
if not api.is_finded("hysteria") then
|
||||
if not api.finded_com("hysteria") then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
@@ -2,13 +2,15 @@ local m, s = ...
|
||||
|
||||
local api = require "luci.passwall.api"
|
||||
|
||||
if not api.is_finded("xray") and not api.is_finded("v2ray") then
|
||||
if not api.finded_com("xray") then
|
||||
return
|
||||
end
|
||||
|
||||
local appname = api.appname
|
||||
local uci = api.uci
|
||||
|
||||
local type_name = "Xray"
|
||||
|
||||
local option_prefix = "xray_"
|
||||
|
||||
local function option_name(name)
|
||||
@@ -21,52 +23,20 @@ local function rm_prefix_cfgvalue(self, section)
|
||||
end
|
||||
end
|
||||
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
|
||||
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]) == "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
|
||||
m:del(section, self.option:sub(1 + #option_prefix))
|
||||
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 = {
|
||||
"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 ]]
|
||||
|
||||
if api.is_finded("xray") then
|
||||
s.fields["type"]:value("Xray", translate("Xray"))
|
||||
end
|
||||
if api.is_finded("v2ray") then
|
||||
s.fields["type"]:value("V2ray", translate("V2ray"))
|
||||
end
|
||||
s.fields["type"]:value(type_name, "Xray")
|
||||
|
||||
o = s:option(ListValue, option_name("protocol"), translate("Protocol"))
|
||||
o:value("vmess", translate("Vmess"))
|
||||
@@ -97,8 +62,6 @@ o:value("wireguard", translate("WireGuard"))
|
||||
o:value("_balancing", translate("Balancing"))
|
||||
o:value("_shunt", translate("Shunt"))
|
||||
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.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>"))
|
||||
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
|
||||
|
||||
local o = s:option(ListValue, option_name("balancingStrategy"), translate("Balancing Strategy"))
|
||||
add_xray_depends(o, { [option_name("protocol")] = "_balancing" })
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "_balancing" })
|
||||
o:depends({ [option_name("protocol")] = "_balancing" })
|
||||
o:value("random")
|
||||
o:value("leastPing")
|
||||
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."))
|
||||
add_xray_depends(o, { [option_name("balancingStrategy")] = "leastPing" })
|
||||
add_v2ray_depends(o, { [option_name("balancingStrategy")] = "leastPing" })
|
||||
o:depends({ [option_name("balancingStrategy")] = "leastPing" })
|
||||
|
||||
local o = s:option(Value, option_name("probeUrl"), translate("Probe URL"))
|
||||
add_xray_depends(o, { [option_name("useCustomProbeUrl")] = true })
|
||||
add_v2ray_depends(o, { [option_name("useCustomProbeUrl")] = true })
|
||||
o:depends({ [option_name("useCustomProbeUrl")] = true })
|
||||
o.default = "https://www.google.com/generate_204"
|
||||
o.description = translate("The URL used to detect the connection status.")
|
||||
|
||||
-- 探测间隔
|
||||
local o = s:option(Value, option_name("probeInterval"), translate("Probe Interval"))
|
||||
add_xray_depends(o, { [option_name("balancingStrategy")] = "leastPing" })
|
||||
add_v2ray_depends(o, { [option_name("balancingStrategy")] = "leastPing" })
|
||||
o:depends({ [option_name("balancingStrategy")] = "leastPing" })
|
||||
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.")
|
||||
|
||||
@@ -163,11 +121,9 @@ o.description = translate("The interval between initiating probes. Every time th
|
||||
if #nodes_table > 0 then
|
||||
o = s:option(Flag, option_name("preproxy_enabled"), translate("Preproxy"))
|
||||
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: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
|
||||
o:value(v.id, v.remarks)
|
||||
end
|
||||
@@ -187,7 +143,6 @@ uci:foreach(appname, "shunt_rules", function(e)
|
||||
o:value("_direct", translate("Direct Connection"))
|
||||
o:value("_blackhole", translate("Blackhole"))
|
||||
o:depends({ [option_name("protocol")] = "_shunt" })
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "_shunt" })
|
||||
|
||||
if #nodes_table > 0 then
|
||||
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
|
||||
o:value(v.id, v.remarks)
|
||||
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
|
||||
@@ -258,134 +212,88 @@ o:depends({ [option_name("protocol")] = "_shunt" })
|
||||
-- [[ 分流模块 End ]]
|
||||
|
||||
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.datatype = "port"
|
||||
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" })
|
||||
|
||||
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(Value, option_name("username"), translate("Username"))
|
||||
add_xray_depends(o, { [option_name("protocol")] = "http" })
|
||||
add_xray_depends(o, { [option_name("protocol")] = "socks" })
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "http" })
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "socks" })
|
||||
o:depends({ [option_name("protocol")] = "http" })
|
||||
o:depends({ [option_name("protocol")] = "socks" })
|
||||
|
||||
o = s:option(Value, option_name("password"), translate("Password"))
|
||||
o.password = true
|
||||
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_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: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("security"), translate("Encrypt Method"))
|
||||
for a, t in ipairs(security_list) do o:value(t) end
|
||||
add_xray_depends(o, { [option_name("protocol")] = "vmess" })
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "vmess" })
|
||||
o:depends({ [option_name("protocol")] = "vmess" })
|
||||
|
||||
o = s:option(Value, option_name("encryption"), translate("Encrypt Method"))
|
||||
o.default = "none"
|
||||
o:value("none")
|
||||
add_xray_depends(o, { [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:depends({ [option_name("protocol")] = "vless" })
|
||||
|
||||
o = s:option(ListValue, option_name("x_ss_encrypt_method"), translate("Encrypt Method"))
|
||||
o.not_rewrite = true
|
||||
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)
|
||||
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
|
||||
if s.fields["type"]:formvalue(arg[1]) == type_name then
|
||||
m:set(section, "method", value)
|
||||
end
|
||||
end
|
||||
|
||||
o = s:option(Flag, option_name("iv_check"), translate("IV Check"))
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
||||
add_xray_depends(o, { [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-256-gcm" })
|
||||
add_xray_depends(o, { [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")] = "xchacha20-poly1305" })
|
||||
o:depends({ [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" })
|
||||
o:depends({ [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" })
|
||||
|
||||
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" })
|
||||
add_xray_depends(o, { [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-aes-128-gcm" })
|
||||
o:depends({ [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-chacha20-poly1305" })
|
||||
|
||||
o = s:option(Value, option_name("uuid"), translate("ID"))
|
||||
o.password = true
|
||||
add_xray_depends(o, { [option_name("protocol")] = "vmess" })
|
||||
add_xray_depends(o, { [option_name("protocol")] = "vless" })
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "vmess" })
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "vless" })
|
||||
o:depends({ [option_name("protocol")] = "vmess" })
|
||||
o:depends({ [option_name("protocol")] = "vless" })
|
||||
|
||||
o = s:option(Flag, option_name("tls"), translate("TLS"))
|
||||
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 = s:option(ListValue, option_name("flow"), 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, [option_name("transport")] = "tcp" })
|
||||
o:depends({ [option_name("protocol")] = "vless", [option_name("tls")] = true, [option_name("transport")] = "tcp" })
|
||||
|
||||
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 = s:option(Flag, option_name("reality"), translate("REALITY"), translate("Only recommend to use with VLESS-TCP-XTLS-Vision."))
|
||||
o.default = 0
|
||||
add_xray_depends(o, { [option_name("tls")] = true, [option_name("transport")] = "tcp" })
|
||||
add_xray_depends(o, { [option_name("tls")] = true, [option_name("transport")] = "h2" })
|
||||
add_xray_depends(o, { [option_name("tls")] = true, [option_name("transport")] = "grpc" })
|
||||
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.default = "default"
|
||||
@@ -393,72 +301,49 @@ o:value("default", translate("Default"))
|
||||
o:value("h2,http/1.1")
|
||||
o:value("h2")
|
||||
o:value("http/1.1")
|
||||
add_xray_depends(o, { [option_name("tls")] = true, [option_name("reality")] = false })
|
||||
add_v2ray_depends(o, { [option_name("tls")] = true })
|
||||
o:depends({ [option_name("tls")] = true, [option_name("reality")] = false })
|
||||
|
||||
-- o = s:option(Value, option_name("minversion"), translate("minversion"))
|
||||
-- o.default = "1.3"
|
||||
-- o:value("1.3")
|
||||
-- add_xray_depends(o, { [option_name("tls")] = true })
|
||||
-- add_v2ray_depends(o, { [option_name("tls")] = true })
|
||||
-- o:depends({ [option_name("tls")] = true })
|
||||
|
||||
o = s:option(Value, option_name("tls_serverName"), translate("Domain"))
|
||||
add_xray_depends(o, { [option_name("tls")] = true })
|
||||
add_v2ray_depends(o, { [option_name("tls")] = true })
|
||||
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"
|
||||
add_xray_depends(o, { [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 })
|
||||
o:depends({ [option_name("tls")] = true, [option_name("reality")] = false })
|
||||
|
||||
-- [[ REALITY部分 ]] --
|
||||
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"))
|
||||
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.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.not_rewrite = true
|
||||
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("safari")
|
||||
o:value("ios")
|
||||
-- o:value("android")
|
||||
o:value("edge")
|
||||
-- o:value("360")
|
||||
o:value("safari")
|
||||
o:value("360")
|
||||
o:value("qq")
|
||||
o:value("ios")
|
||||
o:value("android")
|
||||
o:value("random")
|
||||
o:value("randomized")
|
||||
o.default = "chrome"
|
||||
add_xray_depends(o, { [option_name("tls")] = true, [option_name("reality")] = true })
|
||||
function o.cfgvalue(self, section)
|
||||
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:depends({ [option_name("tls")] = true, [option_name("utls")] = true })
|
||||
o:depends({ [option_name("tls")] = true, [option_name("reality")] = true })
|
||||
|
||||
o = s:option(ListValue, option_name("transport"), translate("Transport"))
|
||||
o:value("tcp", "TCP")
|
||||
@@ -468,50 +353,44 @@ o:value("h2", "HTTP/2")
|
||||
o:value("ds", "DomainSocket")
|
||||
o:value("quic", "QUIC")
|
||||
o:value("grpc", "gRPC")
|
||||
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" })
|
||||
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: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" })
|
||||
|
||||
--[[
|
||||
o = s:option(ListValue, option_name("ss_transport"), translate("Transport"))
|
||||
o:value("ws", "WebSocket")
|
||||
o:value("h2", "HTTP/2")
|
||||
o:value("h2+ws", "HTTP/2 & WebSocket")
|
||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
||||
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||
]]--
|
||||
|
||||
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"))
|
||||
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"))
|
||||
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"))
|
||||
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.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
|
||||
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
|
||||
|
||||
o = s:option(Value, option_name("wireguard_keepAlive"), translate("Keep Alive"))
|
||||
o.default = "0"
|
||||
add_xray_depends(o, { [option_name("protocol")] = "wireguard" })
|
||||
o:depends({ [option_name("protocol")] = "wireguard" })
|
||||
|
||||
-- [[ TCP部分 ]]--
|
||||
|
||||
@@ -519,194 +398,151 @@ add_xray_depends(o, { [option_name("protocol")] = "wireguard" })
|
||||
o = s:option(ListValue, option_name("tcp_guise"), translate("Camouflage Type"))
|
||||
o:value("none", "none")
|
||||
o:value("http", "http")
|
||||
add_xray_depends(o, { [option_name("transport")] = "tcp" })
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "tcp" })
|
||||
o:depends({ [option_name("transport")] = "tcp" })
|
||||
|
||||
-- HTTP域名
|
||||
o = s:option(DynamicList, option_name("tcp_guise_http_host"), translate("HTTP Host"))
|
||||
add_xray_depends(o, { [option_name("tcp_guise")] = "http" })
|
||||
add_v2ray_depends(o, { [option_name("tcp_guise")] = "http" })
|
||||
o:depends({ [option_name("tcp_guise")] = "http" })
|
||||
|
||||
-- HTTP路径
|
||||
o = s:option(DynamicList, option_name("tcp_guise_http_path"), translate("HTTP Path"))
|
||||
o.placeholder = "/"
|
||||
add_xray_depends(o, { [option_name("tcp_guise")] = "http" })
|
||||
add_v2ray_depends(o, { [option_name("tcp_guise")] = "http" })
|
||||
o:depends({ [option_name("tcp_guise")] = "http" })
|
||||
|
||||
-- [[ 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)'))
|
||||
for a, t in ipairs(header_type_list) do o:value(t) end
|
||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
o:depends({ [option_name("transport")] = "mkcp" })
|
||||
|
||||
o = s:option(Value, option_name("mkcp_mtu"), translate("KCP MTU"))
|
||||
o.default = "1350"
|
||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
o:depends({ [option_name("transport")] = "mkcp" })
|
||||
|
||||
o = s:option(Value, option_name("mkcp_tti"), translate("KCP TTI"))
|
||||
o.default = "20"
|
||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
o:depends({ [option_name("transport")] = "mkcp" })
|
||||
|
||||
o = s:option(Value, option_name("mkcp_uplinkCapacity"), translate("KCP uplinkCapacity"))
|
||||
o.default = "5"
|
||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
o:depends({ [option_name("transport")] = "mkcp" })
|
||||
|
||||
o = s:option(Value, option_name("mkcp_downlinkCapacity"), translate("KCP downlinkCapacity"))
|
||||
o.default = "20"
|
||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
o:depends({ [option_name("transport")] = "mkcp" })
|
||||
|
||||
o = s:option(Flag, option_name("mkcp_congestion"), translate("KCP Congestion"))
|
||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
o:depends({ [option_name("transport")] = "mkcp" })
|
||||
|
||||
o = s:option(Value, option_name("mkcp_readBufferSize"), translate("KCP readBufferSize"))
|
||||
o.default = "1"
|
||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
o:depends({ [option_name("transport")] = "mkcp" })
|
||||
|
||||
o = s:option(Value, option_name("mkcp_writeBufferSize"), translate("KCP writeBufferSize"))
|
||||
o.default = "1"
|
||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
o:depends({ [option_name("transport")] = "mkcp" })
|
||||
|
||||
o = s:option(Value, option_name("mkcp_seed"), translate("KCP Seed"))
|
||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
o:depends({ [option_name("transport")] = "mkcp" })
|
||||
|
||||
-- [[ WebSocket部分 ]]--
|
||||
o = s:option(Value, option_name("ws_host"), translate("WebSocket Host"))
|
||||
add_xray_depends(o, { [option_name("transport")] = "ws" })
|
||||
add_xray_depends(o, { [option_name("ss_transport")] = "ws" })
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "ws" })
|
||||
add_v2ray_depends(o, { [option_name("ss_transport")] = "ws" })
|
||||
o:depends({ [option_name("transport")] = "ws" })
|
||||
o:depends({ [option_name("ss_transport")] = "ws" })
|
||||
|
||||
o = s:option(Value, option_name("ws_path"), translate("WebSocket Path"))
|
||||
o.placeholder = "/"
|
||||
add_xray_depends(o, { [option_name("transport")] = "ws" })
|
||||
add_xray_depends(o, { [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 })
|
||||
o:depends({ [option_name("transport")] = "ws" })
|
||||
o:depends({ [option_name("ss_transport")] = "ws" })
|
||||
|
||||
-- [[ HTTP/2部分 ]]--
|
||||
o = s:option(Value, option_name("h2_host"), translate("HTTP/2 Host"))
|
||||
add_xray_depends(o, { [option_name("transport")] = "h2" })
|
||||
add_xray_depends(o, { [option_name("ss_transport")] = "h2" })
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "h2" })
|
||||
add_v2ray_depends(o, { [option_name("ss_transport")] = "h2" })
|
||||
o:depends({ [option_name("transport")] = "h2" })
|
||||
o:depends({ [option_name("ss_transport")] = "h2" })
|
||||
|
||||
o = s:option(Value, option_name("h2_path"), translate("HTTP/2 Path"))
|
||||
o.placeholder = "/"
|
||||
add_xray_depends(o, { [option_name("transport")] = "h2" })
|
||||
add_xray_depends(o, { [option_name("ss_transport")] = "h2" })
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "h2" })
|
||||
add_v2ray_depends(o, { [option_name("ss_transport")] = "h2" })
|
||||
o:depends({ [option_name("transport")] = "h2" })
|
||||
o:depends({ [option_name("ss_transport")] = "h2" })
|
||||
|
||||
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.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.default = "15"
|
||||
add_xray_depends(o, { [option_name("h2_health_check")] = true })
|
||||
o:depends({ [option_name("h2_health_check")] = true })
|
||||
|
||||
-- [[ DomainSocket部分 ]]--
|
||||
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" })
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "ds" })
|
||||
o:depends({ [option_name("transport")] = "ds" })
|
||||
|
||||
-- [[ QUIC部分 ]]--
|
||||
o = s:option(ListValue, option_name("quic_security"), translate("Encrypt Method"))
|
||||
o:value("none")
|
||||
o:value("aes-128-gcm")
|
||||
o:value("chacha20-poly1305")
|
||||
add_xray_depends(o, { [option_name("transport")] = "quic" })
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "quic" })
|
||||
o:depends({ [option_name("transport")] = "quic" })
|
||||
|
||||
o = s:option(Value, option_name("quic_key"), translate("Encrypt Method") .. translate("Key"))
|
||||
add_xray_depends(o, { [option_name("transport")] = "quic" })
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "quic" })
|
||||
o:depends({ [option_name("transport")] = "quic" })
|
||||
|
||||
o = s:option(ListValue, option_name("quic_guise"), translate("Camouflage Type"))
|
||||
for a, t in ipairs(header_type_list) do o:value(t) end
|
||||
add_xray_depends(o, { [option_name("transport")] = "quic" })
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "quic" })
|
||||
o:depends({ [option_name("transport")] = "quic" })
|
||||
|
||||
-- [[ gRPC部分 ]]--
|
||||
o = s:option(Value, option_name("grpc_serviceName"), "ServiceName")
|
||||
add_xray_depends(o, { [option_name("transport")] = "grpc" })
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "grpc" })
|
||||
o:depends({ [option_name("transport")] = "grpc" })
|
||||
|
||||
o = s:option(ListValue, option_name("grpc_mode"), "gRPC " .. translate("Transfer mode"))
|
||||
o:value("gun")
|
||||
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"))
|
||||
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.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.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.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.default = "0"
|
||||
add_xray_depends(o, { [option_name("transport")] = "grpc" })
|
||||
o:depends({ [option_name("transport")] = "grpc" })
|
||||
|
||||
-- [[ Mux ]]--
|
||||
o = s:option(Flag, option_name("mux"), translate("Mux"))
|
||||
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" })
|
||||
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: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(Value, option_name("mux_concurrency"), translate("Mux concurrency"))
|
||||
o.default = 8
|
||||
add_xray_depends(o, { [option_name("mux")] = true })
|
||||
add_v2ray_depends(o, { [option_name("mux")] = true })
|
||||
o:depends({ [option_name("mux")] = true })
|
||||
|
||||
-- [[ XUDP Mux ]]--
|
||||
o = s:option(Flag, option_name("xmux"), translate("xMux"))
|
||||
o.default = 1
|
||||
add_xray_depends(o, { [option_name("protocol")] = "vless", [option_name("tlsflow")] = "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" })
|
||||
|
||||
o = s:option(Value, option_name("xudp_concurrency"), translate("XUDP Mux concurrency"))
|
||||
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
|
||||
if key:find(option_prefix) == 1 then
|
||||
@@ -715,5 +551,14 @@ for key, value in pairs(s.fields) do
|
||||
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
|
||||
|
||||
@@ -0,0 +1,578 @@
|
||||
local m, s = ...
|
||||
|
||||
local api = require "luci.passwall.api"
|
||||
|
||||
local singbox_bin = api.finded_com("singbox")
|
||||
|
||||
if not singbox_bin then
|
||||
return
|
||||
end
|
||||
|
||||
local singbox_tags = luci.sys.exec(singbox_bin .. " 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, "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" })
|
||||
|
||||
o = s:option(Value, option_name("hysteria_alpn"), translate("QUIC TLS ALPN"))
|
||||
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:depends({ [option_name("protocol")] = "hysteria"})
|
||||
o:depends({ [option_name("protocol")] = "tuic" })
|
||||
o:depends({ [option_name("protocol")] = "hysteria2" })
|
||||
|
||||
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 })
|
||||
o:depends({ [option_name("protocol")] = "hysteria"})
|
||||
o:depends({ [option_name("protocol")] = "tuic" })
|
||||
o:depends({ [option_name("protocol")] = "hysteria2" })
|
||||
|
||||
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
|
||||
@@ -37,7 +37,7 @@ end
|
||||
local ssrust_encrypt_method_list = {
|
||||
"plain", "none",
|
||||
"aes-128-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
|
||||
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha8-poly1305", "2022-blake3-chacha20-poly1305"
|
||||
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
||||
}
|
||||
|
||||
-- [[ Shadowsocks Rust ]]
|
||||
|
||||
@@ -2,7 +2,7 @@ local m, s = ...
|
||||
|
||||
local api = require "luci.passwall.api"
|
||||
|
||||
if not api.is_finded("trojan-go") then
|
||||
if not api.finded_com("trojan-go") then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
@@ -45,15 +45,8 @@ e = t:option(DummyValue, "type", translate("Type"))
|
||||
e.cfgvalue = function(t, n)
|
||||
local v = Value.cfgvalue(t, n)
|
||||
if v then
|
||||
if v == "V2ray" or v == "Xray" then
|
||||
if v == "sing-box" or v == "Xray" then
|
||||
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
|
||||
end
|
||||
return v
|
||||
|
||||
@@ -2,7 +2,7 @@ local m, s = ...
|
||||
|
||||
local api = require "luci.passwall.api"
|
||||
|
||||
if not api.is_finded("brook") then
|
||||
if not api.finded_com("brook") then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ local m, s = ...
|
||||
|
||||
local api = require "luci.passwall.api"
|
||||
|
||||
if not api.is_finded("hysteria") then
|
||||
if not api.finded_com("hysteria") then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
@@ -2,10 +2,12 @@ local m, s = ...
|
||||
|
||||
local api = require "luci.passwall.api"
|
||||
|
||||
if not api.is_finded("xray") and not api.is_finded("v2ray")then
|
||||
if not api.finded_com("xray") then
|
||||
return
|
||||
end
|
||||
|
||||
local type_name = "Xray"
|
||||
|
||||
local option_prefix = "xray_"
|
||||
|
||||
local function option_name(name)
|
||||
@@ -18,52 +20,20 @@ local function rm_prefix_cfgvalue(self, section)
|
||||
end
|
||||
end
|
||||
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
|
||||
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]) == "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
|
||||
m:del(section, self.option:sub(1 + #option_prefix))
|
||||
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 = {
|
||||
"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 ]]
|
||||
|
||||
if api.is_finded("v2ray") then
|
||||
s.fields["type"]:value("V2ray", translate("V2ray"))
|
||||
end
|
||||
if api.is_finded("xray") then
|
||||
s.fields["type"]:value("Xray", translate("Xray"))
|
||||
end
|
||||
s.fields["type"]:value(type_name, "Xray")
|
||||
|
||||
o = s:option(ListValue, option_name("protocol"), translate("Protocol"))
|
||||
o:value("vmess", "Vmess")
|
||||
@@ -89,13 +54,9 @@ o:value("socks", "Socks")
|
||||
o:value("shadowsocks", "Shadowsocks")
|
||||
o:value("trojan", "Trojan")
|
||||
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.datatype = "port"
|
||||
add_xray_depends(o)
|
||||
add_v2ray_depends(o)
|
||||
|
||||
o = s:option(Flag, option_name("auth"), translate("Auth"))
|
||||
o.validate = function(self, value, t)
|
||||
@@ -108,97 +69,75 @@ o.validate = function(self, value, t)
|
||||
end
|
||||
return value
|
||||
end
|
||||
add_xray_depends(o, { [option_name("protocol")] = "socks" })
|
||||
add_xray_depends(o, { [option_name("protocol")] = "http" })
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "socks" })
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "http" })
|
||||
o:depends({ [option_name("protocol")] = "socks" })
|
||||
o:depends({ [option_name("protocol")] = "http" })
|
||||
|
||||
o = s:option(Value, option_name("username"), translate("Username"))
|
||||
add_xray_depends(o, { [option_name("auth")] = true })
|
||||
add_v2ray_depends(o, { [option_name("auth")] = true })
|
||||
o:depends({ [option_name("auth")] = true })
|
||||
|
||||
o = s:option(Value, option_name("password"), translate("Password"))
|
||||
o.password = true
|
||||
add_xray_depends(o, { [option_name("auth")] = true })
|
||||
add_v2ray_depends(o, { [option_name("auth")] = true })
|
||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
||||
o:depends({ [option_name("auth")] = true })
|
||||
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||
|
||||
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")
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "dokodemo-door" })
|
||||
add_xray_depends(o, { [option_name("protocol")] = "dokodemo-door" })
|
||||
o:depends({ [option_name("protocol")] = "dokodemo-door" })
|
||||
|
||||
o = s:option(Value, option_name("d_address"), translate("Destination address"))
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "dokodemo-door" })
|
||||
add_xray_depends(o, { [option_name("protocol")] = "dokodemo-door" })
|
||||
o:depends({ [option_name("protocol")] = "dokodemo-door" })
|
||||
|
||||
o = s:option(Value, option_name("d_port"), translate("Destination port"))
|
||||
o.datatype = "port"
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "dokodemo-door" })
|
||||
add_xray_depends(o, { [option_name("protocol")] = "dokodemo-door" })
|
||||
o:depends({ [option_name("protocol")] = "dokodemo-door" })
|
||||
|
||||
o = s:option(Value, option_name("decryption"), translate("Encrypt Method"))
|
||||
o.default = "none"
|
||||
add_v2ray_depends(o, { [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:depends({ [option_name("protocol")] = "vless" })
|
||||
|
||||
o = s:option(ListValue, option_name("x_ss_method"), translate("Encrypt Method"))
|
||||
o.not_rewrite = true
|
||||
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)
|
||||
return m:get(section, "method")
|
||||
end
|
||||
function o.write(self, section, value)
|
||||
if s.fields["type"]:formvalue(arg[1]) == "Xray" then
|
||||
if s.fields["type"]:formvalue(arg[1]) == type_name then
|
||||
m:set(section, "method", value)
|
||||
end
|
||||
end
|
||||
|
||||
o = s:option(Flag, option_name("iv_check"), translate("IV Check"))
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
||||
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||
|
||||
o = s:option(ListValue, option_name("ss_network"), translate("Transport"))
|
||||
o.default = "tcp,udp"
|
||||
o:value("tcp", "TCP")
|
||||
o:value("udp", "UDP")
|
||||
o:value("tcp,udp", "TCP,UDP")
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
||||
add_xray_depends(o, { [option_name("protocol")] = "shadowsocks" })
|
||||
o:depends({ [option_name("protocol")] = "shadowsocks" })
|
||||
|
||||
o = s:option(Flag, option_name("udp_forward"), translate("UDP Forward"))
|
||||
o.default = "1"
|
||||
o.rmempty = false
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "socks" })
|
||||
add_xray_depends(o, { [option_name("protocol")] = "socks" })
|
||||
o:depends({ [option_name("protocol")] = "socks" })
|
||||
|
||||
o = s:option(DynamicList, option_name("uuid"), translate("ID") .. "/" .. translate("Password"))
|
||||
for i = 1, 3 do
|
||||
o:value(api.gen_uuid(1))
|
||||
end
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "vmess" })
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "vless" })
|
||||
add_v2ray_depends(o, { [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")] = "trojan" })
|
||||
o:depends({ [option_name("protocol")] = "vmess" })
|
||||
o:depends({ [option_name("protocol")] = "vless" })
|
||||
o:depends({ [option_name("protocol")] = "trojan" })
|
||||
|
||||
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, [option_name("transport")] = "tcp" })
|
||||
|
||||
o = s:option(Flag, option_name("tls"), translate("TLS"))
|
||||
o.default = 0
|
||||
@@ -214,44 +153,29 @@ o.validate = function(self, value, t)
|
||||
return value
|
||||
end
|
||||
end
|
||||
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" })
|
||||
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: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" })
|
||||
|
||||
o = s:option(ListValue, option_name("alpn"), translate("alpn"))
|
||||
o.default = "h2,http/1.1"
|
||||
o:value("h2,http/1.1")
|
||||
o:value("h2")
|
||||
o:value("http/1.1")
|
||||
add_v2ray_depends(o, { [option_name("tls")] = true })
|
||||
add_xray_depends(o, { [option_name("tls")] = true })
|
||||
o:depends({ [option_name("tls")] = true })
|
||||
|
||||
-- o = s:option(Value, option_name("minversion"), translate("minversion"))
|
||||
-- o.default = "1.3"
|
||||
-- o:value("1.3")
|
||||
--add_v2ray_depends(o, { [option_name("tls")] = true })
|
||||
--add_xray_depends(o, { [option_name("tls")] = true })
|
||||
--o:depends({ [option_name("tls")] = true })
|
||||
|
||||
-- [[ 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"
|
||||
add_v2ray_depends(o, { [option_name("tls")] = true })
|
||||
add_xray_depends(o, { [option_name("tls")] = true })
|
||||
o:depends({ [option_name("tls")] = true })
|
||||
o.validate = function(self, value, t)
|
||||
if value and 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.default = m:get(s.section, "tls_keyFile") or "/etc/config/ssl/" .. arg[1] .. ".key"
|
||||
add_v2ray_depends(o, { [option_name("tls")] = true })
|
||||
add_xray_depends(o, { [option_name("tls")] = true })
|
||||
o:depends({ [option_name("tls")] = true })
|
||||
o.validate = function(self, value, t)
|
||||
if value and value ~= "" then
|
||||
if not nixio.fs.access(value) then
|
||||
@@ -286,36 +209,27 @@ o:value("h2", "HTTP/2")
|
||||
o:value("ds", "DomainSocket")
|
||||
o:value("quic", "QUIC")
|
||||
o:value("grpc", "gRPC")
|
||||
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" })
|
||||
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: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" })
|
||||
|
||||
-- [[ WebSocket部分 ]]--
|
||||
|
||||
o = s:option(Value, option_name("ws_host"), translate("WebSocket Host"))
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "ws" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "ws" })
|
||||
o:depends({ [option_name("transport")] = "ws" })
|
||||
|
||||
o = s:option(Value, option_name("ws_path"), translate("WebSocket Path"))
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "ws" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "ws" })
|
||||
o:depends({ [option_name("transport")] = "ws" })
|
||||
|
||||
-- [[ HTTP/2部分 ]]--
|
||||
|
||||
o = s:option(Value, option_name("h2_host"), translate("HTTP/2 Host"))
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "h2" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "h2" })
|
||||
o:depends({ [option_name("transport")] = "h2" })
|
||||
|
||||
o = s:option(Value, option_name("h2_path"), translate("HTTP/2 Path"))
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "h2" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "h2" })
|
||||
o:depends({ [option_name("transport")] = "h2" })
|
||||
|
||||
-- [[ 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:value("none", "none")
|
||||
o:value("http", "http")
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "tcp" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "tcp" })
|
||||
o:depends({ [option_name("transport")] = "tcp" })
|
||||
|
||||
-- HTTP域名
|
||||
o = s:option(DynamicList, option_name("tcp_guise_http_host"), translate("HTTP Host"))
|
||||
add_v2ray_depends(o, { [option_name("tcp_guise")] = "http" })
|
||||
add_xray_depends(o, { [option_name("tcp_guise")] = "http" })
|
||||
o:depends({ [option_name("tcp_guise")] = "http" })
|
||||
|
||||
-- HTTP路径
|
||||
o = s:option(DynamicList, option_name("tcp_guise_http_path"), translate("HTTP Path"))
|
||||
add_v2ray_depends(o, { [option_name("tcp_guise")] = "http" })
|
||||
add_xray_depends(o, { [option_name("tcp_guise")] = "http" })
|
||||
o:depends({ [option_name("tcp_guise")] = "http" })
|
||||
|
||||
-- [[ 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)'))
|
||||
for a, t in ipairs(header_type_list) do o:value(t) end
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
o:depends({ [option_name("transport")] = "mkcp" })
|
||||
|
||||
o = s:option(Value, option_name("mkcp_mtu"), translate("KCP MTU"))
|
||||
o.default = "1350"
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
o:depends({ [option_name("transport")] = "mkcp" })
|
||||
|
||||
o = s:option(Value, option_name("mkcp_tti"), translate("KCP TTI"))
|
||||
o.default = "20"
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
o:depends({ [option_name("transport")] = "mkcp" })
|
||||
|
||||
o = s:option(Value, option_name("mkcp_uplinkCapacity"), translate("KCP uplinkCapacity"))
|
||||
o.default = "5"
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
o:depends({ [option_name("transport")] = "mkcp" })
|
||||
|
||||
o = s:option(Value, option_name("mkcp_downlinkCapacity"), translate("KCP downlinkCapacity"))
|
||||
o.default = "20"
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
o:depends({ [option_name("transport")] = "mkcp" })
|
||||
|
||||
o = s:option(Flag, option_name("mkcp_congestion"), translate("KCP Congestion"))
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
o:depends({ [option_name("transport")] = "mkcp" })
|
||||
|
||||
o = s:option(Value, option_name("mkcp_readBufferSize"), translate("KCP readBufferSize"))
|
||||
o.default = "1"
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
o:depends({ [option_name("transport")] = "mkcp" })
|
||||
|
||||
o = s:option(Value, option_name("mkcp_writeBufferSize"), translate("KCP writeBufferSize"))
|
||||
o.default = "1"
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
o:depends({ [option_name("transport")] = "mkcp" })
|
||||
|
||||
o = s:option(Value, option_name("mkcp_seed"), translate("KCP Seed"))
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "mkcp" })
|
||||
o:depends({ [option_name("transport")] = "mkcp" })
|
||||
|
||||
-- [[ DomainSocket部分 ]]--
|
||||
|
||||
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" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "ds" })
|
||||
o:depends({ [option_name("transport")] = "ds" })
|
||||
|
||||
-- [[ QUIC部分 ]]--
|
||||
o = s:option(ListValue, option_name("quic_security"), translate("Encrypt Method"))
|
||||
o:value("none")
|
||||
o:value("aes-128-gcm")
|
||||
o:value("chacha20-poly1305")
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "quic" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "quic" })
|
||||
o:depends({ [option_name("transport")] = "quic" })
|
||||
|
||||
o = s:option(Value, option_name("quic_key"), translate("Encrypt Method") .. translate("Key"))
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "quic" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "quic" })
|
||||
o:depends({ [option_name("transport")] = "quic" })
|
||||
|
||||
o = s:option(ListValue, option_name("quic_guise"), translate("Camouflage Type"))
|
||||
for a, t in ipairs(header_type_list) do o:value(t) end
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "quic" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "quic" })
|
||||
o:depends({ [option_name("transport")] = "quic" })
|
||||
|
||||
-- [[ gRPC部分 ]]--
|
||||
o = s:option(Value, option_name("grpc_serviceName"), "ServiceName")
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "grpc" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "grpc" })
|
||||
o:depends({ [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."))
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "tcp" })
|
||||
add_v2ray_depends(o, { [option_name("transport")] = "ws" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "tcp" })
|
||||
add_xray_depends(o, { [option_name("transport")] = "ws" })
|
||||
o:depends({ [option_name("transport")] = "tcp" })
|
||||
o:depends({ [option_name("transport")] = "ws" })
|
||||
|
||||
-- [[ Fallback部分 ]]--
|
||||
o = s:option(Flag, option_name("fallback"), translate("Fallback"))
|
||||
add_v2ray_depends(o, { [option_name("protocol")] = "vless", [option_name("transport")] = "tcp" })
|
||||
add_v2ray_depends(o, { [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:depends({ [option_name("protocol")] = "vless", [option_name("transport")] = "tcp" })
|
||||
o:depends({ [option_name("protocol")] = "trojan", [option_name("transport")] = "tcp" })
|
||||
|
||||
--[[
|
||||
o = s:option(Value, option_name("fallback_alpn"), "Fallback alpn")
|
||||
add_v2ray_depends(o, { [option_name("fallback")] = true })
|
||||
add_xray_depends(o, { [option_name("fallback")] = true })
|
||||
o:depends({ [option_name("fallback")] = true })
|
||||
|
||||
o = s:option(Value, option_name("fallback_path"), "Fallback path")
|
||||
add_v2ray_depends(o, { [option_name("fallback")] = true })
|
||||
add_xray_depends(o, { [option_name("fallback")] = true })
|
||||
o:depends({ [option_name("fallback")] = true })
|
||||
|
||||
o = s:option(Value, option_name("fallback_dest"), "Fallback dest")
|
||||
add_v2ray_depends(o, { [option_name("fallback")] = true })
|
||||
add_xray_depends(o, { [option_name("fallback")] = true })
|
||||
o:depends({ [option_name("fallback")] = true })
|
||||
|
||||
o = s:option(Value, option_name("fallback_xver"), "Fallback xver")
|
||||
o.default = 0
|
||||
add_v2ray_depends(o, { [option_name("fallback")] = true })
|
||||
add_xray_depends(o, { [option_name("fallback")] = true })
|
||||
o:depends({ [option_name("fallback")] = true })
|
||||
]]--
|
||||
|
||||
o = s:option(DynamicList, option_name("fallback_list"), "Fallback", translate("dest,path"))
|
||||
add_v2ray_depends(o, { [option_name("fallback")] = true })
|
||||
add_xray_depends(o, { [option_name("fallback")] = true })
|
||||
o:depends({ [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.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.default = "0"
|
||||
add_v2ray_depends(o)
|
||||
add_xray_depends(o)
|
||||
|
||||
local nodes_table = {}
|
||||
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] = {
|
||||
id = e[".name"],
|
||||
remarks = e["remark"]
|
||||
@@ -472,45 +356,32 @@ o:value("_http", translate("Custom HTTP"))
|
||||
o:value("_iface", translate("Custom Interface") .. " (Only Support Xray)")
|
||||
for k, v in pairs(nodes_table) do o:value(v.id, v.remarks) end
|
||||
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)"))
|
||||
add_v2ray_depends(o, { [option_name("outbound_node")] = "_socks"})
|
||||
add_v2ray_depends(o, { [option_name("outbound_node")] = "_http"})
|
||||
add_xray_depends(o, { [option_name("outbound_node")] = "_socks"})
|
||||
add_xray_depends(o, { [option_name("outbound_node")] = "_http"})
|
||||
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"
|
||||
add_v2ray_depends(o, { [option_name("outbound_node")] = "_socks"})
|
||||
add_v2ray_depends(o, { [option_name("outbound_node")] = "_http"})
|
||||
add_xray_depends(o, { [option_name("outbound_node")] = "_socks"})
|
||||
add_xray_depends(o, { [option_name("outbound_node")] = "_http"})
|
||||
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"))
|
||||
add_v2ray_depends(o, { [option_name("outbound_node")] = "_socks"})
|
||||
add_v2ray_depends(o, { [option_name("outbound_node")] = "_http"})
|
||||
add_xray_depends(o, { [option_name("outbound_node")] = "_socks"})
|
||||
add_xray_depends(o, { [option_name("outbound_node")] = "_http"})
|
||||
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
|
||||
add_v2ray_depends(o, { [option_name("outbound_node")] = "_socks"})
|
||||
add_v2ray_depends(o, { [option_name("outbound_node")] = "_http"})
|
||||
add_xray_depends(o, { [option_name("outbound_node")] = "_socks"})
|
||||
add_xray_depends(o, { [option_name("outbound_node")] = "_http"})
|
||||
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"
|
||||
add_v2ray_depends(o, { [option_name("outbound_node")] = "_iface"})
|
||||
add_xray_depends(o, { [option_name("outbound_node")] = "_iface"})
|
||||
o:depends({ [option_name("outbound_node")] = "_iface"})
|
||||
|
||||
o = s:option(Flag, option_name("log"), translate("Log"))
|
||||
o.default = "1"
|
||||
o.rmempty = false
|
||||
add_v2ray_depends(o)
|
||||
add_xray_depends(o)
|
||||
|
||||
o = s:option(ListValue, option_name("loglevel"), translate("Log Level"))
|
||||
o.default = "warning"
|
||||
@@ -518,8 +389,7 @@ o:value("debug")
|
||||
o:value("info")
|
||||
o:value("warning")
|
||||
o:value("error")
|
||||
add_v2ray_depends(o, { [option_name("log")] = true })
|
||||
add_xray_depends(o, { [option_name("log")] = true })
|
||||
o:depends({ [option_name("log")] = true })
|
||||
|
||||
for key, value in pairs(s.fields) do
|
||||
if key:find(option_prefix) == 1 then
|
||||
@@ -528,5 +398,14 @@ for key, value in pairs(s.fields) do
|
||||
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
|
||||
|
||||
@@ -0,0 +1,388 @@
|
||||
local m, s = ...
|
||||
|
||||
local api = require "luci.passwall.api"
|
||||
|
||||
local singbox_bin = api.finded_com("singbox")
|
||||
|
||||
if not singbox_bin then
|
||||
return
|
||||
end
|
||||
|
||||
local singbox_tags = luci.sys.exec(singbox_bin .. " 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" })
|
||||
|
||||
o = s:option(Value, option_name("hysteria_alpn"), translate("QUIC TLS ALPN"))
|
||||
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:depends({ [option_name("protocol")] = "hysteria" })
|
||||
o:depends({ [option_name("protocol")] = "tuic" })
|
||||
o:depends({ [option_name("protocol")] = "hysteria2" })
|
||||
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:depends({ [option_name("protocol")] = "hysteria" })
|
||||
o:depends({ [option_name("protocol")] = "tuic" })
|
||||
o:depends({ [option_name("protocol")] = "hysteria2" })
|
||||
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
|
||||
@@ -37,7 +37,7 @@ end
|
||||
local ssrust_encrypt_method_list = {
|
||||
"plain", "none",
|
||||
"aes-128-gcm", "aes-256-gcm", "chacha20-ietf-poly1305",
|
||||
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha8-poly1305", "2022-blake3-chacha20-poly1305"
|
||||
"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"
|
||||
}
|
||||
|
||||
-- [[ Shadowsocks Rust ]]
|
||||
|
||||
@@ -2,7 +2,7 @@ local m, s = ...
|
||||
|
||||
local api = require "luci.passwall.api"
|
||||
|
||||
if not api.is_finded("trojan-go") then
|
||||
if not api.finded_com("trojan-go") then
|
||||
return
|
||||
end
|
||||
|
||||
|
||||
@@ -298,7 +298,7 @@ function get_valid_nodes()
|
||||
local address = e.address
|
||||
if is_ip(address) or datatypes.hostname(address) then
|
||||
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
|
||||
if protocol == "vmess" then
|
||||
protocol = "VMess"
|
||||
@@ -330,7 +330,7 @@ function get_node_remarks(n)
|
||||
remarks = "%s:[%s] " % {n.type .. " " .. i18n.translatef(n.protocol), n.remarks}
|
||||
else
|
||||
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
|
||||
if protocol == "vmess" then
|
||||
protocol = "VMess"
|
||||
@@ -397,8 +397,14 @@ function get_customed_path(e)
|
||||
return uci_get_type("global_app", e .. "_file")
|
||||
end
|
||||
|
||||
function finded_com(e)
|
||||
local bin = get_app_path(e)
|
||||
if not bin then return end
|
||||
return luci.sys.exec('echo -n $(type -t -p "%s" | head -n1)' % { bin })
|
||||
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})
|
||||
return luci.sys.exec('echo -n $(type -t -p "/bin/%s" -p "/usr/bin/%s" "%s" | head -n1)' % {e, e, e})
|
||||
end
|
||||
|
||||
function is_finded(e)
|
||||
@@ -441,10 +447,12 @@ local function get_bin_version_cache(file, cmd)
|
||||
end
|
||||
|
||||
function get_app_path(app_name)
|
||||
local def_path = com[app_name].default_path
|
||||
local path = uci_get_type("global_app", app_name:gsub("%-","_") .. "_file")
|
||||
path = path and (#path>0 and path or def_path) or def_path
|
||||
return path
|
||||
if com[app_name] then
|
||||
local def_path = com[app_name].default_path
|
||||
local path = uci_get_type("global_app", app_name:gsub("%-","_") .. "_file")
|
||||
path = path and (#path>0 and path or def_path) or def_path
|
||||
return path
|
||||
end
|
||||
end
|
||||
|
||||
function get_app_version(app_name, file)
|
||||
@@ -806,12 +814,23 @@ function to_extract(app_name, file, subfix)
|
||||
return {code = 1, error = i18n.translate("File path required.")}
|
||||
end
|
||||
|
||||
if sys.exec("echo -n $(opkg list-installed | grep -c unzip)") ~= "1" then
|
||||
exec("/bin/rm", {"-f", file})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Not installed unzip, Can't unzip!")
|
||||
}
|
||||
local tools_name
|
||||
if com[app_name].zipped then
|
||||
if not com[app_name].zipped_suffix or com[app_name].zipped_suffix == "zip" then
|
||||
tools_name = "unzip"
|
||||
end
|
||||
if com[app_name].zipped_suffix and com[app_name].zipped_suffix == "tar.gz" then
|
||||
tools_name = "tar"
|
||||
end
|
||||
if tools_name then
|
||||
if sys.exec("echo -n $(command -v %s)" % { tools_name }) == "" then
|
||||
exec("/bin/rm", {"-f", file})
|
||||
return {
|
||||
code = 1,
|
||||
error = i18n.translate("Not installed %s, Can't unzip!" % { tools_name })
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
sys.call("/bin/rm -rf /tmp/".. app_name .."_extract.*")
|
||||
@@ -825,8 +844,19 @@ function to_extract(app_name, file, subfix)
|
||||
local tmp_dir = util.trim(util.exec("mktemp -d -t ".. app_name .."_extract.XXXXXX"))
|
||||
|
||||
local output = {}
|
||||
exec("/usr/bin/unzip", {"-o", file, app_name, "-d", tmp_dir},
|
||||
function(chunk) output[#output + 1] = chunk end)
|
||||
|
||||
if tools_name then
|
||||
if tools_name == "unzip" then
|
||||
local bin = sys.exec("echo -n $(command -v unzip)")
|
||||
exec(bin, {"-o", file, app_name, "-d", tmp_dir}, function(chunk) output[#output + 1] = chunk end)
|
||||
elseif tools_name == "tar" then
|
||||
local bin = sys.exec("echo -n $(command -v tar)")
|
||||
if com[app_name].zipped_suffix == "tar.gz" then
|
||||
exec(bin, {"-zxf", file, "-C", tmp_dir}, function(chunk) output[#output + 1] = chunk end)
|
||||
sys.call("/bin/mv -f " .. tmp_dir .. "/*/" .. com[app_name].name:lower() .. " " .. tmp_dir)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local files = util.split(table.concat(output))
|
||||
|
||||
@@ -845,7 +875,7 @@ function to_move(app_name,file)
|
||||
local bin_path = file
|
||||
local cmd_rm_tmp = "/bin/rm -rf /tmp/" .. app_name .. "_download.*"
|
||||
if fs.stat(file, "type") == "dir" then
|
||||
bin_path = file .. "/" .. app_name
|
||||
bin_path = file .. "/" .. com[app_name].name:lower()
|
||||
cmd_rm_tmp = "/bin/rm -rf /tmp/" .. app_name .. "_extract.*"
|
||||
end
|
||||
|
||||
|
||||
@@ -49,19 +49,17 @@ _M["trojan-go"] = {
|
||||
}
|
||||
}
|
||||
|
||||
_M.v2ray = {
|
||||
name = "V2ray",
|
||||
repo = "v2fly/v2ray-core",
|
||||
_M.singbox = {
|
||||
name = "Sing-Box",
|
||||
repo = "SagerNet/sing-box",
|
||||
get_url = gh_pre_release_url,
|
||||
cmd_version = "version | awk '{print $2}' | sed -n 1P",
|
||||
cmd_version = "version | awk '{print $3}' | sed -n 1P",
|
||||
zipped = true,
|
||||
default_path = "/usr/bin/v2ray",
|
||||
zipped_suffix = "tar.gz",
|
||||
default_path = "/usr/bin/sing-box",
|
||||
match_fmt_str = "linux%%-%s",
|
||||
file_tree = {
|
||||
x86_64 = "64",
|
||||
x86 = "32",
|
||||
mips = "mips32",
|
||||
mipsel = "mips32le"
|
||||
x86_64 = "amd64"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,11 +67,16 @@ _M.xray = {
|
||||
name = "Xray",
|
||||
repo = "XTLS/Xray-core",
|
||||
get_url = gh_pre_release_url,
|
||||
cmd_version = _M.v2ray.cmd_version,
|
||||
cmd_version = "version | awk '{print $2}' | sed -n 1P",
|
||||
zipped = true,
|
||||
default_path = "/usr/bin/xray",
|
||||
match_fmt_str = _M.v2ray.match_fmt_str,
|
||||
file_tree = _M.v2ray.file_tree
|
||||
match_fmt_str = "linux%%-%s",
|
||||
file_tree = {
|
||||
x86_64 = "64",
|
||||
x86 = "32",
|
||||
mips = "mips32",
|
||||
mipsel = "mips32le"
|
||||
}
|
||||
}
|
||||
|
||||
_M["chinadns-ng"] = {
|
||||
|
||||
@@ -140,9 +140,9 @@ local function start()
|
||||
elseif type == "SS-Rust" then
|
||||
config = require(require_dir .. "util_shadowsocks").gen_config_server(user)
|
||||
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 == "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 == "Xray" then
|
||||
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)
|
||||
|
||||
1559
luci-app-passwall/luasrc/passwall/util_sing-box.lua
Normal file
1559
luci-app-passwall/luasrc/passwall/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"
|
||||
end
|
||||
|
||||
if node.type == "V2ray" or node.type == "Xray" then
|
||||
if node.type == "Xray" and node.tlsflow == "xtls-rprx-vision" then
|
||||
if node.type == "Xray" then
|
||||
if node.flow == "xtls-rprx-vision" then
|
||||
else
|
||||
proxy = 0
|
||||
if proxy_tag ~= "nil" then
|
||||
@@ -60,7 +60,7 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
end
|
||||
end
|
||||
|
||||
if node.type ~= "V2ray" and node.type ~= "Xray" then
|
||||
if node.type ~= "Xray" then
|
||||
if node.type == "Socks" then
|
||||
node.protocol = "socks"
|
||||
node.transport = "tcp"
|
||||
@@ -91,7 +91,7 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
node.stream_security = "none"
|
||||
end
|
||||
|
||||
if node.type == "V2ray" or node.type == "Xray" then
|
||||
if node.type == "Xray" then
|
||||
if node.tls and node.tls == "1" then
|
||||
node.stream_security = "tls"
|
||||
if node.type == "Xray" and node.reality and node.reality == "1" then
|
||||
@@ -137,7 +137,7 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
tlsSettings = (node.stream_security == "tls") and {
|
||||
serverName = node.tls_serverName,
|
||||
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,
|
||||
realitySettings = (node.stream_security == "reality") and {
|
||||
serverName = node.tls_serverName,
|
||||
@@ -208,7 +208,7 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
level = 0,
|
||||
security = (node.protocol == "vmess") and node.security or nil,
|
||||
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.transport == "tcp" and node.flow and node.flow ~= "") and node.flow or nil
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -271,7 +271,7 @@ function gen_config_server(node)
|
||||
for i = 1, #node.uuid do
|
||||
clients[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 "tcp" == node.transport and node.flow and node.flow ~= "") and node.flow or nil
|
||||
}
|
||||
end
|
||||
settings = {
|
||||
@@ -762,10 +762,10 @@ function gen_config(var)
|
||||
else
|
||||
if proxy then
|
||||
local pre_proxy = nil
|
||||
if _node.type ~= "V2ray" and _node.type ~= "Xray" then
|
||||
if _node.type ~= "Xray" then
|
||||
pre_proxy = true
|
||||
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
|
||||
end
|
||||
if pre_proxy then
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<%+cbi/valueheader%>
|
||||
<%
|
||||
local api = require "luci.passwall.api"
|
||||
local has_v2ray = api.is_finded("v2ray")
|
||||
local has_xray = api.is_finded("xray")
|
||||
local has_singbox = api.finded_com("singbox")
|
||||
local has_xray = api.finded_com("xray")
|
||||
-%>
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
function padright(str, cnt, pad) {
|
||||
@@ -147,8 +147,10 @@ local has_xray = api.is_finded("xray")
|
||||
} else if (v_type === "Hysteria") {
|
||||
dom_prefix = "hysteria_"
|
||||
protocol = "hysteria"
|
||||
} else if (v_type === "V2ray" || v_type === "Xray") {
|
||||
} else if (v_type === "Xray") {
|
||||
dom_prefix = "xray_"
|
||||
} else if (v_type === "sing-box") {
|
||||
dom_prefix = "singbox_"
|
||||
}
|
||||
var _address = ""
|
||||
if (dom_prefix && dom_prefix != null) {
|
||||
@@ -236,7 +238,7 @@ local has_xray = api.is_finded("xray")
|
||||
"&protoparam=" + b64encsafe(v_protocol_param.value) +
|
||||
"&remarks=" + b64encutf8safe(v_alias.value);
|
||||
url = b64encsafe(ssr_str);
|
||||
} else if ((v_type === "V2ray" || v_type === "Xray") && opt.get(dom_prefix + "protocol").value === "vmess") {
|
||||
} else if ((v_type === "sing-box" || v_type === "Xray") && opt.get(dom_prefix + "protocol").value === "vmess") {
|
||||
protocol = "vmess";
|
||||
var info = {};
|
||||
info.v = "2";
|
||||
@@ -281,7 +283,7 @@ local has_xray = api.is_finded("xray")
|
||||
info.sni = opt.get(dom_prefix + "tls_serverName").value;
|
||||
}
|
||||
url = b64EncodeUnicode(JSON.stringify(info));
|
||||
} else if ((v_type === "V2ray" || v_type === "Xray") && opt.get(dom_prefix + "protocol").value === "vless") {
|
||||
} else if ((v_type === "sing-box" || v_type === "Xray") && opt.get(dom_prefix + "protocol").value === "vless") {
|
||||
protocol = "vless";
|
||||
var v_password = opt.get(dom_prefix + "uuid");
|
||||
var v_port = opt.get(dom_prefix + "port");
|
||||
@@ -334,8 +336,8 @@ local has_xray = api.is_finded("xray")
|
||||
params += opt.query("sid", "reality_shortId");
|
||||
params += opt.query("spx", "reality_spiderX");
|
||||
}
|
||||
if (opt.get(dom_prefix + "tlsflow") && opt.get(dom_prefix + "tlsflow").value) {
|
||||
let v_flow = 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 + "flow").value;
|
||||
params += "&flow=" + v_flow;
|
||||
}
|
||||
params += "&security=" + v_security;
|
||||
@@ -404,7 +406,7 @@ local has_xray = api.is_finded("xray")
|
||||
params = params.substring(1);
|
||||
}
|
||||
url += params;
|
||||
} else if (((v_type === "V2ray" || v_type === "Xray") && opt.get(dom_prefix + "protocol").value === "trojan")) {
|
||||
} else if (((v_type === "sing-box" || v_type === "Xray") && opt.get(dom_prefix + "protocol").value === "trojan")) {
|
||||
protocol = "trojan";
|
||||
var v_password = opt.get(dom_prefix + "password");
|
||||
var v_port = opt.get(dom_prefix + "port");
|
||||
@@ -629,7 +631,6 @@ local has_xray = api.is_finded("xray")
|
||||
opt.set('remarks', b64decutf8safe(rem));
|
||||
}
|
||||
if (ssu[0] === "ss") {
|
||||
dom_prefix = "ss_"
|
||||
var url0 = "", param = "";
|
||||
var sipIndex = ssu[1].indexOf("@");
|
||||
var ploc = ssu[1].indexOf("#");
|
||||
@@ -659,11 +660,28 @@ local has_xray = api.is_finded("xray")
|
||||
method = userInfo.substr(0, userInfoSplitIndex);
|
||||
password = userInfo.substr(userInfoSplitIndex + 1);
|
||||
}
|
||||
if (["2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha8-poly1305", "2022-blake3-chacha20-poly1305"].includes(method)) {
|
||||
if (["2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"].includes(method)) {
|
||||
<% if has_singbox then %>
|
||||
opt.set('type', "sing-box");
|
||||
dom_prefix = "singbox_"
|
||||
<% elseif has_xray then %>
|
||||
opt.set('type', "Xray");
|
||||
dom_prefix = "xray_"
|
||||
<% else %>
|
||||
opt.set('type', "SS-Rust");
|
||||
dom_prefix = "ssrust_"
|
||||
<% end %>
|
||||
} else {
|
||||
<% if has_singbox then %>
|
||||
opt.set('type', "sing-box");
|
||||
dom_prefix = "singbox_"
|
||||
<% elseif has_xray then %>
|
||||
opt.set('type', "Xray");
|
||||
dom_prefix = "xray_"
|
||||
<% else %>
|
||||
opt.set('type', "SS");
|
||||
dom_prefix = "ss_"
|
||||
<% end %>
|
||||
}
|
||||
opt.set(dom_prefix + 'address', server);
|
||||
opt.set(dom_prefix + 'port', port);
|
||||
@@ -677,9 +695,18 @@ local has_xray = api.is_finded("xray")
|
||||
opt.set('remarks', decodeURI(param));
|
||||
}
|
||||
} else {
|
||||
<% if has_singbox then %>
|
||||
opt.set('type', "sing-box");
|
||||
dom_prefix = "singbox_"
|
||||
<% elseif has_xray then %>
|
||||
opt.set('type', "Xray");
|
||||
dom_prefix = "xray_"
|
||||
<% else %>
|
||||
opt.set('type', "SS");
|
||||
dom_prefix = "ss_"
|
||||
<% end %>
|
||||
var sstr = b64decsafe(url0);
|
||||
var team = sstr.split('@');
|
||||
opt.set('type', "SS");
|
||||
var part1 = team[0].split(':');
|
||||
var part2 = team[1].split(':');
|
||||
opt.set(dom_prefix + 'address', part2[0]);
|
||||
@@ -694,7 +721,16 @@ local has_xray = api.is_finded("xray")
|
||||
}
|
||||
}
|
||||
if (ssu[0] === "trojan" || ssu[0] === "trojan-plus") {
|
||||
<% if has_singbox then %>
|
||||
opt.set('type', "sing-box");
|
||||
dom_prefix = "singbox_"
|
||||
<% elseif has_xray then %>
|
||||
opt.set('type', "Xray");
|
||||
dom_prefix = "xray_"
|
||||
<% else %>
|
||||
opt.set('type', "Trojan-Plus");
|
||||
dom_prefix = "trojan_plus_"
|
||||
<% end %>
|
||||
var m = parseNodeUrl(ssrurl);
|
||||
var password = m.passwd;
|
||||
if (password === "") {
|
||||
@@ -715,7 +751,6 @@ local has_xray = api.is_finded("xray")
|
||||
if (queryParam.mux || queryParam.ws || queryParam.h2 || queryParam.ss || queryParam.plugin) {
|
||||
ssu[0] = "trojan-go"
|
||||
}
|
||||
opt.set('type', "Trojan-Plus");
|
||||
opt.set(dom_prefix + 'address', m.hostname);
|
||||
opt.set(dom_prefix + 'port', m.port || "443");
|
||||
opt.set(dom_prefix + 'password', decodeURIComponent(password));
|
||||
@@ -801,13 +836,14 @@ local has_xray = api.is_finded("xray")
|
||||
}
|
||||
}
|
||||
if (ssu[0] === "vmess") {
|
||||
dom_prefix = "xray_"
|
||||
var sstr = b64DecodeUnicode(ssu[1]);
|
||||
var ploc = sstr.indexOf("/?");
|
||||
<% if has_v2ray then %>
|
||||
opt.set('type', "V2ray");
|
||||
<% if has_singbox then %>
|
||||
opt.set('type', "sing-box");
|
||||
dom_prefix = "singbox_"
|
||||
<% elseif has_xray then %>
|
||||
opt.set('type', "Xray");
|
||||
dom_prefix = "xray_"
|
||||
<% end %>
|
||||
opt.set(dom_prefix + 'protocol', "vmess");
|
||||
var url0, param = "";
|
||||
@@ -854,11 +890,12 @@ local has_xray = api.is_finded("xray")
|
||||
}
|
||||
}
|
||||
if (ssu[0] === "vless") {
|
||||
dom_prefix = "xray_"
|
||||
<% if has_xray then %>
|
||||
<% if has_singbox then %>
|
||||
opt.set('type', "sing-box");
|
||||
dom_prefix = "singbox_"
|
||||
<% elseif has_xray then %>
|
||||
opt.set('type', "Xray");
|
||||
<% elseif has_v2ray then %>
|
||||
opt.set('type', "V2ray");
|
||||
dom_prefix = "xray_"
|
||||
<% end %>
|
||||
opt.set(dom_prefix + 'protocol', "vless");
|
||||
var m = parseNodeUrl(ssrurl);
|
||||
@@ -887,7 +924,7 @@ local has_xray = api.is_finded("xray")
|
||||
if (queryParam.security == "tls") {
|
||||
opt.set(dom_prefix + 'tls', true);
|
||||
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_allowInsecure', true);
|
||||
if (queryParam.allowinsecure === '0') {
|
||||
@@ -901,7 +938,7 @@ local has_xray = api.is_finded("xray")
|
||||
if (queryParam.security == "reality") {
|
||||
opt.set(dom_prefix + 'tls', 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 || '');
|
||||
if (queryParam.fp && queryParam.fp.trim() != "") {
|
||||
opt.set('reality_fingerprint', queryParam.fp);
|
||||
@@ -1003,8 +1040,13 @@ local has_xray = api.is_finded("xray")
|
||||
}
|
||||
}
|
||||
if (ssu[0] === "hysteria") {
|
||||
<% if has_singbox then %>
|
||||
opt.set('type', "sing-box");
|
||||
dom_prefix = "singbox_"
|
||||
<% else %>
|
||||
opt.set('type', "Hysteria");
|
||||
dom_prefix = "hysteria_"
|
||||
var stype = "Hysteria";
|
||||
<% end %>
|
||||
var m = parseNodeUrl(ssrurl);
|
||||
var queryParam = {};
|
||||
if (m.search.length > 1) {
|
||||
@@ -1017,7 +1059,6 @@ local has_xray = api.is_finded("xray")
|
||||
queryParam[decodeURIComponent(params[0])] = decodeURIComponent(params[1] || '');
|
||||
}
|
||||
}
|
||||
opt.set('type', stype);
|
||||
opt.set(dom_prefix + 'address', m.hostname);
|
||||
opt.set(dom_prefix + 'port', m.port || "443");
|
||||
opt.set(dom_prefix + 'protocol', queryParam.protocol);
|
||||
|
||||
@@ -481,6 +481,9 @@ msgstr "传输层插件"
|
||||
msgid "Shadowsocks secondary encryption"
|
||||
msgstr "Shadowsocks 二次加密"
|
||||
|
||||
msgid "Obfs Type"
|
||||
msgstr "混淆类型"
|
||||
|
||||
msgid "Obfs Password"
|
||||
msgstr "混淆密码"
|
||||
|
||||
@@ -490,6 +493,9 @@ msgstr "认证类型"
|
||||
msgid "Auth Password"
|
||||
msgstr "认证密码"
|
||||
|
||||
msgid "Commands the client to use the BBR flow control algorithm"
|
||||
msgstr "命令客户端使用 BBR 流量控制算法"
|
||||
|
||||
msgid "Max upload Mbps"
|
||||
msgstr "最大上行(Mbps)"
|
||||
|
||||
@@ -502,6 +508,9 @@ msgstr "QUIC 流接收窗口"
|
||||
msgid "QUIC connection receive window"
|
||||
msgstr "QUIC 连接接收窗口"
|
||||
|
||||
msgid "QUIC concurrent bidirectional streams"
|
||||
msgstr "QUIC 并发双向流的最大数量"
|
||||
|
||||
msgid "Disable MTU detection"
|
||||
msgstr "禁用 MTU 检测"
|
||||
|
||||
@@ -1363,8 +1372,8 @@ msgstr "无"
|
||||
msgid "You did not fill in the %s path. Please save and apply then update manually."
|
||||
msgstr "您没有填写 %s 路径。请保存应用后再手动更新。"
|
||||
|
||||
msgid "Not installed unzip, Can't unzip!"
|
||||
msgstr "未安装unzip,无法解压。"
|
||||
msgid "Not installed %s, Can't unzip!"
|
||||
msgstr "未安装 %s,无法解压!"
|
||||
|
||||
msgid "Can't determine ARCH, or ARCH not supported."
|
||||
msgstr "无法确认ARCH架构,或是不支持。"
|
||||
@@ -1458,3 +1467,21 @@ msgstr "端口跳跃时间 "
|
||||
|
||||
msgid "Additional ports for hysteria hop"
|
||||
msgstr "端口跳跃额外端口"
|
||||
|
||||
msgid "Custom geoip Path"
|
||||
msgstr "自定义geoip文件路径"
|
||||
|
||||
msgid "Custom geoip URL"
|
||||
msgstr "自定义geoip文件更新链接"
|
||||
|
||||
msgid "Custom geosite Path"
|
||||
msgstr "自定义geosite文件路径"
|
||||
|
||||
msgid "Custom geosite URL"
|
||||
msgstr "自定义geosite文件更新链接"
|
||||
|
||||
msgid "Override the connection destination address"
|
||||
msgstr "覆盖连接目标地址"
|
||||
|
||||
msgid "Override the connection destination address with the sniffed domain."
|
||||
msgstr "用探测出的域名覆盖连接目标地址。"
|
||||
|
||||
@@ -56,6 +56,19 @@ global_xray=$(uci -q get passwall.@global_xray[0])
|
||||
uci -q commit passwall
|
||||
}
|
||||
|
||||
sed -i "s#option tlsflow#option flow#g" /etc/config/passwall
|
||||
|
||||
global_singbox=$(uci -q get passwall.@global_singbox[0])
|
||||
[ -z "${global_singbox}" ] && {
|
||||
cfgid=$(uci add passwall global_singbox)
|
||||
uci -q set passwall.${cfgid}.sniff_override_destination=1
|
||||
uci -q set passwall.${cfgid}.geoip_path="/tmp/singbox/geoip.db"
|
||||
uci -q set passwall.${cfgid}.geoip_url="https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db"
|
||||
uci -q set passwall.${cfgid}.geosite_path="/tmp/singbox/geosite.db"
|
||||
uci -q set passwall.${cfgid}.geosite_url="https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db"
|
||||
uci -q commit passwall
|
||||
}
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
rm -rf /tmp/luci-modulecache/
|
||||
killall -HUP rpcd 2>/dev/null
|
||||
|
||||
@@ -31,7 +31,7 @@ config global_forwarding
|
||||
option tcp_no_redir_ports 'disable'
|
||||
option udp_no_redir_ports 'disable'
|
||||
option tcp_proxy_drop_ports 'disable'
|
||||
option udp_proxy_drop_ports '80,443'
|
||||
option udp_proxy_drop_ports '443'
|
||||
option tcp_redir_ports '22,25,53,143,465,587,853,993,995,80,443'
|
||||
option udp_redir_ports '1:65535'
|
||||
option accept_icmp '0'
|
||||
@@ -42,6 +42,13 @@ config global_forwarding
|
||||
config global_xray
|
||||
option sniffing '1'
|
||||
option route_only '0'
|
||||
|
||||
config global_singbox
|
||||
option sniff_override_destination '1'
|
||||
option geoip_path '/usr/share/singbox/geoip.db'
|
||||
option geoip_url 'https://github.com/SagerNet/sing-geoip/releases/latest/download/geoip.db'
|
||||
option geosite_path '/usr/share/singbox/geosite.db'
|
||||
option geosite_url 'https://github.com/SagerNet/sing-geosite/releases/latest/download/geosite.db'
|
||||
|
||||
config global_other
|
||||
option nodes_ping 'auto_ping tcping'
|
||||
@@ -65,7 +72,7 @@ config global_rules
|
||||
option v2ray_location_asset '/usr/share/v2ray/'
|
||||
|
||||
config global_app
|
||||
option v2ray_file '/usr/bin/v2ray'
|
||||
option singbox_file '/usr/bin/sing-box'
|
||||
option xray_file '/usr/bin/xray'
|
||||
option trojan_go_file '/usr/bin/trojan-go'
|
||||
option brook_file '/usr/bin/brook'
|
||||
|
||||
@@ -32,6 +32,7 @@ resolve_dns=0
|
||||
use_tcp_node_resolve_dns=0
|
||||
use_udp_node_resolve_dns=0
|
||||
LUA_UTIL_PATH=/usr/lib/lua/luci/passwall
|
||||
UTIL_SINGBOX=$LUA_UTIL_PATH/util_sing-box.lua
|
||||
UTIL_SS=$LUA_UTIL_PATH/util_shadowsocks.lua
|
||||
UTIL_XRAY=$LUA_UTIL_PATH/util_xray.lua
|
||||
UTIL_TROJAN=$LUA_UTIL_PATH/util_trojan.lua
|
||||
@@ -324,7 +325,77 @@ run_ipt2socks() {
|
||||
ln_run "$(first_type ipt2socks)" "ipt2socks_${flag}" $log_file -l $local_port -b 0.0.0.0 -s $socks_address -p $socks_port ${_extra_param}
|
||||
}
|
||||
|
||||
run_v2ray() {
|
||||
run_singbox() {
|
||||
local flag type node tcp_redir_port udp_redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
|
||||
local dns_listen_port remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh dns_query_strategy dns_cache dns_socks_address dns_socks_port
|
||||
local loglevel log_file config_file
|
||||
local _extra_param=""
|
||||
eval_set_val $@
|
||||
[ -z "$type" ] && {
|
||||
local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
||||
if [ "$type" != "sing-box" ]; then
|
||||
bin=$(first_type $(config_t_get global_app singbox_file) sing-box)
|
||||
[ -n "$bin" ] && type="sing-box"
|
||||
fi
|
||||
}
|
||||
[ -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" ] && _extra_param="${_extra_param} -flag $flag"
|
||||
[ -n "$node" ] && _extra_param="${_extra_param} -node $node"
|
||||
[ -n "$tcp_redir_port" ] && _extra_param="${_extra_param} -tcp_redir_port $tcp_redir_port"
|
||||
[ -n "$udp_redir_port" ] && _extra_param="${_extra_param} -udp_redir_port $udp_redir_port"
|
||||
[ -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_socks_address" ] && [ -n "$dns_socks_port" ] && _extra_param="${_extra_param} -dns_socks_address ${dns_socks_address} -dns_socks_port ${dns_socks_port}"
|
||||
[ -n "$dns_listen_port" ] && _extra_param="${_extra_param} -dns_listen_port ${dns_listen_port}"
|
||||
[ -n "$dns_query_strategy" ] && _extra_param="${_extra_param} -remote_dns_query_strategy ${dns_query_strategy}"
|
||||
[ -n "$dns_cache" ] && _extra_param="${_extra_param} -dns_cache ${dns_cache}"
|
||||
case "$remote_dns_protocol" in
|
||||
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}"
|
||||
;;
|
||||
fakedns)
|
||||
_extra_param="${_extra_param} -remote_dns_fake 1"
|
||||
;;
|
||||
esac
|
||||
_extra_param="${_extra_param} -tcp_proxy_way $tcp_proxy_way"
|
||||
lua $UTIL_SINGBOX gen_config ${_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_xray() {
|
||||
local flag type node tcp_redir_port udp_redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
|
||||
local dns_listen_port remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh dns_client_ip dns_query_strategy dns_cache dns_socks_address dns_socks_port
|
||||
local loglevel log_file config_file
|
||||
@@ -332,14 +403,9 @@ run_v2ray() {
|
||||
eval_set_val $@
|
||||
[ -z "$type" ] && {
|
||||
local type=$(echo $(config_n_get $node type) | tr 'A-Z' 'a-z')
|
||||
if [ "$type" != "v2ray" ] && [ "$type" != "xray" ]; then
|
||||
local bin=$(first_type $(config_t_get global_app v2ray_file) v2ray)
|
||||
if [ -n "$bin" ]; then
|
||||
type="v2ray"
|
||||
else
|
||||
bin=$(first_type $(config_t_get global_app xray_file) xray)
|
||||
[ -n "$bin" ] && type="xray"
|
||||
fi
|
||||
if [ "$type" != "xray" ]; then
|
||||
bin=$(first_type $(config_t_get global_app xray_file) xray)
|
||||
[ -n "$bin" ] && type="xray"
|
||||
fi
|
||||
}
|
||||
[ -z "$type" ] && return 1
|
||||
@@ -490,7 +556,7 @@ run_socks() {
|
||||
error_msg="某种原因,此 Socks 服务的相关配置已失联,启动中止!"
|
||||
fi
|
||||
|
||||
if [ "$type" == "v2ray" ] || [ "$type" == "xray" ]; then
|
||||
if [ "$type" == "sing-box" ] || [ "$type" == "xray" ]; then
|
||||
local protocol=$(config_n_get $node protocol)
|
||||
if [ "$protocol" == "_balancing" ] || [ "$protocol" == "_shunt" ] || [ "$protocol" == "_iface" ]; then
|
||||
unset error_msg
|
||||
@@ -505,13 +571,8 @@ run_socks() {
|
||||
|
||||
case "$type" in
|
||||
socks)
|
||||
local bin=$(first_type $(config_t_get global_app v2ray_file) v2ray)
|
||||
if [ -n "$bin" ]; then
|
||||
type="v2ray"
|
||||
else
|
||||
bin=$(first_type $(config_t_get global_app xray_file) xray)
|
||||
[ -n "$bin" ] && type="xray"
|
||||
fi
|
||||
local bin=$(first_type $(config_t_get global_app xray_file) xray)
|
||||
[ -n "$bin" ] && type="xray"
|
||||
[ -z "$type" ] && return 1
|
||||
local _socks_address=$(config_n_get $node address)
|
||||
local _socks_port=$(config_n_get $node port)
|
||||
@@ -525,14 +586,21 @@ run_socks() {
|
||||
lua $UTIL_XRAY gen_proto_config -local_socks_port $socks_port ${_extra_param} -server_proto socks -server_address ${_socks_address} -server_port ${_socks_port} -server_username ${_socks_username} -server_password ${_socks_password} > $config_file
|
||||
ln_run "$bin" $type $log_file run -c "$config_file"
|
||||
;;
|
||||
v2ray|\
|
||||
sing-box)
|
||||
[ "$http_port" != "0" ] && {
|
||||
http_flag=1
|
||||
config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g")
|
||||
local _args="-local_http_port $http_port"
|
||||
}
|
||||
run_singbox flag=$flag node=$node socks_port=$socks_port config_file=$config_file log_file=$log_file ${_args}
|
||||
;;
|
||||
xray)
|
||||
[ "$http_port" != "0" ] && {
|
||||
http_flag=1
|
||||
config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g")
|
||||
local _v2ray_args="http_port=$http_port"
|
||||
local _args="http_port=$http_port"
|
||||
}
|
||||
run_v2ray flag=$flag node=$node socks_port=$socks_port config_file=$config_file log_file=$log_file ${_v2ray_args}
|
||||
run_xray flag=$flag node=$node socks_port=$socks_port config_file=$config_file log_file=$log_file ${_args}
|
||||
;;
|
||||
trojan-go)
|
||||
lua $UTIL_TROJAN gen_config -node $node -run_type client -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $port > $config_file
|
||||
@@ -594,17 +662,19 @@ run_socks() {
|
||||
esac
|
||||
|
||||
# http to socks
|
||||
[ -z "$http_flag" ] && [ "$http_port" != "0" ] && [ -n "$http_config_file" ] && [ "$type" != "v2ray" ] && [ "$type" != "xray" ] && [ "$type" != "socks" ] && {
|
||||
local bin=$(first_type $(config_t_get global_app v2ray_file) v2ray)
|
||||
[ -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 singbox_file) sing-box)
|
||||
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
|
||||
bin=$(first_type $(config_t_get global_app xray_file) xray)
|
||||
[ -n "$bin" ] && type="xray"
|
||||
[ -z "$type" ] && return 1
|
||||
lua $UTIL_XRAY gen_proto_config -local_http_port $http_port -server_proto socks -server_address "127.0.0.1" -server_port $socks_port -server_username $_username -server_password $_password > $http_config_file
|
||||
ln_run "$bin" ${type} /dev/null run -c "$http_config_file"
|
||||
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
|
||||
}
|
||||
@@ -649,9 +719,11 @@ run_redir() {
|
||||
[ -n "${_socks_username}" ] && [ -n "${_socks_password}" ] && local _extra_param="-a ${_socks_username} -k ${_socks_password}"
|
||||
ln_run "$(first_type ipt2socks)" "ipt2socks_UDP" $log_file -l $local_port -b 0.0.0.0 -s ${_socks_address} -p ${_socks_port} ${_extra_param} -U -v
|
||||
;;
|
||||
v2ray|\
|
||||
sing-box)
|
||||
run_singbox flag=UDP node=$node udp_redir_port=$local_port config_file=$config_file log_file=$log_file
|
||||
;;
|
||||
xray)
|
||||
run_v2ray flag=UDP node=$node udp_redir_port=$local_port config_file=$config_file log_file=$log_file
|
||||
run_xray flag=UDP node=$node udp_redir_port=$local_port config_file=$config_file log_file=$log_file
|
||||
;;
|
||||
trojan-go)
|
||||
local loglevel=$(config_t_get global trojan_loglevel "2")
|
||||
@@ -702,11 +774,7 @@ run_redir() {
|
||||
[ "$tcp_node_http_port" != "0" ] && tcp_node_http=1
|
||||
if [ $PROXY_IPV6 == "1" ]; then
|
||||
echolog "开启实验性IPv6透明代理(TProxy),请确认您的节点及类型支持IPv6!"
|
||||
if [ $type != "v2ray" ]; then
|
||||
PROXY_IPV6_UDP=1
|
||||
else
|
||||
echolog "节点类型:$type暂未支持IPv6 UDP代理!"
|
||||
fi
|
||||
PROXY_IPV6_UDP=1
|
||||
fi
|
||||
|
||||
if [ "$tcp_proxy_way" = "redirect" ]; then
|
||||
@@ -735,45 +803,42 @@ run_redir() {
|
||||
unset _socks_password
|
||||
}
|
||||
;;
|
||||
v2ray|\
|
||||
xray)
|
||||
sing-box)
|
||||
local _flag="TCP"
|
||||
local _v2ray_args=""
|
||||
local _args=""
|
||||
[ "$tcp_node_socks" = "1" ] && {
|
||||
tcp_node_socks_flag=1
|
||||
_v2ray_args="${_v2ray_args} socks_port=${tcp_node_socks_port}"
|
||||
_args="${_args} socks_port=${tcp_node_socks_port}"
|
||||
config_file=$(echo $config_file | sed "s/TCP/TCP_SOCKS/g")
|
||||
}
|
||||
[ "$tcp_node_http" = "1" ] && {
|
||||
tcp_node_http_flag=1
|
||||
_v2ray_args="${_v2ray_args} http_port=${tcp_node_http_port}"
|
||||
_args="${_args} http_port=${tcp_node_http_port}"
|
||||
config_file=$(echo $config_file | sed "s/TCP/TCP_HTTP/g")
|
||||
}
|
||||
[ "$TCP_UDP" = "1" ] && {
|
||||
UDP_REDIR_PORT=$local_port
|
||||
UDP_NODE="nil"
|
||||
_flag="TCP_UDP"
|
||||
_v2ray_args="${_v2ray_args} udp_redir_port=${UDP_REDIR_PORT}"
|
||||
_args="${_args} udp_redir_port=${UDP_REDIR_PORT}"
|
||||
config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g")
|
||||
}
|
||||
[ "${DNS_MODE}" = "v2ray" -o "${DNS_MODE}" = "xray" ] && {
|
||||
[ "${DNS_MODE}" = "sing-box" ] && {
|
||||
resolve_dns=1
|
||||
config_file=$(echo $config_file | sed "s/.json/_DNS.json/g")
|
||||
_v2ray_args="${_v2ray_args} dns_query_strategy=${DNS_QUERY_STRATEGY}"
|
||||
local _dns_client_ip=$(config_t_get global dns_client_ip)
|
||||
[ -n "${_dns_client_ip}" ] && _v2ray_args="${_v2ray_args} dns_client_ip=${_dns_client_ip}"
|
||||
[ "${DNS_CACHE}" == "0" ] && _v2ray_args="${_v2ray_args} dns_cache=0"
|
||||
_args="${_args} dns_query_strategy=${DNS_QUERY_STRATEGY}"
|
||||
[ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0"
|
||||
local v2ray_dns_mode=$(config_t_get global v2ray_dns_mode tcp)
|
||||
_v2ray_args="${_v2ray_args} remote_dns_protocol=${v2ray_dns_mode}"
|
||||
_v2ray_args="${_v2ray_args} dns_listen_port=${dns_listen_port}"
|
||||
_args="${_args} remote_dns_protocol=${v2ray_dns_mode}"
|
||||
_args="${_args} dns_listen_port=${dns_listen_port}"
|
||||
case "$v2ray_dns_mode" in
|
||||
tcp)
|
||||
_v2ray_args="${_v2ray_args} remote_dns_tcp_server=${REMOTE_DNS}"
|
||||
_args="${_args} remote_dns_tcp_server=${REMOTE_DNS}"
|
||||
echolog " - 域名解析 DNS Over TCP..."
|
||||
;;
|
||||
doh)
|
||||
remote_dns_doh=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query")
|
||||
_v2ray_args="${_v2ray_args} remote_dns_doh=${remote_dns_doh}"
|
||||
_args="${_args} remote_dns_doh=${remote_dns_doh}"
|
||||
echolog " - 域名解析 DNS Over HTTPS..."
|
||||
;;
|
||||
fakedns)
|
||||
@@ -782,7 +847,55 @@ run_redir() {
|
||||
;;
|
||||
esac
|
||||
}
|
||||
run_v2ray flag=$_flag node=$node tcp_redir_port=$local_port config_file=$config_file log_file=$log_file ${_v2ray_args}
|
||||
run_singbox flag=$_flag node=$node tcp_redir_port=$local_port config_file=$config_file log_file=$log_file ${_args}
|
||||
;;
|
||||
xray)
|
||||
local _flag="TCP"
|
||||
local _args=""
|
||||
[ "$tcp_node_socks" = "1" ] && {
|
||||
tcp_node_socks_flag=1
|
||||
_args="${_args} socks_port=${tcp_node_socks_port}"
|
||||
config_file=$(echo $config_file | sed "s/TCP/TCP_SOCKS/g")
|
||||
}
|
||||
[ "$tcp_node_http" = "1" ] && {
|
||||
tcp_node_http_flag=1
|
||||
_args="${_args} http_port=${tcp_node_http_port}"
|
||||
config_file=$(echo $config_file | sed "s/TCP/TCP_HTTP/g")
|
||||
}
|
||||
[ "$TCP_UDP" = "1" ] && {
|
||||
UDP_REDIR_PORT=$local_port
|
||||
UDP_NODE="nil"
|
||||
_flag="TCP_UDP"
|
||||
_args="${_args} udp_redir_port=${UDP_REDIR_PORT}"
|
||||
config_file=$(echo $config_file | sed "s/TCP/TCP_UDP/g")
|
||||
}
|
||||
[ "${DNS_MODE}" = "xray" ] && {
|
||||
resolve_dns=1
|
||||
config_file=$(echo $config_file | sed "s/.json/_DNS.json/g")
|
||||
_args="${_args} dns_query_strategy=${DNS_QUERY_STRATEGY}"
|
||||
local _dns_client_ip=$(config_t_get global dns_client_ip)
|
||||
[ -n "${_dns_client_ip}" ] && _args="${_args} dns_client_ip=${_dns_client_ip}"
|
||||
[ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0"
|
||||
local v2ray_dns_mode=$(config_t_get global v2ray_dns_mode tcp)
|
||||
_args="${_args} remote_dns_protocol=${v2ray_dns_mode}"
|
||||
_args="${_args} dns_listen_port=${dns_listen_port}"
|
||||
case "$v2ray_dns_mode" in
|
||||
tcp)
|
||||
_args="${_args} remote_dns_tcp_server=${REMOTE_DNS}"
|
||||
echolog " - 域名解析 DNS Over TCP..."
|
||||
;;
|
||||
doh)
|
||||
remote_dns_doh=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query")
|
||||
_args="${_args} remote_dns_doh=${remote_dns_doh}"
|
||||
echolog " - 域名解析 DNS Over HTTPS..."
|
||||
;;
|
||||
fakedns)
|
||||
fakedns=1
|
||||
echolog " - 域名解析 Fake DNS..."
|
||||
;;
|
||||
esac
|
||||
}
|
||||
run_xray flag=$_flag node=$node tcp_redir_port=$local_port config_file=$config_file log_file=$log_file ${_args}
|
||||
;;
|
||||
trojan-go)
|
||||
[ "$TCP_UDP" = "1" ] && {
|
||||
@@ -1135,29 +1248,26 @@ start_dns() {
|
||||
run_dns2socks socks=$dns2socks_socks_server listen_address=127.0.0.1 listen_port=${dns_listen_port} dns=$dns2socks_forward cache=$DNS_CACHE
|
||||
echolog " - 域名解析:dns2socks(127.0.0.1:${dns_listen_port}),${dns2socks_socks_server} -> ${dns2socks_forward}"
|
||||
;;
|
||||
v2ray|\
|
||||
xray)
|
||||
sing-box)
|
||||
[ "${resolve_dns}" == "0" ] && {
|
||||
local config_file=$TMP_PATH/DNS.json
|
||||
local log_file=$TMP_PATH/DNS.log
|
||||
local log_file=/dev/null
|
||||
local _v2ray_args="type=$DNS_MODE config_file=$config_file log_file=$log_file"
|
||||
[ "${DNS_CACHE}" == "0" ] && _v2ray_args="${_v2ray_args} dns_cache=0"
|
||||
_v2ray_args="${_v2ray_args} dns_query_strategy=${DNS_QUERY_STRATEGY}"
|
||||
local _dns_client_ip=$(config_t_get global dns_client_ip)
|
||||
[ -n "${_dns_client_ip}" ] && _v2ray_args="${_v2ray_args} dns_client_ip=${_dns_client_ip}"
|
||||
local _args="type=$DNS_MODE config_file=$config_file log_file=$log_file"
|
||||
[ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0"
|
||||
_args="${_args} dns_query_strategy=${DNS_QUERY_STRATEGY}"
|
||||
use_tcp_node_resolve_dns=1
|
||||
local v2ray_dns_mode=$(config_t_get global v2ray_dns_mode tcp)
|
||||
_v2ray_args="${_v2ray_args} dns_listen_port=${dns_listen_port}"
|
||||
_v2ray_args="${_v2ray_args} remote_dns_protocol=${v2ray_dns_mode}"
|
||||
_args="${_args} dns_listen_port=${dns_listen_port}"
|
||||
_args="${_args} remote_dns_protocol=${v2ray_dns_mode}"
|
||||
case "$v2ray_dns_mode" in
|
||||
tcp)
|
||||
_v2ray_args="${_v2ray_args} remote_dns_tcp_server=${REMOTE_DNS}"
|
||||
_args="${_args} remote_dns_tcp_server=${REMOTE_DNS}"
|
||||
echolog " - 域名解析 DNS Over TCP..."
|
||||
;;
|
||||
doh)
|
||||
remote_dns_doh=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query")
|
||||
_v2ray_args="${_v2ray_args} remote_dns_doh=${remote_dns_doh}"
|
||||
_args="${_args} remote_dns_doh=${remote_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}\")")
|
||||
@@ -1172,7 +1282,46 @@ start_dns() {
|
||||
echolog " - 域名解析 DNS Over HTTPS..."
|
||||
;;
|
||||
esac
|
||||
run_v2ray ${_v2ray_args}
|
||||
run_singbox ${_args}
|
||||
}
|
||||
;;
|
||||
xray)
|
||||
[ "${resolve_dns}" == "0" ] && {
|
||||
local config_file=$TMP_PATH/DNS.json
|
||||
local log_file=$TMP_PATH/DNS.log
|
||||
local log_file=/dev/null
|
||||
local _args="type=$DNS_MODE config_file=$config_file log_file=$log_file"
|
||||
[ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0"
|
||||
_args="${_args} dns_query_strategy=${DNS_QUERY_STRATEGY}"
|
||||
local _dns_client_ip=$(config_t_get global dns_client_ip)
|
||||
[ -n "${_dns_client_ip}" ] && _args="${_args} dns_client_ip=${_dns_client_ip}"
|
||||
use_tcp_node_resolve_dns=1
|
||||
local v2ray_dns_mode=$(config_t_get global v2ray_dns_mode tcp)
|
||||
_args="${_args} dns_listen_port=${dns_listen_port}"
|
||||
_args="${_args} remote_dns_protocol=${v2ray_dns_mode}"
|
||||
case "$v2ray_dns_mode" in
|
||||
tcp)
|
||||
_args="${_args} remote_dns_tcp_server=${REMOTE_DNS}"
|
||||
echolog " - 域名解析 DNS Over TCP..."
|
||||
;;
|
||||
doh)
|
||||
remote_dns_doh=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query")
|
||||
_args="${_args} remote_dns_doh=${remote_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=$(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}" ] && REMOTE_DNS=${_doh_bootstrap}:${_doh_port}
|
||||
unset _doh_url _doh_host_port _doh_host _is_ip _doh_port _doh_bootstrap
|
||||
echolog " - 域名解析 DNS Over HTTPS..."
|
||||
;;
|
||||
esac
|
||||
run_xray ${_args}
|
||||
}
|
||||
;;
|
||||
dns2tcp)
|
||||
@@ -1316,7 +1465,7 @@ acl_app() {
|
||||
remote_dns=${remote_dns:-1.1.1.1}
|
||||
chinadns_ng=${chinadns_ng:-0}
|
||||
when_chnroute_default_dns=${when_chnroute_default_dns:-direct}
|
||||
[ "$dns_mode" = "v2ray" -o "$dns_mode" = "xray" ] && {
|
||||
[ "$dns_mode" = "sing-box" -o "$dns_mode" = "xray" ] && {
|
||||
[ "$v2ray_dns_mode" = "doh" ] && remote_dns=${remote_dns_doh:-https://1.1.1.1/dns-query}
|
||||
}
|
||||
[ "$tcp_proxy_mode" = "default" ] && tcp_proxy_mode=$TCP_PROXY_MODE
|
||||
@@ -1336,9 +1485,9 @@ acl_app() {
|
||||
_dns_port=$dns_port
|
||||
if [ "$dns_mode" = "dns2socks" ]; then
|
||||
run_dns2socks flag=acl_${sid} socks_address=127.0.0.1 socks_port=$socks_port listen_address=0.0.0.0 listen_port=${_dns_port} dns=$remote_dns cache=1
|
||||
elif [ "$dns_mode" = "v2ray" -o "$dns_mode" = "xray" ]; then
|
||||
elif [ "$dns_mode" = "sing-box" -o "$dns_mode" = "xray" ]; then
|
||||
config_file=$TMP_ACL_PATH/${tcp_node}_SOCKS_${socks_port}_DNS.json
|
||||
run_v2ray flag=acl_${sid} type=$dns_mode dns_socks_address=127.0.0.1 dns_socks_port=$socks_port dns_listen_port=${_dns_port} remote_dns_protocol=${v2ray_dns_mode} remote_dns_tcp_server=${remote_dns} remote_dns_doh="${remote_dns}" dns_client_ip=${dns_client_ip} dns_query_strategy=${DNS_QUERY_STRATEGY} config_file=$config_file
|
||||
run_${dns_mode} flag=acl_${sid} type=$dns_mode dns_socks_address=127.0.0.1 dns_socks_port=$socks_port dns_listen_port=${_dns_port} remote_dns_protocol=${v2ray_dns_mode} remote_dns_tcp_server=${remote_dns} remote_dns_doh="${remote_dns}" dns_client_ip=${dns_client_ip} dns_query_strategy=${DNS_QUERY_STRATEGY} config_file=$config_file
|
||||
fi
|
||||
eval node_${tcp_node}_$(echo -n "${remote_dns}" | md5sum | cut -d " " -f1)=${_dns_port}
|
||||
}
|
||||
@@ -1421,10 +1570,10 @@ acl_app() {
|
||||
tcp_port=$redir_port
|
||||
|
||||
local type=$(echo $(config_n_get $tcp_node type) | tr 'A-Z' 'a-z')
|
||||
if [ -n "${type}" ] && ([ "${type}" = "v2ray" ] || [ "${type}" = "xray" ]); then
|
||||
if [ -n "${type}" ] && ([ "${type}" = "sing-box" ] || [ "${type}" = "xray" ]); then
|
||||
config_file="acl/${tcp_node}_TCP_${redir_port}.json"
|
||||
_extra_param="socks_address=127.0.0.1 socks_port=$socks_port"
|
||||
if [ "$dns_mode" = "v2ray" -o "$dns_mode" = "xray" ]; then
|
||||
if [ "$dns_mode" = "sing-box" ] || [ "$dns_mode" = "xray" ]; then
|
||||
dns_port=$(get_new_port $(expr $dns_port + 1))
|
||||
_dns_port=$dns_port
|
||||
config_file=$(echo $config_file | sed "s/TCP_/DNS_${_dns_port}_TCP_/g")
|
||||
@@ -1435,7 +1584,7 @@ acl_app() {
|
||||
_extra_param="${_extra_param} udp_redir_port=$redir_port"
|
||||
}
|
||||
config_file="$TMP_PATH/$config_file"
|
||||
run_v2ray flag=$tcp_node node=$tcp_node tcp_redir_port=$redir_port ${_extra_param} config_file=$config_file
|
||||
run_${type} flag=$tcp_node node=$tcp_node tcp_redir_port=$redir_port ${_extra_param} config_file=$config_file
|
||||
else
|
||||
config_file="acl/${tcp_node}_SOCKS_${socks_port}.json"
|
||||
run_socks flag=$tcp_node node=$tcp_node bind=127.0.0.1 socks_port=$socks_port config_file=$config_file
|
||||
@@ -1485,10 +1634,10 @@ acl_app() {
|
||||
udp_port=$redir_port
|
||||
|
||||
local type=$(echo $(config_n_get $udp_node type) | tr 'A-Z' 'a-z')
|
||||
if [ -n "${type}" ] && ([ "${type}" = "v2ray" ] || [ "${type}" = "xray" ]); then
|
||||
if [ -n "${type}" ] && ([ "${type}" = "sing-box" ] || [ "${type}" = "xray" ]); then
|
||||
config_file="acl/${udp_node}_UDP_${redir_port}.json"
|
||||
config_file="$TMP_PATH/$config_file"
|
||||
run_v2ray flag=$udp_node node=$udp_node udp_redir_port=$redir_port config_file=$config_file
|
||||
run_${type} flag=$udp_node node=$udp_node udp_redir_port=$redir_port config_file=$config_file
|
||||
else
|
||||
config_file="acl/${udp_node}_SOCKS_${socks_port}.json"
|
||||
run_socks flag=$udp_node node=$udp_node bind=127.0.0.1 socks_port=$socks_port config_file=$config_file
|
||||
@@ -1624,8 +1773,8 @@ WHEN_CHNROUTE_DEFAULT_DNS=$(config_t_get global when_chnroute_default_dns direct
|
||||
FILTER_PROXY_IPV6=$(config_t_get global filter_proxy_ipv6 0)
|
||||
dns_listen_port=${DNS_PORT}
|
||||
|
||||
REDIRECT_LIST="socks ss ss-rust ssr v2ray xray trojan-go trojan-plus naiveproxy hysteria"
|
||||
TPROXY_LIST="brook socks ss ss-rust ssr v2ray xray trojan-go trojan-plus hysteria"
|
||||
REDIRECT_LIST="socks ss ss-rust ssr sing-box xray trojan-go trojan-plus naiveproxy hysteria"
|
||||
TPROXY_LIST="brook socks ss ss-rust ssr sing-box xray trojan-go trojan-plus hysteria"
|
||||
RESOLVFILE=/tmp/resolv.conf.d/resolv.conf.auto
|
||||
[ -f "${RESOLVFILE}" ] && [ -s "${RESOLVFILE}" ] || RESOLVFILE=/tmp/resolv.conf.auto
|
||||
|
||||
|
||||
@@ -1125,6 +1125,7 @@ flush_ipset() {
|
||||
for _name in $(ipset list | grep "Name: " | grep "passwall_" | awk '{print $2}'); do
|
||||
destroy_ipset ${_name}
|
||||
done
|
||||
rm -rf /tmp/singbox_passwall*
|
||||
rm -rf /tmp/etc/passwall_tmp/dnsmasq*
|
||||
/etc/init.d/passwall reload
|
||||
}
|
||||
|
||||
@@ -1166,6 +1166,7 @@ flush_nftset() {
|
||||
for _name in $(nft -a list sets | grep -E "passwall" | awk -F 'set ' '{print $2}' | awk '{print $1}'); do
|
||||
destroy_nftset ${_name}
|
||||
done
|
||||
rm -rf /tmp/singbox_passwall*
|
||||
rm -rf /tmp/etc/passwall_tmp/dnsmasq*
|
||||
/etc/init.d/passwall reload
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ local chnroute6_url = ucic:get(name, "@global_rules[0]", "chnroute6_url") or {"
|
||||
local chnlist_url = ucic:get(name, "@global_rules[0]", "chnlist_url") or {"https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/accelerated-domains.china.conf","https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/apple.china.conf","https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/google.china.conf"}
|
||||
local geoip_api = "https://api.github.com/repos/Loyalsoldier/v2ray-rules-dat/releases/latest"
|
||||
local geosite_api = "https://api.github.com/repos/Loyalsoldier/v2ray-rules-dat/releases/latest"
|
||||
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/")
|
||||
local use_nft = ucic:get(name, "@global_forwarding[0]", "use_nft") or "0"
|
||||
|
||||
local log = function(...)
|
||||
@@ -285,8 +285,8 @@ local function fetch_geoip()
|
||||
f:write(content:gsub("geoip.dat", "/tmp/geoip.dat"), "")
|
||||
f:close()
|
||||
|
||||
if nixio.fs.access(v2ray_asset_location .. "geoip.dat") then
|
||||
luci.sys.call(string.format("cp -f %s %s", v2ray_asset_location .. "geoip.dat", "/tmp/geoip.dat"))
|
||||
if nixio.fs.access(asset_location .. "geoip.dat") then
|
||||
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
|
||||
log("geoip 版本一致,无需更新。")
|
||||
return 1
|
||||
@@ -296,7 +296,7 @@ local function fetch_geoip()
|
||||
if v2.name and v2.name == "geoip.dat" then
|
||||
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
|
||||
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
|
||||
log("geoip 更新成功。")
|
||||
return 1
|
||||
@@ -336,8 +336,8 @@ local function fetch_geosite()
|
||||
f:write(content:gsub("geosite.dat", "/tmp/geosite.dat"), "")
|
||||
f:close()
|
||||
|
||||
if nixio.fs.access(v2ray_asset_location .. "geosite.dat") then
|
||||
luci.sys.call(string.format("cp -f %s %s", v2ray_asset_location .. "geosite.dat", "/tmp/geosite.dat"))
|
||||
if nixio.fs.access(asset_location .. "geosite.dat") then
|
||||
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
|
||||
log("geosite 版本一致,无需更新。")
|
||||
return 1
|
||||
@@ -347,7 +347,7 @@ local function fetch_geosite()
|
||||
if v2.name and v2.name == "geosite.dat" then
|
||||
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
|
||||
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
|
||||
log("geosite 更新成功。")
|
||||
return 1
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -271,7 +271,6 @@
|
||||
103.108.160.0/22
|
||||
103.108.164.0/22
|
||||
103.108.184.0/23
|
||||
103.108.188.0/23
|
||||
103.108.192.0/22
|
||||
103.108.196.0/22
|
||||
103.108.208.0/22
|
||||
@@ -332,7 +331,6 @@
|
||||
103.115.120.0/22
|
||||
103.115.148.0/22
|
||||
103.115.16.0/22
|
||||
103.115.204.0/23
|
||||
103.115.248.0/22
|
||||
103.115.40.0/22
|
||||
103.115.44.0/22
|
||||
@@ -395,7 +393,6 @@
|
||||
103.119.200.0/22
|
||||
103.119.224.0/22
|
||||
103.119.28.0/22
|
||||
103.119.44.0/22
|
||||
103.12.136.0/22
|
||||
103.12.184.0/22
|
||||
103.12.232.0/22
|
||||
@@ -1206,6 +1203,7 @@
|
||||
103.209.200.0/22
|
||||
103.209.208.0/22
|
||||
103.209.216.0/22
|
||||
103.21.102.0/23
|
||||
103.21.112.0/22
|
||||
103.21.116.0/22
|
||||
103.21.136.0/22
|
||||
@@ -1213,6 +1211,7 @@
|
||||
103.21.176.0/22
|
||||
103.21.208.0/22
|
||||
103.21.240.0/22
|
||||
103.21.98.0/23
|
||||
103.210.156.0/22
|
||||
103.210.160.0/22
|
||||
103.210.164.0/22
|
||||
@@ -1301,6 +1300,7 @@
|
||||
103.216.12.0/22
|
||||
103.216.136.0/22
|
||||
103.216.152.0/22
|
||||
103.216.156.0/23
|
||||
103.216.16.0/22
|
||||
103.216.20.0/22
|
||||
103.216.224.0/22
|
||||
@@ -1735,6 +1735,7 @@
|
||||
103.235.80.0/22
|
||||
103.235.84.0/22
|
||||
103.236.0.0/22
|
||||
103.236.116.0/23
|
||||
103.236.12.0/22
|
||||
103.236.120.0/22
|
||||
103.236.16.0/22
|
||||
@@ -2005,6 +2006,7 @@
|
||||
103.255.140.0/22
|
||||
103.255.184.0/22
|
||||
103.255.200.0/22
|
||||
103.255.208.0/23
|
||||
103.255.212.0/22
|
||||
103.255.228.0/22
|
||||
103.255.56.0/22
|
||||
@@ -3259,7 +3261,6 @@
|
||||
103.92.108.0/22
|
||||
103.92.12.0/22
|
||||
103.92.124.0/22
|
||||
103.92.128.0/24
|
||||
103.92.132.0/22
|
||||
103.92.156.0/22
|
||||
103.92.164.0/22
|
||||
@@ -3355,13 +3356,10 @@
|
||||
103.97.128.0/22
|
||||
103.97.144.0/22
|
||||
103.97.148.0/22
|
||||
103.97.16.0/22
|
||||
103.97.16.0/20
|
||||
103.97.188.0/22
|
||||
103.97.192.0/22
|
||||
103.97.20.0/22
|
||||
103.97.228.0/23
|
||||
103.97.24.0/22
|
||||
103.97.28.0/22
|
||||
103.97.32.0/22
|
||||
103.97.36.0/22
|
||||
103.97.40.0/22
|
||||
@@ -4843,7 +4841,6 @@
|
||||
202.12.116.0/24
|
||||
202.12.17.0/24
|
||||
202.12.18.0/24
|
||||
202.12.19.0/24
|
||||
202.12.2.0/24
|
||||
202.12.72.0/24
|
||||
202.12.84.0/23
|
||||
@@ -4856,7 +4853,6 @@
|
||||
202.122.0.0/21
|
||||
202.122.112.0/21
|
||||
202.122.120.0/21
|
||||
202.122.128.0/24
|
||||
202.122.132.0/24
|
||||
202.122.32.0/21
|
||||
202.122.64.0/19
|
||||
@@ -4880,7 +4876,6 @@
|
||||
202.127.196.0/22
|
||||
202.127.2.0/24
|
||||
202.127.200.0/21
|
||||
202.127.208.0/24
|
||||
202.127.212.0/22
|
||||
202.127.216.0/21
|
||||
202.127.224.0/19
|
||||
@@ -5092,21 +5087,17 @@
|
||||
202.38.134.0/24
|
||||
202.38.135.0/24
|
||||
202.38.136.0/23
|
||||
202.38.138.0/24
|
||||
202.38.140.0/23
|
||||
202.38.142.0/23
|
||||
202.38.146.0/23
|
||||
202.38.149.0/24
|
||||
202.38.150.0/23
|
||||
202.38.152.0/23
|
||||
202.38.154.0/23
|
||||
202.38.156.0/24
|
||||
202.38.158.0/23
|
||||
202.38.160.0/23
|
||||
202.38.164.0/22
|
||||
202.38.168.0/23
|
||||
202.38.170.0/24
|
||||
202.38.171.0/24
|
||||
202.38.176.0/23
|
||||
202.38.184.0/21
|
||||
202.38.192.0/18
|
||||
@@ -5325,7 +5316,6 @@
|
||||
202.90.37.0/24
|
||||
202.90.96.0/22
|
||||
202.91.0.0/22
|
||||
202.91.128.0/22
|
||||
202.91.176.0/20
|
||||
202.91.224.0/19
|
||||
202.91.36.0/22
|
||||
@@ -5770,8 +5760,6 @@
|
||||
203.207.88.0/22
|
||||
203.207.92.0/22
|
||||
203.207.96.0/20
|
||||
203.208.0.0/20
|
||||
203.208.16.0/22
|
||||
203.208.32.0/19
|
||||
203.209.224.0/19
|
||||
203.21.0.0/23
|
||||
@@ -6384,7 +6372,6 @@
|
||||
203.9.75.0/24
|
||||
203.9.76.0/23
|
||||
203.9.96.0/22
|
||||
203.90.0.0/22
|
||||
203.90.12.0/22
|
||||
203.90.128.0/19
|
||||
203.90.160.0/19
|
||||
|
||||
@@ -64,6 +64,7 @@
|
||||
2001:df2:8bc0::/48
|
||||
2001:df2:a580::/48
|
||||
2001:df2:c240::/48
|
||||
2001:df2:d4c0::/48
|
||||
2001:df3:1480::/48
|
||||
2001:df3:2a80::/48
|
||||
2001:df3:3a80::/48
|
||||
@@ -443,6 +444,7 @@
|
||||
2401:2a00::/32
|
||||
2401:2b40::/32
|
||||
2401:2e00::/32
|
||||
2401:2e20::/32
|
||||
2401:3100::/32
|
||||
2401:3380::/32
|
||||
2401:33c0::/32
|
||||
@@ -666,7 +668,6 @@
|
||||
2402:4e00::/32
|
||||
2402:4ec0::/32
|
||||
2402:4f80::/32
|
||||
2402:5140::/32
|
||||
2402:5180::/32
|
||||
2402:52c0::/32
|
||||
2402:5340::/32
|
||||
@@ -821,7 +822,6 @@
|
||||
2402:ef80::/32
|
||||
2402:f000::/32
|
||||
2402:f140::/32
|
||||
2402:f3c0::/32
|
||||
2402:f480::/32
|
||||
2402:f540::/32
|
||||
2402:f580::/32
|
||||
|
||||
@@ -24,9 +24,9 @@ uci:revert(appname)
|
||||
local has_ss = api.is_finded("ss-redir")
|
||||
local has_ss_rust = api.is_finded("sslocal")
|
||||
local has_trojan_plus = api.is_finded("trojan-plus")
|
||||
local has_v2ray = api.is_finded("v2ray")
|
||||
local has_xray = api.is_finded("xray")
|
||||
local has_trojan_go = api.is_finded("trojan-go")
|
||||
local has_singbox = api.finded_com("singbox")
|
||||
local has_xray = api.finded_com("xray")
|
||||
local has_trojan_go = api.finded_com("trojan-go")
|
||||
local allowInsecure_default = nil
|
||||
local ss_aead_type_default = uci:get(appname, "@global_subscribe[0]", "ss_aead_type") or "shadowsocks-libev"
|
||||
local trojan_type_default = uci:get(appname, "@global_subscribe[0]", "trojan_type") or "trojan-plus"
|
||||
@@ -395,8 +395,8 @@ local function processData(szType, content, add_mode, add_from)
|
||||
result.remarks = base64Decode(params.remarks)
|
||||
elseif szType == 'vmess' then
|
||||
local info = jsonParse(content)
|
||||
if has_v2ray then
|
||||
result.type = 'V2ray'
|
||||
if has_singbox then
|
||||
result.type = 'sing-box'
|
||||
elseif has_xray then
|
||||
result.type = 'Xray'
|
||||
end
|
||||
@@ -542,13 +542,9 @@ local function processData(szType, content, add_mode, add_from)
|
||||
if method:lower() == "chacha20-poly1305" then
|
||||
result.method = "chacha20-ietf-poly1305"
|
||||
end
|
||||
elseif ss_aead_type_default == "v2ray" and has_v2ray and not result.plugin then
|
||||
result.type = 'V2ray'
|
||||
elseif ss_aead_type_default == "sing-box" and has_singbox and not result.plugin then
|
||||
result.type = 'sing-box'
|
||||
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
|
||||
result.type = 'Xray'
|
||||
result.protocol = 'shadowsocks'
|
||||
@@ -559,13 +555,16 @@ local function processData(szType, content, add_mode, add_from)
|
||||
end
|
||||
end
|
||||
local aead2022 = false
|
||||
for k, v in ipairs({"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha8-poly1305", "2022-blake3-chacha20-poly1305"}) do
|
||||
for k, v in ipairs({"2022-blake3-aes-128-gcm", "2022-blake3-aes-256-gcm", "2022-blake3-chacha20-poly1305"}) do
|
||||
if method:lower() == v:lower() then
|
||||
aead2022 = true
|
||||
end
|
||||
end
|
||||
if aead2022 then
|
||||
if ss_aead_type_default == "xray" and has_xray and not result.plugin then
|
||||
if ss_aead_type_default == "sing-box" and has_singbox and not result.plugin then
|
||||
result.type = 'sing-box'
|
||||
result.protocol = 'shadowsocks'
|
||||
elseif ss_aead_type_default == "xray" and has_xray and not result.plugin then
|
||||
result.type = 'Xray'
|
||||
result.protocol = 'shadowsocks'
|
||||
result.transport = 'tcp'
|
||||
@@ -644,8 +643,8 @@ local function processData(szType, content, add_mode, add_from)
|
||||
end
|
||||
if trojan_type_default == "trojan-plus" and has_trojan_plus then
|
||||
result.type = "Trojan-Plus"
|
||||
elseif trojan_type_default == "v2ray" and has_v2ray then
|
||||
result.type = 'V2ray'
|
||||
elseif trojan_type_default == "sing-box" and has_singbox then
|
||||
result.type = 'sing-box'
|
||||
result.protocol = 'trojan'
|
||||
elseif trojan_type_default == "xray" and has_xray then
|
||||
result.type = 'Xray'
|
||||
@@ -721,10 +720,10 @@ local function processData(szType, content, add_mode, add_from)
|
||||
result.group = content.airport
|
||||
result.remarks = content.remarks
|
||||
elseif szType == "vless" then
|
||||
if has_xray then
|
||||
if has_singbox then
|
||||
result.type = 'sing-box'
|
||||
elseif has_xray then
|
||||
result.type = 'Xray'
|
||||
elseif has_v2ray then
|
||||
result.type = 'V2ray'
|
||||
end
|
||||
result.protocol = "vless"
|
||||
local alias = ""
|
||||
@@ -800,10 +799,11 @@ local function processData(szType, content, add_mode, add_from)
|
||||
|
||||
result.encryption = params.encryption or "none"
|
||||
|
||||
result.flow = params.flow or nil
|
||||
|
||||
result.tls = "0"
|
||||
if params.security == "tls" or params.security == "reality" then
|
||||
result.tls = "1"
|
||||
result.tlsflow = params.flow or nil
|
||||
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"
|
||||
if params.security == "reality" then
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-passwall2
|
||||
PKG_VERSION:=1.20-5
|
||||
PKG_VERSION:=1.20-6
|
||||
PKG_RELEASE:=
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
|
||||
@@ -325,6 +325,9 @@ if singbox_tags:find("with_quic") then
|
||||
|
||||
o = s:option(Flag, option_name("hysteria_disable_mtu_discovery"), translate("Disable MTU detection"))
|
||||
o:depends({ [option_name("protocol")] = "hysteria" })
|
||||
|
||||
o = s:option(Value, option_name("hysteria_alpn"), translate("QUIC TLS ALPN"))
|
||||
o:depends({ [option_name("protocol")] = "hysteria" })
|
||||
end
|
||||
|
||||
if singbox_tags:find("with_quic") then
|
||||
@@ -408,10 +411,16 @@ o:depends({ [option_name("tls")] = true })
|
||||
|
||||
o = s:option(Value, option_name("tls_serverName"), translate("Domain"))
|
||||
o:depends({ [option_name("tls")] = true })
|
||||
o:depends({ [option_name("protocol")] = "hysteria"})
|
||||
o:depends({ [option_name("protocol")] = "tuic" })
|
||||
o:depends({ [option_name("protocol")] = "hysteria2" })
|
||||
|
||||
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 })
|
||||
o:depends({ [option_name("protocol")] = "hysteria"})
|
||||
o:depends({ [option_name("protocol")] = "tuic" })
|
||||
o:depends({ [option_name("protocol")] = "hysteria2" })
|
||||
|
||||
if singbox_tags:find("with_utls") then
|
||||
o = s:option(Flag, option_name("utls"), translate("uTLS"))
|
||||
|
||||
@@ -398,9 +398,8 @@ for key, value in pairs(s.fields) do
|
||||
s.fields[key].write = rm_prefix_write
|
||||
s.fields[key].remove = rm_prefix_remove
|
||||
end
|
||||
end
|
||||
|
||||
local deps = s.fields[key].deps
|
||||
local deps = s.fields[key].deps
|
||||
if #deps > 0 then
|
||||
for index, value in ipairs(deps) do
|
||||
deps[index]["type"] = type_name
|
||||
@@ -408,4 +407,5 @@ for key, value in pairs(s.fields) do
|
||||
else
|
||||
s.fields[key]:depends({ type = type_name })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -131,6 +131,9 @@ if singbox_tags:find("with_quic") then
|
||||
|
||||
o = s:option(Flag, option_name("hysteria_disable_mtu_discovery"), translate("Disable MTU detection"))
|
||||
o:depends({ [option_name("protocol")] = "hysteria" })
|
||||
|
||||
o = s:option(Value, option_name("hysteria_alpn"), translate("QUIC TLS ALPN"))
|
||||
o:depends({ [option_name("protocol")] = "hysteria" })
|
||||
end
|
||||
|
||||
if singbox_tags:find("with_quic") then
|
||||
@@ -245,6 +248,9 @@ o:depends({ [option_name("protocol")] = "trojan" })
|
||||
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:depends({ [option_name("protocol")] = "hysteria" })
|
||||
o:depends({ [option_name("protocol")] = "tuic" })
|
||||
o:depends({ [option_name("protocol")] = "hysteria2" })
|
||||
o.validate = function(self, value, t)
|
||||
if value and value ~= "" then
|
||||
if not nixio.fs.access(value) then
|
||||
@@ -259,6 +265,9 @@ 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:depends({ [option_name("protocol")] = "hysteria" })
|
||||
o:depends({ [option_name("protocol")] = "tuic" })
|
||||
o:depends({ [option_name("protocol")] = "hysteria2" })
|
||||
o.validate = function(self, value, t)
|
||||
if value and value ~= "" then
|
||||
if not nixio.fs.access(value) then
|
||||
|
||||
@@ -264,8 +264,8 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
|
||||
if node.protocol == "hysteria" then
|
||||
protocol_table = {
|
||||
up = node.hysteria_up_mbps .. " Mbps",
|
||||
down = node.hysteria_down_mbps .. " Mbps",
|
||||
up = node.hysteria_up_mbps .. " Mbps",
|
||||
down = node.hysteria_down_mbps .. " Mbps",
|
||||
up_mbps = tonumber(node.hysteria_up_mbps),
|
||||
down_mbps = tonumber(node.hysteria_down_mbps),
|
||||
obfs = node.hysteria_obfs,
|
||||
@@ -274,7 +274,14 @@ function gen_outbound(flag, node, tag, proxy_table)
|
||||
recv_window_conn = tonumber(node.hysteria_recv_window_conn),
|
||||
recv_window = tonumber(node.hysteria_recv_window),
|
||||
disable_mtu_discovery = (node.hysteria_disable_mtu_discovery == "1") and true or false,
|
||||
tls = tls,
|
||||
tls = {
|
||||
enabled = true,
|
||||
server_name = node.tls_serverName,
|
||||
insecure = (node.tls_allowInsecure == "1") and true or false,
|
||||
alpn = (node.hysteria_alpn and node.hysteria_alpn ~= "") and {
|
||||
node.hysteria_alpn
|
||||
} or nil
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
@@ -490,8 +497,8 @@ function gen_config_server(node)
|
||||
|
||||
if node.protocol == "hysteria" then
|
||||
protocol_table = {
|
||||
up = node.hysteria_up_mbps .. " Mbps",
|
||||
down = node.hysteria_down_mbps .. " Mbps",
|
||||
up = node.hysteria_up_mbps .. " Mbps",
|
||||
down = node.hysteria_down_mbps .. " Mbps",
|
||||
up_mbps = tonumber(node.hysteria_up_mbps),
|
||||
down_mbps = tonumber(node.hysteria_down_mbps),
|
||||
obfs = node.hysteria_obfs,
|
||||
@@ -506,7 +513,14 @@ function gen_config_server(node)
|
||||
recv_window_client = node.hysteria_recv_window_client and tonumber(node.hysteria_recv_window_client) or nil,
|
||||
max_conn_client = node.hysteria_max_conn_client and tonumber(node.hysteria_max_conn_client) or nil,
|
||||
disable_mtu_discovery = (node.hysteria_disable_mtu_discovery == "1") and true or false,
|
||||
tls = tls,
|
||||
tls = {
|
||||
enabled = true,
|
||||
certificate_path = node.tls_certificateFile,
|
||||
key_path = node.tls_keyFile,
|
||||
alpn = (node.hysteria_alpn and node.hysteria_alpn ~= "") and {
|
||||
node.hysteria_alpn
|
||||
} or nil
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
@@ -9,10 +9,10 @@ include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
PKG_NAME:=natflow
|
||||
PKG_VERSION:=20230902
|
||||
PKG_VERSION:=20230907
|
||||
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/ptpt52/natflow/tar.gz/$(PKG_VERSION)?
|
||||
PKG_HASH:=05beb1978963c38f4f7d1df91066b19523661001794e4e516fe8e5e2089eff68
|
||||
PKG_HASH:=0ee5394f2d1fc3aab1f2b52c19e43424244e4a9e5d18081082ec0699a7f45931
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
|
||||
PKG_MAINTAINER:=Chen Minqiang <ptpt52@gmail.com>
|
||||
|
||||
Reference in New Issue
Block a user