update 2023-04-07 16:21:24

This commit is contained in:
github-actions[bot] 2023-04-07 16:21:24 +08:00
parent 30f387f142
commit 573e989a66
20 changed files with 349 additions and 200 deletions

View File

@ -126,7 +126,7 @@ update_rules() {
yhosts_rules_local=`cat /usr/share/koolproxy/data/rules/yhosts.txt | sed -n '1p' | cut -d ":" -f2` yhosts_rules_local=`cat /usr/share/koolproxy/data/rules/yhosts.txt | sed -n '1p' | cut -d ":" -f2`
antiad_rules_local=`cat /usr/share/koolproxy/data/rules/antiad.txt | sed -n '2p' | cut -d "=" -f2` antiad_rules_local=`cat /usr/share/koolproxy/data/rules/antiad.txt | sed -n '2p' | cut -d "=" -f2`
koolproxy_rules_local=`cat /usr/share/koolproxy/data/rules/koolproxy.txt | sed -n '3p'|awk '{print $3,$4}'` koolproxy_rules_local=`cat /usr/share/koolproxy/data/rules/koolproxy.txt | sed -n '3p'|awk '{print $3,$4}'`
adgk_rules_local=`cat /usr/share/koolproxy/data/rules/adgk.txt | sed -n '1p'|awk '{print $3}'` adgk_rules_local=`cat /usr/share/koolproxy/data/rules/adgk.txt | sed -n '2p'|awk '{print $3}'`
echo $(date "+%F %T"): -------------------AdGuard规则 Version $adg_rules_local >>$LOGFILE echo $(date "+%F %T"): -------------------AdGuard规则 Version $adg_rules_local >>$LOGFILE
echo $(date "+%F %T"): -------------------Steven规则 Version $steven_rules_local >>$LOGFILE echo $(date "+%F %T"): -------------------Steven规则 Version $steven_rules_local >>$LOGFILE
echo $(date "+%F %T"): -------------------Yhosts规则 Version $yhosts_rules_local >>$LOGFILE echo $(date "+%F %T"): -------------------Yhosts规则 Version $yhosts_rules_local >>$LOGFILE

View File

@ -126,7 +126,7 @@ update_rules() {
yhosts_rules_local=`cat /usr/share/koolproxy/data/rules/yhosts.txt | sed -n '1p' | cut -d ":" -f2` yhosts_rules_local=`cat /usr/share/koolproxy/data/rules/yhosts.txt | sed -n '1p' | cut -d ":" -f2`
antiad_rules_local=`cat /usr/share/koolproxy/data/rules/antiad.txt | sed -n '2p' | cut -d "=" -f2` antiad_rules_local=`cat /usr/share/koolproxy/data/rules/antiad.txt | sed -n '2p' | cut -d "=" -f2`
koolproxy_rules_local=`cat /usr/share/koolproxy/data/rules/koolproxy.txt | sed -n '3p'|awk '{print $3,$4}'` koolproxy_rules_local=`cat /usr/share/koolproxy/data/rules/koolproxy.txt | sed -n '3p'|awk '{print $3,$4}'`
adgk_rules_local=`cat /usr/share/koolproxy/data/rules/adgk.txt | sed -n '1p'|awk '{print $3}'` adgk_rules_local=`cat /usr/share/koolproxy/data/rules/adgk.txt | sed -n '2p'|awk '{print $3}'`
echo $(date "+%F %T"): -------------------AdGuard规则 Version $adg_rules_local >>$LOGFILE echo $(date "+%F %T"): -------------------AdGuard规则 Version $adg_rules_local >>$LOGFILE
echo $(date "+%F %T"): -------------------Steven规则 Version $steven_rules_local >>$LOGFILE echo $(date "+%F %T"): -------------------Steven规则 Version $steven_rules_local >>$LOGFILE
echo $(date "+%F %T"): -------------------Yhosts规则 Version $yhosts_rules_local >>$LOGFILE echo $(date "+%F %T"): -------------------Yhosts规则 Version $yhosts_rules_local >>$LOGFILE

View File

@ -5,11 +5,12 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall2 PKG_NAME:=luci-app-passwall2
PKG_VERSION:=1.10 PKG_VERSION:=1.11
PKG_RELEASE:=6 PKG_RELEASE:=1
PKG_CONFIG_DEPENDS:= \ PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_Transparent_Proxy \ CONFIG_PACKAGE_$(PKG_NAME)_Transparent_Proxy \
CONFIG_PACKAGE_$(PKG_NAME)_Transparent_Proxy_Iptables-nft \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Brook \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Brook \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_Hysteria \
CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_IPv6_Nat \ CONFIG_PACKAGE_$(PKG_NAME)_INCLUDE_IPv6_Nat \
@ -52,6 +53,7 @@ menu "Configuration"
config PACKAGE_$(PKG_NAME)_Transparent_Proxy config PACKAGE_$(PKG_NAME)_Transparent_Proxy
bool "Transparent Proxy" bool "Transparent Proxy"
select PACKAGE_dnsmasq-full select PACKAGE_dnsmasq-full
select PACKAGE_dnsmasq_full_ipset
select PACKAGE_ipset select PACKAGE_ipset
select PACKAGE_iptables select PACKAGE_iptables
select PACKAGE_iptables-zz-legacy select PACKAGE_iptables-zz-legacy
@ -61,7 +63,21 @@ config PACKAGE_$(PKG_NAME)_Transparent_Proxy
select PACKAGE_iptables-mod-conntrack-extra select PACKAGE_iptables-mod-conntrack-extra
select PACKAGE_kmod-ipt-nat select PACKAGE_kmod-ipt-nat
depends on PACKAGE_$(PKG_NAME) depends on PACKAGE_$(PKG_NAME)
default y default y if ! PACKAGE_firewall4
config PACKAGE_$(PKG_NAME)_Transparent_Proxy_Iptables-nft
bool "Transparent Proxy Use Iptables-nft"
select PACKAGE_dnsmasq-full
select PACKAGE_dnsmasq_full_ipset
select PACKAGE_ipset
select PACKAGE_iptables-nft
select PACKAGE_iptables-mod-iprange
select PACKAGE_iptables-mod-socket
select PACKAGE_iptables-mod-tproxy
select PACKAGE_iptables-mod-conntrack-extra
select PACKAGE_kmod-ipt-nat
depends on PACKAGE_$(PKG_NAME)
default y if PACKAGE_firewall4
config PACKAGE_$(PKG_NAME)_INCLUDE_Brook config PACKAGE_$(PKG_NAME)_INCLUDE_Brook
bool "Include Brook" bool "Include Brook"

View File

@ -129,10 +129,21 @@ for k, e in ipairs(api.get_valid_nodes()) do
end end
-- 负载均衡列表 -- 负载均衡列表
balancing_node = s:option(DynamicList, "balancing_node", translate("Load balancing node list"), translate("Load balancing node list, <a target='_blank' href='https://toutyrater.github.io/routing/balance2.html'>document</a>")) local balancing_node = s:option(DynamicList, "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>"))
for k, v in pairs(nodes_table) do balancing_node:value(v.id, v.remarks) end for k, v in pairs(nodes_table) do balancing_node:value(v.id, v.remarks) end
balancing_node:depends("protocol", "_balancing") balancing_node:depends("protocol", "_balancing")
local balancingStrategy = s:option(ListValue, "balancingStrategy", translate("Balancing Strategy"))
balancingStrategy:depends("protocol", "_balancing")
balancingStrategy:value("random")
balancingStrategy:value("leastPing")
balancingStrategy.default = "random"
local probeInterval = s:option(Value, "probeInterval", translate("Probe Interval"))
probeInterval:depends("balancingStrategy", "leastPing")
probeInterval.default = "1m"
probeInterval.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.")
-- 分流 -- 分流
uci:foreach(appname, "shunt_rules", function(e) uci:foreach(appname, "shunt_rules", function(e)
if e[".name"] and e.remarks then if e[".name"] and e.remarks then
@ -192,13 +203,11 @@ domainStrategy.description = "<br /><ul><li>" .. translate("'AsIs': Only use dom
.. "</li><li>" .. translate("'IPIfNonMatch': When no rule matches current domain, resolves it into IP addresses (A or AAAA records) and try all rules again.") .. "</li><li>" .. translate("'IPIfNonMatch': When no rule matches current domain, resolves it into IP addresses (A or AAAA records) and try all rules again.")
.. "</li><li>" .. translate("'IPOnDemand': As long as there is a IP-based rule, resolves the domain into IP immediately.") .. "</li><li>" .. translate("'IPOnDemand': As long as there is a IP-based rule, resolves the domain into IP immediately.")
.. "</li></ul>" .. "</li></ul>"
domainStrategy:depends("protocol", "_balancing")
domainStrategy:depends("protocol", "_shunt") domainStrategy:depends("protocol", "_shunt")
domainMatcher = s:option(ListValue, "domainMatcher", translate("Domain matcher")) domainMatcher = s:option(ListValue, "domainMatcher", translate("Domain matcher"))
domainMatcher:value("hybrid") domainMatcher:value("hybrid")
domainMatcher:value("linear") domainMatcher:value("linear")
domainMatcher:depends("protocol", "_balancing")
domainMatcher:depends("protocol", "_shunt") domainMatcher:depends("protocol", "_shunt")
@ -544,9 +553,9 @@ xray_fingerprint:value("chrome")
xray_fingerprint:value("firefox") xray_fingerprint:value("firefox")
xray_fingerprint:value("safari") xray_fingerprint:value("safari")
xray_fingerprint:value("ios") xray_fingerprint:value("ios")
xray_fingerprint:value("android") --xray_fingerprint:value("android")
xray_fingerprint:value("edge") xray_fingerprint:value("edge")
xray_fingerprint:value("360") --xray_fingerprint:value("360")
xray_fingerprint:value("qq") xray_fingerprint:value("qq")
xray_fingerprint:value("random") xray_fingerprint:value("random")
xray_fingerprint:value("randomized") xray_fingerprint:value("randomized")
@ -579,9 +588,9 @@ reality_fingerprint:value("chrome")
reality_fingerprint:value("firefox") reality_fingerprint:value("firefox")
reality_fingerprint:value("safari") reality_fingerprint:value("safari")
reality_fingerprint:value("ios") reality_fingerprint:value("ios")
reality_fingerprint:value("android") --reality_fingerprint:value("android")
reality_fingerprint:value("edge") reality_fingerprint:value("edge")
reality_fingerprint:value("360") --reality_fingerprint:value("360")
reality_fingerprint:value("qq") reality_fingerprint:value("qq")
reality_fingerprint:value("random") reality_fingerprint:value("random")
reality_fingerprint:value("randomized") reality_fingerprint:value("randomized")
@ -638,6 +647,11 @@ wireguard_mtu = s:option(Value, "wireguard_mtu", translate("MTU"))
wireguard_mtu.default = "1420" wireguard_mtu.default = "1420"
wireguard_mtu:depends({ type = "Xray", protocol = "wireguard" }) wireguard_mtu:depends({ type = "Xray", protocol = "wireguard" })
if api.compare_versions(api.get_app_version("xray"), ">=", "1.8.0") then
wireguard_reserved = s:option(Value, "wireguard_reserved", translate("Reserved"))
wireguard_reserved:depends({ type = "Xray", protocol = "wireguard" })
end
wireguard_keepAlive = s:option(Value, "wireguard_keepAlive", translate("Keep Alive")) wireguard_keepAlive = s:option(Value, "wireguard_keepAlive", translate("Keep Alive"))
wireguard_keepAlive.default = "0" wireguard_keepAlive.default = "0"
wireguard_keepAlive:depends({ type = "Xray", protocol = "wireguard" }) wireguard_keepAlive:depends({ type = "Xray", protocol = "wireguard" })
@ -833,6 +847,9 @@ hysteria_hop_interval:depends("type", "Hysteria")
hysteria_disable_mtu_discovery = s:option(Flag, "hysteria_disable_mtu_discovery", translate("Disable MTU detection")) hysteria_disable_mtu_discovery = s:option(Flag, "hysteria_disable_mtu_discovery", translate("Disable MTU detection"))
hysteria_disable_mtu_discovery:depends("type", "Hysteria") hysteria_disable_mtu_discovery:depends("type", "Hysteria")
hysteria_lazy_start = s:option(Flag, "hysteria_lazy_start", translate("Lazy Start"))
hysteria_lazy_start:depends("type", "Hysteria")
protocol.validate = function(self, value) protocol.validate = function(self, value)
if value == "_shunt" or value == "_balancing" then if value == "_shunt" or value == "_balancing" then
address.rmempty = true address.rmempty = true

View File

@ -13,6 +13,17 @@ command_timeout = 300
LEDE_BOARD = nil LEDE_BOARD = nil
DISTRIB_TARGET = nil DISTRIB_TARGET = nil
LOG_FILE = "/tmp/log/passwall2.log"
function log(...)
local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
local f, err = io.open(LOG_FILE, "a")
if f and err == nil then
f:write(result .. "\n")
f:close()
end
end
function exec_call(cmd) function exec_call(cmd)
local process = io.popen(cmd .. '; echo -e "\n$?"') local process = io.popen(cmd .. '; echo -e "\n$?"')
local lines = {} local lines = {}
@ -355,7 +366,7 @@ function get_customed_path(e)
end end
function is_finded(e) function is_finded(e)
return luci.sys.exec('type -t -p "/bin/%s" -p "%s" "%s"' % {e, get_customed_path(e), e}) ~= "" and true or false return luci.sys.exec('type -t -p "/bin/%s" -p "/usr/bin/%s" -p "%s" "%s"' % {e, e, get_customed_path(e), e}) ~= "" and true or false
end end

View File

@ -74,6 +74,7 @@ function gen_config(var)
hop_interval = (node.hysteria_hop_interval) and tonumber(node.hysteria_hop_interval) or nil, hop_interval = (node.hysteria_hop_interval) and tonumber(node.hysteria_hop_interval) or nil,
disable_mtu_discovery = (node.hysteria_disable_mtu_discovery) and true or false, disable_mtu_discovery = (node.hysteria_disable_mtu_discovery) and true or false,
fast_open = (node.fast_open == "1") and true or false, fast_open = (node.fast_open == "1") and true or false,
lazy_start = (node.hysteria_lazy_start) and true or false,
socks5 = (local_socks_address and local_socks_port) and { socks5 = (local_socks_address and local_socks_port) and {
listen = local_socks_address .. ":" .. local_socks_port, listen = local_socks_address .. ":" .. local_socks_port,
timeout = 300, timeout = 300,

View File

@ -106,6 +106,14 @@ function gen_outbound(flag, node, tag, proxy_table)
end end
end end
if node.protocol == "wireguard" and node.wireguard_reserved then
local bytes = {}
node.wireguard_reserved:gsub("[^,]+", function(b)
bytes[#bytes+1] = tonumber(b)
end)
node.wireguard_reserved = #bytes > 0 and bytes or nil
end
result = { result = {
_flag_tag = node_id, _flag_tag = node_id,
_flag_proxy = proxy, _flag_proxy = proxy,
@ -230,7 +238,8 @@ function gen_outbound(flag, node, tag, proxy_table)
keepAlive = node.wireguard_keepAlive and tonumber(node.wireguard_keepAlive) or nil keepAlive = node.wireguard_keepAlive and tonumber(node.wireguard_keepAlive) or nil
} }
} or nil, } or nil,
mtu = (node.protocol == "wireguard" and node.wireguard_mtu) and tonumber(node.wireguard_mtu) or nil mtu = (node.protocol == "wireguard" and node.wireguard_mtu) and tonumber(node.wireguard_mtu) or nil,
reserved = (node.protocol == "wireguard" and node.wireguard_reserved) and node.wireguard_reserved or nil
} }
} }
local alpn = {} local alpn = {}
@ -522,6 +531,7 @@ function gen_config(var)
local inbounds = {} local inbounds = {}
local outbounds = {} local outbounds = {}
local routing = nil local routing = nil
local observatory = nil
if local_socks_port then if local_socks_port then
local inbound = { local inbound = {
@ -817,10 +827,18 @@ function gen_config(var)
local outbound = gen_outbound(flag, node) local outbound = gen_outbound(flag, node)
if outbound then table.insert(outbounds, outbound) end if outbound then table.insert(outbounds, outbound) end
end end
if node.balancingStrategy == "leastPing" then
observatory = {
subjectSelector = nodes,
probeInterval = node.probeInterval or "1m"
}
end
routing = { routing = {
domainStrategy = node.domainStrategy or "AsIs", balancers = {{
domainMatcher = node.domainMatcher or "hybrid", tag = "balancer",
balancers = {{tag = "balancer", selector = nodes}}, selector = nodes,
strategy = {type = node.balancingStrategy or "random"}
}},
rules = { rules = {
{type = "field", network = "tcp,udp", balancerTag = "balancer"} {type = "field", network = "tcp,udp", balancerTag = "balancer"}
} }
@ -1093,6 +1111,8 @@ function gen_config(var)
inbounds = inbounds, inbounds = inbounds,
-- 传出连接 -- 传出连接
outbounds = outbounds, outbounds = outbounds,
-- 连接观测
observatory = observatory,
-- 路由 -- 路由
routing = routing, routing = routing,
-- 本地策略 -- 本地策略
@ -1277,7 +1297,7 @@ function gen_dns_config(var)
dns = { dns = {
tag = "dns-in1", tag = "dns-in1",
hosts = {}, hosts = {},
disableCache = (dns_cache and dns_cache == "0") and true or false, disableCache = (dns_cache == "1") and false or true,
disableFallback = true, disableFallback = true,
disableFallbackIfMatch = true, disableFallbackIfMatch = true,
servers = {}, servers = {},

View File

@ -56,26 +56,18 @@ local has_xray = api.is_finded("xray")
return b64decsafe(v); return b64decsafe(v);
} }
function parseNodeUrl(url) { function parseNodeUrl(url) {
var m = url.match(/^(([^:\/?#]+:)?(?:\/\/((?:([^\/?#:]*)([^\/?#:]*)@)?([^\/?#:]*)(?::([^\/?#:]*))?)))?([^?#]*)(\?[^#]*)?(#.*)?$/), let protocol = url.substring(0, url.indexOf("://")) + ":"
r = { let str = "http" + url.substring(url.indexOf("://"))
hash: m[10] || "", // #asd const parsedUrl = new URL(str);
host: m[3] || "", // localhost:257 var r = {
hostname: m[6] || "", // localhost hash: parsedUrl.hash, // #asd
href: m[0] || "", // http://username:password@localhost:257/deploy/?asd=asd#asd host: parsedUrl.host, // localhost:257
origin: m[1] || "", // http://username:password@localhost:257 hostname: parsedUrl.hostname, // localhost
pathname: m[8] || (m[1] ? "/" : ""), // /deploy/ port: parsedUrl.port, // 257
port: m[7] || "", // 257 search: parsedUrl.search, // ?asd=asd
protocol: m[2] || "", // http: passwd: parsedUrl.username || parsedUrl.password // username
search: m[9] || "", // ?asd=asd };
passwd: m[4] || "", // username return r;
removed: m[5] || "" // password
};
if (r.protocol.length === 2) {
r.protocol = "file:///" + r.protocol.toUpperCase();
r.origin = r.protocol + "//" + r.host;
}
r.href = r.origin + r.pathname + r.search + r.hash;
return m && r;
} }
function buildUrl(btn, urlname, sid) { function buildUrl(btn, urlname, sid) {
@ -130,15 +122,25 @@ local has_xray = api.is_finded("xray")
opt.client = urlname.indexOf("server") === -1; opt.client = urlname.indexOf("server") === -1;
var v_type = opt.get("type").value; var v_type = opt.get("type").value;
var v_alias = opt.get("remarks"); var v_alias = opt.get("remarks");
var _address = ""
try {
var v_server = opt.get("address");
const ipv6Regex = /^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))$/;
if (ipv6Regex.test(v_server.value)) {
_address = "[" + v_server.value + "]"
} else {
_address = v_server.value
}
} catch(e) {
}
var url = null; var url = null;
if (v_type === "SS") { if (v_type === "SS") {
var v_server = opt.get("address");
var v_port = opt.get("port"); var v_port = opt.get("port");
var v_method = opt.get("ss_encrypt_method"); var v_method = opt.get("ss_encrypt_method");
var v_password = opt.get("password"); var v_password = opt.get("password");
url = b64encsafe(v_method.value + ":" + v_password.value) + "@" + url = b64encsafe(v_method.value + ":" + v_password.value) + "@" +
v_server.value + ":" + _address + ":" +
v_port.value + "/?"; v_port.value + "/?";
var params = ""; var params = "";
@ -160,7 +162,6 @@ local has_xray = api.is_finded("xray")
} }
url += params; url += params;
} else if (v_type === "SSR") { } else if (v_type === "SSR") {
var v_server = opt.get("address");
var v_port = opt.get("port"); var v_port = opt.get("port");
var v_protocol = opt.get("ssr_protocol"); var v_protocol = opt.get("ssr_protocol");
var v_method = opt.get("ssr_encrypt_method"); var v_method = opt.get("ssr_encrypt_method");
@ -168,7 +169,7 @@ local has_xray = api.is_finded("xray")
var v_password = opt.get("password"); var v_password = opt.get("password");
var v_obfs_param = opt.get("obfs_param"); var v_obfs_param = opt.get("obfs_param");
var v_protocol_param = opt.get("protocol_param"); var v_protocol_param = opt.get("protocol_param");
var ssr_str = v_server.value + ":" + var ssr_str = _address + ":" +
v_port.value + ":" + v_port.value + ":" +
v_protocol.value + ":" + v_protocol.value + ":" +
v_method.value + ":" + v_method.value + ":" +
@ -184,6 +185,7 @@ local has_xray = api.is_finded("xray")
info.v = "2"; info.v = "2";
info.ps = v_alias.value; info.ps = v_alias.value;
info.add = opt.get("address").value; info.add = opt.get("address").value;
//info.add = _address;
info.port = opt.get("port").value; info.port = opt.get("port").value;
info.id = opt.get("uuid").value; info.id = opt.get("uuid").value;
@ -196,8 +198,10 @@ local has_xray = api.is_finded("xray")
info.path = opt.get("h2_path").value; info.path = opt.get("h2_path").value;
} else if (v_transport === "tcp") { } else if (v_transport === "tcp") {
info.type = opt.get("tcp_guise").value; info.type = opt.get("tcp_guise").value;
info.host = opt.get("tcp_guise_http_host").value; if (info.type === "http") {
info.path = opt.get("tcp_guise_http_path").value; info.host = opt.get("tcp_guise_http_host").value;
info.path = opt.get("tcp_guise_http_path").value;
}
} else if (v_transport === "mkcp") { } else if (v_transport === "mkcp") {
v_transport = "kcp"; v_transport = "kcp";
info.type = opt.get("mkcp_guise").value; info.type = opt.get("mkcp_guise").value;
@ -223,10 +227,9 @@ local has_xray = api.is_finded("xray")
} else if ((v_type === "V2ray" || v_type === "Xray") && opt.get("protocol").value === "vless") { } else if ((v_type === "V2ray" || v_type === "Xray") && opt.get("protocol").value === "vless") {
v_type = "vless"; v_type = "vless";
var v_password = opt.get("uuid"); var v_password = opt.get("uuid");
var v_server = opt.get("address");
var v_port = opt.get("port"); var v_port = opt.get("port");
url = encodeURIComponent(v_password.value) + url = encodeURIComponent(v_password.value) +
"@" + v_server.value + "@" + _address +
":" + v_port.value + "?"; ":" + v_port.value + "?";
var params = ""; var params = "";
@ -235,6 +238,7 @@ local has_xray = api.is_finded("xray")
params += opt.query("host", "ws_host"); params += opt.query("host", "ws_host");
params += opt.query("path", "ws_path"); params += opt.query("path", "ws_path");
} else if (v_transport === "h2") { } else if (v_transport === "h2") {
v_transport = "http";
params += opt.query("host", "h2_host"); params += opt.query("host", "h2_host");
params += opt.query("path", "h2_path"); params += opt.query("path", "h2_path");
} else if (v_transport === "tcp") { } else if (v_transport === "tcp") {
@ -252,21 +256,32 @@ local has_xray = api.is_finded("xray")
//不知道是用path还是serviceName这里先这样吧 //不知道是用path还是serviceName这里先这样吧
params += opt.query("path", "grpc_serviceName"); params += opt.query("path", "grpc_serviceName");
params += opt.query("serviceName", "grpc_serviceName"); params += opt.query("serviceName", "grpc_serviceName");
params += opt.query("mode", "grpc_mode");
} }
params += "&type=" + v_transport; params += "&type=" + v_transport;
params += opt.query("encryption", "encryption"); params += opt.query("encryption", "encryption");
if (opt.get("tls").checked) { if (opt.get("tls").checked) {
var v_security = "tls"; var v_security = "tls";
params += "&security=" + v_security; if (opt.get("xray_fingerprint") && opt.get("xray_fingerprint").value != "") {
if (opt.get("tlsflow").value) { let v_fp = opt.get("xray_fingerprint").value;
params += "&fp=" + v_fp;
}
if(opt.get("reality") && opt.get("reality").checked) {
v_security = "reality";
if (opt.get("reality_fingerprint") && opt.get("reality_fingerprint").value != "") {
let v_fp = opt.get("reality_fingerprint").value;
params += "&fp=" + v_fp;
}
params += opt.query("pbk", "reality_publicKey");
params += opt.query("sid", "reality_shortId");
params += opt.query("spx", "reality_spiderX");
}
if (opt.get("tlsflow") && opt.get("tlsflow").value) {
let v_flow = opt.get("tlsflow").value; let v_flow = opt.get("tlsflow").value;
params += "&flow=" + v_flow; params += "&flow=" + v_flow;
} }
if (opt.get("xray_fingerprint").value && opt.get("xray_fingerprint").value != "") { params += "&security=" + v_security;
let v_fp = opt.get("xray_fingerprint").value
params += "&fp=" + v_fp;
}
params += opt.query("sni", "tls_serverName"); params += opt.query("sni", "tls_serverName");
} }
@ -280,10 +295,9 @@ local has_xray = api.is_finded("xray")
v_type = "trojan"; v_type = "trojan";
} }
var v_password = opt.get("password"); var v_password = opt.get("password");
var v_server = opt.get("address");
var v_port = opt.get("port"); var v_port = opt.get("port");
url = encodeURIComponent(v_password.value) + url = encodeURIComponent(v_password.value) +
"@" + v_server.value + "@" + _address +
":" + v_port.value + "/?"; ":" + v_port.value + "/?";
var params = ""; var params = "";
if (opt.get("tls").checked) { if (opt.get("tls").checked) {
@ -300,7 +314,6 @@ local has_xray = api.is_finded("xray")
var url = ""; var url = "";
var params = "?"; var params = "?";
var v_protocol = opt.get("brook_protocol"); var v_protocol = opt.get("brook_protocol");
var v_server = opt.get("address");
var v_port = opt.get("port"); var v_port = opt.get("port");
var v_password = opt.get("password"); var v_password = opt.get("password");
var b_protocol_value = v_protocol.value.split('client').join('server'); var b_protocol_value = v_protocol.value.split('client').join('server');
@ -319,14 +332,13 @@ local has_xray = api.is_finded("xray")
if (v_path_value.length > 1 && v_path_value.indexOf('/') < 0) { if (v_path_value.length > 1 && v_path_value.indexOf('/') < 0) {
v_path_value = '/' + v_path_value; v_path_value = '/' + v_path_value;
} }
params += "&" + url_protocol + "=" + encodeURIComponent(prefix + v_server.value + ":" + v_port.value + v_path_value); params += "&" + url_protocol + "=" + encodeURIComponent(prefix + _address + ":" + v_port.value + v_path_value);
} else { } else {
params += "&" + url_protocol + "=" + encodeURIComponent(v_server.value + ":" + v_port.value); params += "&" + url_protocol + "=" + encodeURIComponent(_address + ":" + v_port.value);
} }
url += url_protocol; url += url_protocol;
url += params; url += params;
} else if (v_type === "Hysteria") { } else if (v_type === "Hysteria") {
var v_server = opt.get("address");
var v_port = opt.get("port"); var v_port = opt.get("port");
var params = ""; var params = "";
params += opt.query("protocol", "hysteria_protocol"); params += opt.query("protocol", "hysteria_protocol");
@ -338,7 +350,7 @@ local has_xray = api.is_finded("xray")
params += opt.query("alpn", "hysteria_alpn"); params += opt.query("alpn", "hysteria_alpn");
params += opt.query("obfsParam", "hysteria_obfs"); params += opt.query("obfsParam", "hysteria_obfs");
var url = var url =
v_server.value + ":" + _address + ":" +
v_port.value + "?" + v_port.value + "?" +
params + params +
"#" + encodeURI(v_alias.value); "#" + encodeURI(v_alias.value);
@ -677,6 +689,7 @@ local has_xray = api.is_finded("xray")
if (queryParam.security) { if (queryParam.security) {
if (queryParam.security == "tls") { if (queryParam.security == "tls") {
opt.set('tls', true); opt.set('tls', true);
opt.set('reality', false)
opt.set('tlsflow', queryParam.flow || ''); opt.set('tlsflow', queryParam.flow || '');
opt.set('tls_serverName', queryParam.sni || ''); opt.set('tls_serverName', queryParam.sni || '');
opt.set('tls_allowInsecure', true); opt.set('tls_allowInsecure', true);
@ -688,10 +701,25 @@ local has_xray = api.is_finded("xray")
} }
} }
} }
if (queryParam.security == "reality") {
opt.set('tls', true);
opt.set('reality', true)
opt.set('tlsflow', queryParam.flow || '');
opt.set('tls_serverName', queryParam.sni || '');
if (queryParam.fp && queryParam.fp.trim() != "") {
opt.set('reality_fingerprint', queryParam.fp);
}
opt.set('reality_publicKey', queryParam.pbk || '');
opt.set('reality_shortId', queryParam.sid || '');
opt.set('reality_spiderX', queryParam.spx || '');
}
queryParam.type = queryParam.type.toLowerCase(); queryParam.type = queryParam.type.toLowerCase();
if (queryParam.type === "kcp" || queryParam.type === "mkcp") if (queryParam.type === "kcp" || queryParam.type === "mkcp")
queryParam.type = "mkcp" queryParam.type = "mkcp"
if (queryParam.type === "h2" || queryParam.type === "http")
queryParam.type = "h2"
opt.set('transport', queryParam.type); opt.set('transport', queryParam.type);
if (queryParam.type === "tcp") { if (queryParam.type === "tcp") {
opt.set('tcp_guise', queryParam.headerType || "none"); opt.set('tcp_guise', queryParam.headerType || "none");
@ -702,7 +730,7 @@ local has_xray = api.is_finded("xray")
} else if (queryParam.type === "ws") { } else if (queryParam.type === "ws") {
opt.set('ws_host', queryParam.host || ""); opt.set('ws_host', queryParam.host || "");
opt.set('ws_path', queryParam.path || ""); opt.set('ws_path', queryParam.path || "");
} else if (queryParam.type === "h2") { } else if (queryParam.type === "h2" || queryParam.type === "http") {
opt.set('h2_host', queryParam.host || ""); opt.set('h2_host', queryParam.host || "");
opt.set('h2_path', queryParam.path || ""); opt.set('h2_path', queryParam.path || "");
} else if (queryParam.type === "quic") { } else if (queryParam.type === "quic") {
@ -713,6 +741,7 @@ local has_xray = api.is_finded("xray")
opt.set('mkcp_guise', queryParam.headerType || "none"); opt.set('mkcp_guise', queryParam.headerType || "none");
} else if (queryParam.type === "grpc") { } else if (queryParam.type === "grpc") {
opt.set('grpc_serviceName', (queryParam.serviceName || queryParam.path) || ""); opt.set('grpc_serviceName', (queryParam.serviceName || queryParam.path) || "");
opt.set('grpc_mode', queryParam.mode);
} }
if (m.hash) { if (m.hash) {

View File

@ -274,6 +274,15 @@ msgstr "Xray 负载均衡"
msgid "V2ray_balancing" msgid "V2ray_balancing"
msgstr "V2ray 负载均衡" msgstr "V2ray 负载均衡"
msgid "Balancing Strategy"
msgstr "负载均衡策略"
msgid "Probe Interval"
msgstr "探测间隔"
msgid "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."
msgstr "发起探测的间隔。每经过这个时间,就会对一个服务器进行服务器状态检测。时间格式为数字+单位,比如<code>&quot;10s&quot;</code>, <code>&quot;2h45m&quot;</code>,支持的时间单位有 <code>ns</code><code>us</code><code>ms</code><code>s</code><code>m</code><code>h</code>,分别对应纳秒、微秒、毫秒、秒、分、时。"
msgid "Shunt" msgid "Shunt"
msgstr "分流" msgstr "分流"
@ -406,6 +415,9 @@ msgstr "QUIC 连接接收窗口"
msgid "Disable MTU detection" msgid "Disable MTU detection"
msgstr "禁用 MTU 检测" msgstr "禁用 MTU 检测"
msgid "Lazy Start"
msgstr "延迟启动"
msgid "Encrypt Method" msgid "Encrypt Method"
msgstr "加密" msgstr "加密"

View File

@ -70,6 +70,7 @@ config nodes 'myshunt'
option AD 'nil' option AD 'nil'
option BT '_direct' option BT '_direct'
option Netflix 'nil' option Netflix 'nil'
option OpenAI 'nil'
option TVB 'nil' option TVB 'nil'
option Proxy '_default' option Proxy '_default'
option China '_direct' option China '_direct'
@ -173,6 +174,10 @@ config shunt_rules 'Netflix'
option remarks 'Netflix' option remarks 'Netflix'
option network 'tcp,udp' option network 'tcp,udp'
option domain_list 'geosite:netflix' option domain_list 'geosite:netflix'
config shunt_rules 'OpenAI'
option remarks 'OpenAI'
option domain_list 'geosite:openai'
config shunt_rules 'TVB' config shunt_rules 'TVB'
option remarks 'TVB' option remarks 'TVB'

View File

@ -299,12 +299,12 @@ run_v2ray() {
} }
local buffer_size=$(config_t_get global_forwarding buffer_size) local buffer_size=$(config_t_get global_forwarding buffer_size)
[ -n "${buffer_size}" ] && _extra_param="${_extra_param} -buffer_size ${buffer_size}" [ -n "${buffer_size}" ] && _extra_param="${_extra_param} -buffer_size ${buffer_size}"
local protocol=$(config_n_get $node protocol) local protocol=$(config_n_get $node protocol)
[ "$protocol" == "_iface" ] && { [ "$protocol" == "_iface" ] && {
IFACES="$IFACES $(config_n_get $node iface)" IFACES="$IFACES $(config_n_get $node iface)"
} }
[ -n "$dns_listen_port" ] && { [ -n "$dns_listen_port" ] && {
V2RAY_DNS_DIRECT_CONFIG="${TMP_PATH}/${flag}_dns_direct.json" V2RAY_DNS_DIRECT_CONFIG="${TMP_PATH}/${flag}_dns_direct.json"
V2RAY_DNS_DIRECT_LOG="${TMP_PATH}/${flag}_dns_direct.log" V2RAY_DNS_DIRECT_LOG="${TMP_PATH}/${flag}_dns_direct.log"
@ -345,10 +345,10 @@ run_v2ray() {
esac esac
[ -n "$direct_dns_query_strategy" ] && V2RAY_DNS_DIRECT_ARGS="${V2RAY_DNS_DIRECT_ARGS} -dns_query_strategy ${direct_dns_query_strategy}" [ -n "$direct_dns_query_strategy" ] && V2RAY_DNS_DIRECT_ARGS="${V2RAY_DNS_DIRECT_ARGS} -dns_query_strategy ${direct_dns_query_strategy}"
[ -n "$direct_dns_client_ip" ] && V2RAY_DNS_DIRECT_ARGS="${V2RAY_DNS_DIRECT_ARGS} -dns_client_ip ${direct_dns_client_ip}" [ -n "$direct_dns_client_ip" ] && V2RAY_DNS_DIRECT_ARGS="${V2RAY_DNS_DIRECT_ARGS} -dns_client_ip ${direct_dns_client_ip}"
lua $UTIL_XRAY gen_dns_config ${V2RAY_DNS_DIRECT_ARGS} > $V2RAY_DNS_DIRECT_CONFIG lua $UTIL_XRAY gen_dns_config ${V2RAY_DNS_DIRECT_ARGS} > $V2RAY_DNS_DIRECT_CONFIG
ln_run "$(first_type $(config_t_get global_app ${type}_file) ${type})" ${type} $V2RAY_DNS_DIRECT_LOG run -c "$V2RAY_DNS_DIRECT_CONFIG" ln_run "$(first_type $(config_t_get global_app ${type}_file) ${type})" ${type} $V2RAY_DNS_DIRECT_LOG run -c "$V2RAY_DNS_DIRECT_CONFIG"
[ "$remote_dns_protocol" != "fakedns" ] && { [ "$remote_dns_protocol" != "fakedns" ] && {
V2RAY_DNS_REMOTE_CONFIG="${TMP_PATH}/${flag}_dns_remote.json" V2RAY_DNS_REMOTE_CONFIG="${TMP_PATH}/${flag}_dns_remote.json"
V2RAY_DNS_REMOTE_LOG="${TMP_PATH}/${flag}_dns_remote.log" V2RAY_DNS_REMOTE_LOG="${TMP_PATH}/${flag}_dns_remote.log"
@ -386,15 +386,15 @@ run_v2ray() {
V2RAY_DNS_REMOTE_ARGS="${V2RAY_DNS_REMOTE_ARGS} -remote_dns_fake 1" V2RAY_DNS_REMOTE_ARGS="${V2RAY_DNS_REMOTE_ARGS} -remote_dns_fake 1"
;; ;;
esac esac
[ -n "$remote_dns_query_strategy" ] && V2RAY_DNS_REMOTE_ARGS="${V2RAY_DNS_REMOTE_ARGS} -dns_query_strategy ${remote_dns_query_strategy}" [ -n "$remote_dns_query_strategy" ] && V2RAY_DNS_REMOTE_ARGS="${V2RAY_DNS_REMOTE_ARGS} -dns_query_strategy ${remote_dns_query_strategy}"
[ -n "$remote_dns_client_ip" ] && V2RAY_DNS_REMOTE_ARGS="${V2RAY_DNS_REMOTE_ARGS} -dns_client_ip ${remote_dns_client_ip}" [ -n "$remote_dns_client_ip" ] && V2RAY_DNS_REMOTE_ARGS="${V2RAY_DNS_REMOTE_ARGS} -dns_client_ip ${remote_dns_client_ip}"
V2RAY_DNS_REMOTE_ARGS="${V2RAY_DNS_REMOTE_ARGS} -remote_dns_outbound_socks_address 127.0.0.1 -remote_dns_outbound_socks_port ${socks_port}" V2RAY_DNS_REMOTE_ARGS="${V2RAY_DNS_REMOTE_ARGS} -remote_dns_outbound_socks_address 127.0.0.1 -remote_dns_outbound_socks_port ${socks_port}"
lua $UTIL_XRAY gen_dns_config ${V2RAY_DNS_REMOTE_ARGS} > $V2RAY_DNS_REMOTE_CONFIG lua $UTIL_XRAY gen_dns_config ${V2RAY_DNS_REMOTE_ARGS} > $V2RAY_DNS_REMOTE_CONFIG
ln_run "$(first_type $(config_t_get global_app ${type}_file) ${type})" ${type} $V2RAY_DNS_REMOTE_LOG run -c "$V2RAY_DNS_REMOTE_CONFIG" ln_run "$(first_type $(config_t_get global_app ${type}_file) ${type})" ${type} $V2RAY_DNS_REMOTE_LOG run -c "$V2RAY_DNS_REMOTE_CONFIG"
} }
[ -n "$dns_listen_port" ] && _extra_param="${_extra_param} -dns_listen_port ${dns_listen_port}" [ -n "$dns_listen_port" ] && _extra_param="${_extra_param} -dns_listen_port ${dns_listen_port}"
[ -n "$dns_cache" ] && _extra_param="${_extra_param} -dns_cache ${dns_cache}" [ -n "$dns_cache" ] && _extra_param="${_extra_param} -dns_cache ${dns_cache}"
_extra_param="${_extra_param} -dns_query_strategy UseIP" _extra_param="${_extra_param} -dns_query_strategy UseIP"
@ -405,7 +405,7 @@ run_v2ray() {
_extra_param="${_extra_param} -remote_dns_port ${dns_remote_listen_port} -remote_dns_udp_server 127.0.0.1" _extra_param="${_extra_param} -remote_dns_port ${dns_remote_listen_port} -remote_dns_udp_server 127.0.0.1"
fi fi
} }
lua $UTIL_XRAY gen_config -node $node -redir_port $redir_port -tcp_proxy_way $tcp_proxy_way -loglevel $loglevel ${_extra_param} > $config_file lua $UTIL_XRAY gen_config -node $node -redir_port $redir_port -tcp_proxy_way $tcp_proxy_way -loglevel $loglevel ${_extra_param} > $config_file
ln_run "$(first_type $(config_t_get global_app ${type}_file) ${type})" ${type} $log_file run -c "$config_file" ln_run "$(first_type $(config_t_get global_app ${type}_file) ${type})" ${type} $log_file run -c "$config_file"
} }
@ -441,7 +441,7 @@ run_socks() {
else else
error_msg="某种原因,此 Socks 服务的相关配置已失联,启动中止!" error_msg="某种原因,此 Socks 服务的相关配置已失联,启动中止!"
fi fi
if [ "$type" == "v2ray" ] || [ "$type" == "xray" ]; then if [ "$type" == "v2ray" ] || [ "$type" == "xray" ]; then
local protocol=$(config_n_get $node protocol) local protocol=$(config_n_get $node protocol)
if [ "$protocol" == "_balancing" ] || [ "$protocol" == "_shunt" ] || [ "$protocol" == "_iface" ]; then if [ "$protocol" == "_balancing" ] || [ "$protocol" == "_shunt" ] || [ "$protocol" == "_iface" ]; then
@ -558,7 +558,7 @@ node_switch() {
new_script_func=$(echo $script_func | sed "s#${now_node_arg}#node=${new_node}#g") new_script_func=$(echo $script_func | sed "s#${now_node_arg}#node=${new_node}#g")
${new_script_func} ${new_script_func}
echo $new_node > $TMP_ID_PATH/${flag} echo $new_node > $TMP_ID_PATH/${flag}
[ "$shunt_logic" != "0" ] && [ "$(config_n_get $new_node protocol nil)" = "_shunt" ] && { [ "$shunt_logic" != "0" ] && [ "$(config_n_get $new_node protocol nil)" = "_shunt" ] && {
echo $(config_n_get $new_node default_node nil) > $TMP_ID_PATH/${flag}_default echo $(config_n_get $new_node default_node nil) > $TMP_ID_PATH/${flag}_default
echo $(config_n_get $new_node main_node nil) > $TMP_ID_PATH/${flag}_main echo $(config_n_get $new_node main_node nil) > $TMP_ID_PATH/${flag}_main
@ -642,7 +642,7 @@ run_global() {
} }
msg="${msg}" msg="${msg}"
echolog ${msg} echolog ${msg}
source $APP_PATH/helper_dnsmasq.sh stretch source $APP_PATH/helper_dnsmasq.sh stretch
source $APP_PATH/helper_dnsmasq.sh add TMP_DNSMASQ_PATH=$TMP_DNSMASQ_PATH DNSMASQ_CONF_FILE=/tmp/dnsmasq.d/dnsmasq-passwall2.conf DEFAULT_DNS=$AUTO_DNS LOCAL_DNS=$LOCAL_DNS TUN_DNS=$TUN_DNS source $APP_PATH/helper_dnsmasq.sh add TMP_DNSMASQ_PATH=$TMP_DNSMASQ_PATH DNSMASQ_CONF_FILE=/tmp/dnsmasq.d/dnsmasq-passwall2.conf DEFAULT_DNS=$AUTO_DNS LOCAL_DNS=$LOCAL_DNS TUN_DNS=$TUN_DNS
@ -801,7 +801,7 @@ acl_app() {
sid=$(uci -q show "${CONFIG}.${item}" | grep "=acl_rule" | awk -F '=' '{print $1}' | awk -F '.' '{print $2}') sid=$(uci -q show "${CONFIG}.${item}" | grep "=acl_rule" | awk -F '=' '{print $1}' | awk -F '.' '{print $2}')
eval $(uci -q show "${CONFIG}.${item}" | cut -d'.' -sf 3-) eval $(uci -q show "${CONFIG}.${item}" | cut -d'.' -sf 3-)
[ "$enabled" = "1" ] || continue [ "$enabled" = "1" ] || continue
[ -z "${sources}" ] && continue [ -z "${sources}" ] && continue
for s in $sources; do for s in $sources; do
is_iprange=$(lua_api "iprange(\"${s}\")") is_iprange=$(lua_api "iprange(\"${s}\")")
@ -821,7 +821,7 @@ acl_app() {
[ -z "${rule_list}" ] && continue [ -z "${rule_list}" ] && continue
mkdir -p $TMP_ACL_PATH/$sid mkdir -p $TMP_ACL_PATH/$sid
echo -e "${rule_list}" | sed '/^$/d' > $TMP_ACL_PATH/$sid/rule_list echo -e "${rule_list}" | sed '/^$/d' > $TMP_ACL_PATH/$sid/rule_list
tcp_proxy_mode="global" tcp_proxy_mode="global"
udp_proxy_mode="global" udp_proxy_mode="global"
node=${node:-default} node=${node:-default}
@ -833,7 +833,7 @@ acl_app() {
remote_dns=${remote_dns:-1.1.1.1} remote_dns=${remote_dns:-1.1.1.1}
[ "$remote_dns_protocol" = "doh" ] && remote_dns=${remote_dns_doh:-https://1.1.1.1/dns-query} [ "$remote_dns_protocol" = "doh" ] && remote_dns=${remote_dns_doh:-https://1.1.1.1/dns-query}
remote_dns_query_strategy=${remote_dns_query_strategy:-UseIPv4} remote_dns_query_strategy=${remote_dns_query_strategy:-UseIPv4}
[ "$node" != "nil" ] && { [ "$node" != "nil" ] && {
if [ "$node" = "default" ]; then if [ "$node" = "default" ]; then
node=$NODE node=$NODE
@ -893,18 +893,18 @@ acl_app() {
start() { start() {
pgrep -f /tmp/etc/passwall2/bin > /dev/null 2>&1 && { pgrep -f /tmp/etc/passwall2/bin > /dev/null 2>&1 && {
echolog "程序已启动,无需重复启动!" echolog "程序已启动,先停止再重新启动!"
return 0 stop
} }
ulimit -n 65535 ulimit -n 65535
start_socks start_socks
local USE_TABLES="iptables" local USE_TABLES="iptables"
if [ -z "$(command -v iptables-legacy || command -v iptables)" ] || [ -z "$(command -v ipset)" ]; then if [ -z "$(command -v iptables-legacy || command -v iptables)" ] || [ -z "$(command -v ipset)" ]; then
echolog "系统未安装iptables或ipset无法透明代理" echolog "系统未安装iptables或ipset无法透明代理"
fi fi
[ "$ENABLED_DEFAULT_ACL" == 1 ] && run_global [ "$ENABLED_DEFAULT_ACL" == 1 ] && run_global
source $APP_PATH/${USE_TABLES}.sh start source $APP_PATH/${USE_TABLES}.sh start
[ "$ENABLED_DEFAULT_ACL" == 1 ] && source $APP_PATH/helper_dnsmasq.sh logic_restart [ "$ENABLED_DEFAULT_ACL" == 1 ] && source $APP_PATH/helper_dnsmasq.sh logic_restart

View File

@ -21,14 +21,10 @@ local geosite_api = ucic:get_first(name, 'global_rules', "geosite_url", "https:/
local log = function(...) local log = function(...)
if arg1 then if arg1 then
local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
if arg1 == "log" then if arg1 == "log" then
local f, err = io.open("/tmp/log/passwall2.log", "a") api.log(...)
if f and err == nil then
f:write(result .. "\n")
f:close()
end
elseif arg1 == "print" then elseif arg1 == "print" then
local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
print(result) print(result)
end end
end end

View File

@ -80,15 +80,11 @@ local nodeResult = {} -- update result
local debug = false local debug = false
local log = function(...) local log = function(...)
local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
if debug == true then if debug == true then
local result = os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({...}, " ")
print(result) print(result)
else else
local f, err = io.open("/tmp/log/" .. appname .. ".log", "a") api.log(...)
if f and err == nil then
f:write(result .. "\n")
f:close()
end
end end
end end
@ -328,15 +324,17 @@ local function processData(szType, content, add_mode, add_from)
add_mode = add_mode, --0为手动配置,1为导入,2为订阅 add_mode = add_mode, --0为手动配置,1为导入,2为订阅
add_from = add_from add_from = add_from
} }
--ssr://base64(host:port:protocol:method:obfs:base64pass/?obfsparam=base64param&protoparam=base64param&remarks=base64remarks&group=base64group&udpport=0&uot=0)
if szType == 'ssr' then if szType == 'ssr' then
result.type = "SSR"
local dat = split(content, "/%?") local dat = split(content, "/%?")
local hostInfo = split(dat[1], ':') local hostInfo = split(dat[1], ':')
result.type = "SSR" if dat[1]:match('%[(.*)%]') then
result.address = "" result.address = dat[1]:match('%[(.*)%]')
for i=1,#hostInfo-5,1 do else
result.address = result.address .. hostInfo[i] .. ":" result.address = hostInfo[#hostInfo-5]
end end
result.address = string.sub(result.address, 0, #result.address-1)
result.port = hostInfo[#hostInfo-4] result.port = hostInfo[#hostInfo-4]
result.protocol = hostInfo[#hostInfo-3] result.protocol = hostInfo[#hostInfo-3]
result.method = hostInfo[#hostInfo-2] result.method = hostInfo[#hostInfo-2]
@ -410,6 +408,15 @@ local function processData(szType, content, add_mode, add_from)
result.tls = "0" result.tls = "0"
end end
elseif szType == "ss" then elseif szType == "ss" then
result.type = "SS"
--SS-URI = "ss://" userinfo "@" hostname ":" port [ "/" ] [ "?" plugin ] [ "#" tag ]
--userinfo = websafe-base64-encode-utf8(method ":" password)
--ss://YWVzLTEyOC1nY206dGVzdA@192.168.100.1:8888#Example1
--ss://cmM0LW1kNTpwYXNzd2Q@192.168.100.1:8888/?plugin=obfs-local%3Bobfs%3Dhttp#Example2
--ss://2022-blake3-aes-256-gcm:YctPZ6U7xPPcU%2Bgp3u%2B0tx%2FtRizJN9K8y%2BuKlW2qjlI%3D@192.168.100.1:8888#Example3
--ss://2022-blake3-aes-256-gcm:YctPZ6U7xPPcU%2Bgp3u%2B0tx%2FtRizJN9K8y%2BuKlW2qjlI%3D@192.168.100.1:8888/?plugin=v2ray-plugin%3Bserver#Example3
local idx_sp = 0 local idx_sp = 0
local alias = "" local alias = ""
if content:find("#") then if content:find("#") then
@ -418,28 +425,9 @@ local function processData(szType, content, add_mode, add_from)
end end
result.remarks = UrlDecode(alias) result.remarks = UrlDecode(alias)
local info = content:sub(1, idx_sp - 1) local info = content:sub(1, idx_sp - 1)
local hostInfo = split(base64Decode(info), "@") if info:find("/%?") then
local hostInfoLen = #hostInfo local find_index = info:find("/%?")
local host = nil local query = split(info, "/%?")
local userinfo = nil
if hostInfoLen > 2 then
host = split(hostInfo[hostInfoLen], ":")
userinfo = {}
for i = 1, hostInfoLen - 1 do
tinsert(userinfo, hostInfo[i])
end
userinfo = table.concat(userinfo, '@')
else
host = split(hostInfo[2], ":")
userinfo = base64Decode(hostInfo[1])
end
local method = userinfo:sub(1, userinfo:find(":") - 1)
local password = userinfo:sub(userinfo:find(":") + 1, #userinfo)
result.type = "SS"
result.address = host[1]
if host[2] and host[2]:find("/%?") then
local query = split(host[2], "/%?")
result.port = query[1]
local params = {} local params = {}
for _, v in pairs(split(query[2], '&')) do for _, v in pairs(split(query[2], '&')) do
local t = split(v, '=') local t = split(v, '=')
@ -459,39 +447,70 @@ local function processData(szType, content, add_mode, add_from)
if result.plugin and result.plugin == "simple-obfs" then if result.plugin and result.plugin == "simple-obfs" then
result.plugin = "obfs-local" result.plugin = "obfs-local"
end end
else info = info:sub(1, find_index - 1)
result.port = host[2]
end end
result.method = method
result.password = password
local aead = false local hostInfo = split(base64Decode(info), "@")
for k, v in ipairs({"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305"}) do if hostInfo and #hostInfo > 0 then
if method:lower() == v:lower() then local host_port = hostInfo[#hostInfo]
aead = true -- [2001:4860:4860::8888]:443
-- 8.8.8.8:443
if host_port:find(":") then
local sp = split(host_port, ":")
result.port = sp[#sp]
if api.is_ipv6addrport(host_port) then
result.address = api.get_ipv6_only(host_port)
else
result.address = sp[1]
end
else
result.address = host_port
end end
end
if aead then local userinfo = nil
if ss_aead_type_default == "shadowsocks-libev" and has_ss then if #hostInfo > 2 then
result.type = "SS" userinfo = {}
elseif ss_aead_type_default == "shadowsocks-rust" and has_ss_rust then for i = 1, #hostInfo - 1 do
result.type = 'SS-Rust' tinsert(userinfo, hostInfo[i])
if method:lower() == "chacha20-poly1305" then
result.method = "chacha20-ietf-poly1305"
end end
elseif ss_aead_type_default == "v2ray" and has_v2ray and not result.plugin then userinfo = table.concat(userinfo, '@')
result.type = 'V2ray' else
result.protocol = 'shadowsocks' userinfo = base64Decode(hostInfo[1])
result.transport = 'tcp' end
if method:lower() == "chacha20-ietf-poly1305" then
result.method = "chacha20-poly1305" local method = userinfo:sub(1, userinfo:find(":") - 1)
local password = userinfo:sub(userinfo:find(":") + 1, #userinfo)
result.method = method
result.password = password
local aead = false
for k, v in ipairs({"aes-128-gcm", "aes-256-gcm", "chacha20-poly1305", "chacha20-ietf-poly1305"}) do
if method:lower() == v:lower() then
aead = true
end end
elseif ss_aead_type_default == "xray" and has_xray and not result.plugin then end
result.type = 'Xray' if aead then
result.protocol = 'shadowsocks' if ss_aead_type_default == "shadowsocks-libev" and has_ss then
result.transport = 'tcp' result.type = "SS"
if method:lower() == "chacha20-ietf-poly1305" then elseif ss_aead_type_default == "shadowsocks-rust" and has_ss_rust then
result.method = "chacha20-poly1305" result.type = 'SS-Rust'
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'
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'
result.transport = 'tcp'
if method:lower() == "chacha20-ietf-poly1305" then
result.method = "chacha20-poly1305"
end
end end
end end
end end
@ -513,33 +532,28 @@ local function processData(szType, content, add_mode, add_from)
result.password = UrlDecode(Info[1]) result.password = UrlDecode(Info[1])
local port = "443" local port = "443"
Info[2] = (Info[2] or ""):gsub("/%?", "?") Info[2] = (Info[2] or ""):gsub("/%?", "?")
local hostInfo = nil
if Info[2]:find(":") then
hostInfo = split(Info[2], ":")
result.address = hostInfo[1]
local idx_port = 2
if hostInfo[2]:find("?") then
hostInfo = split(hostInfo[2], "?")
idx_port = 1
end
if hostInfo[idx_port] ~= "" then port = hostInfo[idx_port] end
else
if Info[2]:find("?") then
hostInfo = split(Info[2], "?")
end
result.address = hostInfo and hostInfo[1] or Info[2]
end
local peer, sni = nil, ""
local allowInsecure = allowInsecure_default
local query = split(Info[2], "?") local query = split(Info[2], "?")
local host_port = query[1]
local params = {} local params = {}
for _, v in pairs(split(query[2], '&')) do for _, v in pairs(split(query[2], '&')) do
local t = split(v, '=') local t = split(v, '=')
params[string.lower(t[1])] = UrlDecode(t[2]) params[string.lower(t[1])] = UrlDecode(t[2])
end end
if params.allowinsecure then -- [2001:4860:4860::8888]:443
allowInsecure = params.allowinsecure -- 8.8.8.8:443
if host_port:find(":") then
local sp = split(host_port, ":")
port = sp[#sp]
if api.is_ipv6addrport(host_port) then
result.address = api.get_ipv6_only(host_port)
else
result.address = sp[1]
end
else
result.address = host_port
end end
local peer, sni = nil, ""
if params.peer then peer = params.peer end if params.peer then peer = params.peer end
sni = params.sni and params.sni or "" sni = params.sni and params.sni or ""
if params.ws and params.ws == "1" then if params.ws and params.ws == "1" then
@ -551,7 +565,16 @@ local function processData(szType, content, add_mode, add_from)
result.port = port result.port = port
result.tls = '1' result.tls = '1'
result.tls_serverName = peer and peer or sni result.tls_serverName = peer and peer or sni
result.tls_allowInsecure = allowInsecure and "1" or "0" if params.allowinsecure then
if params.allowinsecure == "1" or params.allowinsecure == "0" then
result.tls_allowInsecure = params.allowinsecure
else
result.tls_allowInsecure = string.lower(params.allowinsecure) == "true" and "1" or "0"
end
--log(result.remarks .. ' 使用节点AllowInsecure设定: '.. result.tls_allowInsecure)
else
result.tls_allowInsecure = allowInsecure_default and "1" or "0"
end
end end
elseif szType == "ssd" then elseif szType == "ssd" then
result.type = "SS" result.type = "SS"
@ -581,36 +604,34 @@ local function processData(szType, content, add_mode, add_from)
result.uuid = UrlDecode(Info[1]) result.uuid = UrlDecode(Info[1])
local port = "443" local port = "443"
Info[2] = (Info[2] or ""):gsub("/%?", "?") Info[2] = (Info[2] or ""):gsub("/%?", "?")
local hostInfo = nil
if Info[2]:find(":") then
hostInfo = split(Info[2], ":")
result.address = hostInfo[1]
local idx_port = 2
if hostInfo[2]:find("?") then
hostInfo = split(hostInfo[2], "?")
idx_port = 1
end
if hostInfo[idx_port] ~= "" then port = hostInfo[idx_port] end
else
if Info[2]:find("?") then
hostInfo = split(Info[2], "?")
end
result.address = hostInfo and hostInfo[1] or Info[2]
end
local query = split(Info[2], "?") local query = split(Info[2], "?")
local host_port = query[1]
local params = {} local params = {}
for _, v in pairs(split(query[2], '&')) do for _, v in pairs(split(query[2], '&')) do
local t = split(v, '=') local t = split(v, '=')
params[t[1]] = UrlDecode(t[2]) params[t[1]] = UrlDecode(t[2])
end end
-- [2001:4860:4860::8888]:443
-- 8.8.8.8:443
if host_port:find(":") then
local sp = split(host_port, ":")
port = sp[#sp]
if api.is_ipv6addrport(host_port) then
result.address = api.get_ipv6_only(host_port)
else
result.address = sp[1]
end
else
result.address = host_port
end
params.type = string.lower(params.type) params.type = string.lower(params.type)
if params.type == 'ws' then if params.type == 'ws' then
result.ws_host = params.host result.ws_host = params.host
result.ws_path = params.path result.ws_path = params.path
end end
if params.type == 'h2' then if params.type == 'h2' or params.type == 'http' then
params.type = "h2"
result.h2_host = params.host result.h2_host = params.host
result.h2_path = params.path result.h2_path = params.path
end end
@ -637,17 +658,24 @@ local function processData(szType, content, add_mode, add_from)
if params.type == 'grpc' then if params.type == 'grpc' then
if params.path then result.grpc_serviceName = params.path end if params.path then result.grpc_serviceName = params.path end
if params.serviceName then result.grpc_serviceName = params.serviceName end if params.serviceName then result.grpc_serviceName = params.serviceName end
result.grpc_mode = params.mode
end end
result.transport = params.type result.transport = params.type
result.encryption = params.encryption or "none" result.encryption = params.encryption or "none"
result.tls = "0" result.tls = "0"
if params.security == "tls" then if params.security == "tls" or params.security == "reality" then
result.tls = "1" result.tls = "1"
result.tlsflow = params.flow or nil result.tlsflow = params.flow or nil
result.tls_serverName = (params.sni and params.sni ~= "") and params.sni or params.host result.tls_serverName = (params.sni and params.sni ~= "") and params.sni or params.host
result.fingerprint = (params.fp and params.fp ~= "") and params.fp or "chrome" result.fingerprint = (params.fp and params.fp ~= "") and params.fp or "chrome"
if params.security == "reality" then
result.reality = "1"
result.reality_publicKey = params.pbk or nil
result.reality_shortId = params.sid or nil
result.reality_spiderX = params.spx or nil
end
end end
result.port = port result.port = port
@ -664,9 +692,7 @@ local function processData(szType, content, add_mode, add_from)
result.type = "Hysteria" result.type = "Hysteria"
local dat = split(content, '%?') local dat = split(content, '%?')
local hostInfo = split(dat[1], ':') local host_port = dat[1]
result.address = hostInfo[1]
result.port = hostInfo[2]
local params = {} local params = {}
for _, v in pairs(split(dat[2], '&')) do for _, v in pairs(split(dat[2], '&')) do
local t = split(v, '=') local t = split(v, '=')
@ -674,6 +700,19 @@ local function processData(szType, content, add_mode, add_from)
params[t[1]] = t[2] params[t[1]] = t[2]
end end
end end
-- [2001:4860:4860::8888]:443
-- 8.8.8.8:443
if host_port:find(":") then
local sp = split(host_port, ":")
result.port = sp[#sp]
if api.is_ipv6addrport(host_port) then
result.address = api.get_ipv6_only(host_port)
else
result.address = sp[1]
end
else
result.address = host_port
end
result.protocol = params.protocol result.protocol = params.protocol
result.hysteria_obfs = params.obfsParam result.hysteria_obfs = params.obfsParam
result.hysteria_auth_type = "string" result.hysteria_auth_type = "string"
@ -990,8 +1029,8 @@ local function parse_link(raw, add_mode, add_from)
if result then if result then
if not result.type then if not result.type then
log('丢弃节点:' .. result.remarks .. ",找不到可使用二进制.") log('丢弃节点:' .. result.remarks .. ",找不到可使用二进制.")
elseif (add_mode == "2" and is_filter_keyword(result.remarks)) or not result.address or result.remarks == "NULL" or result.address=="127.0.0.1" or elseif (add_mode == "2" and is_filter_keyword(result.remarks)) or not result.address or result.remarks == "NULL" or result.address == "127.0.0.1" or
(not datatypes.hostname(result.address) and not (datatypes.ipmask4(result.address) or datatypes.ipmask6(result.address))) then (not datatypes.hostname(result.address) and not (api.is_ip(result.address))) then
log('丢弃过滤节点: ' .. result.type .. ' 节点, ' .. result.remarks) log('丢弃过滤节点: ' .. result.type .. ' 节点, ' .. result.remarks)
else else
tinsert(node_list, result) tinsert(node_list, result)

View File

@ -9,10 +9,13 @@ LUCI_TITLE:=LuCI support for quickstart
LUCI_DEPENDS:=+quickstart +luci-app-store LUCI_DEPENDS:=+quickstart +luci-app-store
LUCI_PKGARCH:=all LUCI_PKGARCH:=all
PKG_VERSION:=0.6.9-4 PKG_VERSION:=0.7.2-1
# PKG_RELEASE MUST be empty for luci.mk # PKG_RELEASE MUST be empty for luci.mk
PKG_RELEASE:= PKG_RELEASE:=
LUCI_MINIFY_CSS:=0
LUCI_MINIFY_JS:=0
include $(TOPDIR)/feeds/luci/luci.mk include $(TOPDIR)/feeds/luci/luci.mk
# call BuildPackage - OpenWrt buildroot signature # call BuildPackage - OpenWrt buildroot signature

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -10,11 +10,11 @@ include $(TOPDIR)/rules.mk
PKG_ARCH_quickstart:=$(ARCH) PKG_ARCH_quickstart:=$(ARCH)
PKG_NAME:=quickstart PKG_NAME:=quickstart
PKG_VERSION:=0.6.11 PKG_VERSION:=0.7.3
PKG_RELEASE:=2 PKG_RELEASE:=1
PKG_SOURCE:=$(PKG_NAME)-binary-$(PKG_VERSION).tar.gz PKG_SOURCE:=$(PKG_NAME)-binary-$(PKG_VERSION).tar.gz
PKG_SOURCE_URL:=https://fw.koolcenter.com/binary/quickstart/ PKG_SOURCE_URL:=https://fw.koolcenter.com/binary/quickstart/
PKG_HASH:=f6cbc4a8dab3c5e659b45ffda617df94ea81cf5e9e07dbe88183036167b9bfb5 PKG_HASH:=65c14deccf7afb8179a347e31a6f1e5d20333e7b01f9003837abae15c3955ada
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-binary-$(PKG_VERSION) PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-binary-$(PKG_VERSION)