mirror of
https://github.com/kenzok8/small-package.git
synced 2026-02-06 14:56:34 +08:00
update 2026-01-14 04:30:07
This commit is contained in:
@@ -334,10 +334,7 @@ function connect_status()
|
||||
local proxy_mode = uci:get(appname, "@global[0]", "tcp_proxy_mode") or "proxy"
|
||||
local localhost_proxy = uci:get(appname, "@global[0]", "localhost_proxy") or "1"
|
||||
local socks_server = (localhost_proxy == "0") and api.get_cache_var("GLOBAL_TCP_SOCKS_server") or ""
|
||||
-- 兼容 curl 8.6 time_starttransfer 错误
|
||||
local curl_ver = api.get_bin_version_cache("/usr/bin/curl", "-V 2>/dev/null | head -n 1 | awk '{print $2}' | cut -d. -f1,2 | tr -d ' \n'") or "0"
|
||||
url = (curl_ver == "8.6") and "-w %{http_code}:%{time_appconnect} https://" .. url
|
||||
or "-w %{http_code}:%{time_starttransfer} http://" .. url
|
||||
url = "-w %{http_code}:%{time_pretransfer} " .. url
|
||||
if socks_server and socks_server ~= "" then
|
||||
if (chn_list == "proxy" and gfw_list == "0" and proxy_mode ~= "proxy" and baidu ~= nil) or (chn_list == "0" and gfw_list == "0" and proxy_mode == "proxy") then
|
||||
-- 中国列表+百度 or 全局
|
||||
|
||||
@@ -682,13 +682,36 @@ o.default = "proxy"
|
||||
o = s:taboption("Proxy", DummyValue, "switch_mode", " ")
|
||||
o.template = appname .. "/global/proxy"
|
||||
|
||||
o = s:taboption("Proxy", Flag, "localhost_proxy", translate("Localhost Proxy"), translate("When selected, localhost can transparent proxy."))
|
||||
o.default = "1"
|
||||
o.rmempty = false
|
||||
---- Check the transparent proxy component
|
||||
local handle = io.popen("lsmod")
|
||||
local mods = ""
|
||||
if handle then
|
||||
mods = handle:read("*a") or ""
|
||||
handle:close()
|
||||
end
|
||||
|
||||
o = s:taboption("Proxy", Flag, "client_proxy", translate("Client Proxy"), translate("When selected, devices in LAN can transparent proxy. Otherwise, it will not be proxy. But you can still use access control to allow the designated device to proxy."))
|
||||
o.default = "1"
|
||||
o.rmempty = false
|
||||
if (mods:find("REDIRECT") and mods:find("TPROXY")) or (mods:find("nft_redir") and mods:find("nft_tproxy")) then
|
||||
o = s:taboption("Proxy", Flag, "localhost_proxy", translate("Localhost Proxy"), translate("When selected, localhost can transparent proxy."))
|
||||
o.default = "1"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("Proxy", Flag, "client_proxy", translate("Client Proxy"), translate("When selected, devices in LAN can transparent proxy. Otherwise, it will not be proxy. But you can still use access control to allow the designated device to proxy."))
|
||||
o.default = "1"
|
||||
o.rmempty = false
|
||||
else
|
||||
local html = string.format([[<div class="cbi-checkbox"><input class="cbi-input-checkbox" type="checkbox" disabled></div><div class="cbi-value-description"><font color="red">%s</font></div>]], translate("Missing components, transparent proxy is unavailable."))
|
||||
o = s:taboption("Proxy", DummyValue, "localhost_proxy", translate("Localhost Proxy"))
|
||||
o.rawhtml = true
|
||||
function o.cfgvalue(self, section)
|
||||
return html
|
||||
end
|
||||
|
||||
o = s:taboption("Proxy", DummyValue, "client_proxy", translate("Client Proxy"))
|
||||
o.rawhtml = true
|
||||
function o.cfgvalue(self, section)
|
||||
return html
|
||||
end
|
||||
end
|
||||
|
||||
o = s:taboption("Proxy", DummyValue, "_proxy_tips", " ")
|
||||
o.rawhtml = true
|
||||
|
||||
@@ -124,7 +124,15 @@ if has_fw4 then
|
||||
o:value("1", "NFtables")
|
||||
end
|
||||
|
||||
if (os.execute("lsmod | grep -i REDIRECT >/dev/null") == 0 and os.execute("lsmod | grep -i TPROXY >/dev/null") == 0) or (os.execute("lsmod | grep -i nft_redir >/dev/null") == 0 and os.execute("lsmod | grep -i nft_tproxy >/dev/null") == 0) then
|
||||
---- Check the transparent proxy component
|
||||
local handle = io.popen("lsmod")
|
||||
local mods = ""
|
||||
if handle then
|
||||
mods = handle:read("*a") or ""
|
||||
handle:close()
|
||||
end
|
||||
|
||||
if (mods:find("REDIRECT") and mods:find("TPROXY")) or (mods:find("nft_redir") and mods:find("nft_tproxy")) then
|
||||
o = s:option(ListValue, "tcp_proxy_way", translate("TCP Proxy Way"))
|
||||
o.default = "redirect"
|
||||
o:value("redirect", "REDIRECT")
|
||||
@@ -142,7 +150,7 @@ if (os.execute("lsmod | grep -i REDIRECT >/dev/null") == 0 and os.execute("lsmod
|
||||
self.map:set(section, "tcp_proxy_way", value)
|
||||
end
|
||||
|
||||
if os.execute("lsmod | grep -i ip6table_mangle >/dev/null") == 0 or os.execute("lsmod | grep -i nft_tproxy >/dev/null") == 0 then
|
||||
if mods:find("ip6table_mangle") or mods:find("nft_tproxy") then
|
||||
---- IPv6 TProxy
|
||||
o = s:option(Flag, "ipv6_tproxy", translate("IPv6 TProxy"),
|
||||
"<font color='red'>" .. translate(
|
||||
|
||||
@@ -138,7 +138,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-1-4 check" onclick="check_connect('baidu', 'http://www.baidu.com')">
|
||||
<div class="pure-u-1-4 check" onclick="check_connect('baidu', 'https://www.baidu.com')">
|
||||
<div class="block pure-g">
|
||||
<div class="pure-u-1-3">
|
||||
<div class="img-con">
|
||||
@@ -150,7 +150,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-1-4 check" onclick="check_connect('google', 'http://www.google.com/generate_204')">
|
||||
<div class="pure-u-1-4 check" onclick="check_connect('google', 'https://www.google.com/generate_204')">
|
||||
<div class="block pure-g">
|
||||
<div class="pure-u-1-3">
|
||||
<div class="img-con">
|
||||
@@ -162,7 +162,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-1-4 check" onclick="check_connect('github', 'http://github.com')">
|
||||
<div class="pure-u-1-4 check" onclick="check_connect('github', 'https://github.com')">
|
||||
<div class="block pure-g">
|
||||
<div class="pure-u-1-3">
|
||||
<div class="img-con">
|
||||
@@ -174,7 +174,7 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="pure-u-1-4 check" onclick="check_connect('instagram', 'http://www.instagram.com')">
|
||||
<div class="pure-u-1-4 check" onclick="check_connect('instagram', 'https://www.instagram.com')">
|
||||
<div class="block pure-g">
|
||||
<div class="pure-u-1-3">
|
||||
<div class="img-con">
|
||||
|
||||
@@ -352,6 +352,9 @@ msgstr "客户端代理"
|
||||
msgid "When selected, devices in LAN can transparent proxy. Otherwise, it will not be proxy. But you can still use access control to allow the designated device to proxy."
|
||||
msgstr "当勾选时,局域网内的设备可以透明代理。否则,将不代理。但您仍然可以使用访问控制允许指定的设备代理。"
|
||||
|
||||
msgid "Missing components, transparent proxy is unavailable."
|
||||
msgstr "缺少组件,透明代理不可用。"
|
||||
|
||||
msgid "Want different devices to use different proxy modes/ports/nodes? Please use access control."
|
||||
msgstr "希望不同设备使用不同的代理模式/端口/节点?请使用访问控制。"
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ url_test_node() {
|
||||
fi
|
||||
sleep 1s
|
||||
local probeUrl=$(config_t_get global_other url_test_url https://www.google.com/generate_204)
|
||||
result=$(curl --connect-timeout 3 --max-time 5 -o /dev/null -I -skL -w "%{http_code}:%{time_starttransfer}" -x ${curlx} "${probeUrl}")
|
||||
result=$(curl --connect-timeout 3 --max-time 5 -o /dev/null -I -skL -w "%{http_code}:%{time_pretransfer}" -x ${curlx} "${probeUrl}")
|
||||
# 结束 SS 插件进程
|
||||
local pid_file="/tmp/etc/${CONFIG}/url_test_${node_id}_plugin.pid"
|
||||
[ -s "$pid_file" ] && kill -9 "$(head -n 1 "$pid_file")" >/dev/null 2>&1
|
||||
|
||||
@@ -38,7 +38,7 @@ Fork this repository and:
|
||||
|
||||
* Create a release by pushing a tag
|
||||
* Wait until actions finish
|
||||
* Use `opkg -i *` to install both ipks from Releases.
|
||||
* Use `opkg -i *` to install all ipks from Releases.
|
||||
|
||||
## Enable preview app
|
||||
|
||||
@@ -56,6 +56,7 @@ Some features are deprecated / unstable so they are placed in preview app. To en
|
||||
* 2025-07-27 fix: dynamic direct: only cover global servers; increase default timeout
|
||||
* 2025-08-20 fix: dynamic direct connection tracking
|
||||
* 2025-08-26 fix: dnsmasq global integration mode
|
||||
* 2026-01-13 feat: feat: vless encryption; minor DNS tweaks; code cleanups
|
||||
|
||||
## Changelog since 3.5.0
|
||||
|
||||
|
||||
@@ -34,14 +34,14 @@ function parse_ip_port(val, port_default) {
|
||||
|
||||
function format_dns(method, val) {
|
||||
const parsed = parse_ip_port(val, 53);
|
||||
if (method == "udp") {
|
||||
if (method === "udp") {
|
||||
return {
|
||||
address: parsed["ip"],
|
||||
port: parsed["port"]
|
||||
};
|
||||
}
|
||||
let url_suffix = "";
|
||||
if (substr(method, 0, 5) == "https") {
|
||||
if (substr(method, 0, 5) === "https") {
|
||||
url_suffix = "/dns-query";
|
||||
}
|
||||
return {
|
||||
@@ -50,11 +50,11 @@ function format_dns(method, val) {
|
||||
}
|
||||
|
||||
function domain_rules(proxy, k) {
|
||||
if (proxy[k] == null) {
|
||||
if (proxy[k] === null) {
|
||||
return [];
|
||||
}
|
||||
return filter(proxy[k], function (x) {
|
||||
if (substr(x, 0, 8) == "geosite:") {
|
||||
if (substr(x, 0, 8) === "geosite:") {
|
||||
return geosite_existence;
|
||||
}
|
||||
return true;
|
||||
@@ -96,11 +96,27 @@ export function dns_server_inbounds(proxy) {
|
||||
export function dns_rules(proxy, tcp_hijack_inbound_tags, udp_hijack_inbound_tags) {
|
||||
const dns_port = int(proxy["dns_port"] || 5300);
|
||||
const dns_count = int(proxy["dns_count"] || 3);
|
||||
const fast_dns = parse_ip_port(proxy["fast_dns"] || fallback_fast_dns, 53);
|
||||
const secure_dns = parse_ip_port(proxy["secure_dns"] || fallback_secure_dns, 53);
|
||||
let dns_server_tags = [];
|
||||
for (let i = dns_port; i <= dns_port + dns_count; i++) {
|
||||
push(dns_server_tags, sprintf("dns_server_inbound:%d", i));
|
||||
}
|
||||
let result = [
|
||||
{
|
||||
type: "field",
|
||||
inboundTag: ["dns_conf_inbound"],
|
||||
ip: [fast_dns["ip"]],
|
||||
port: `${fast_dns["port"]}`,
|
||||
outboundTag: "dynamic_direct"
|
||||
},
|
||||
{
|
||||
type: "field",
|
||||
inboundTag: ["dns_conf_inbound"],
|
||||
ip: [secure_dns["ip"]],
|
||||
port: `${secure_dns["port"]}`,
|
||||
balancerTag: "udp_outbound_v4"
|
||||
},
|
||||
{
|
||||
type: "field",
|
||||
inboundTag: dns_server_tags,
|
||||
@@ -157,7 +173,7 @@ export function dns_conf(proxy, config, manual_tproxy, fakedns) {
|
||||
let domain_names_set = {};
|
||||
let domain_extra_options = {};
|
||||
|
||||
for (let server in filter(values(config), i => i[".type"] == "servers")) {
|
||||
for (let server in filter(values(config), i => i[".type"] === "servers")) {
|
||||
if (iptoarr(server["server"])) {
|
||||
continue;
|
||||
}
|
||||
@@ -206,6 +222,20 @@ export function dns_conf(proxy, config, manual_tproxy, fakedns) {
|
||||
port: fast_dns_object["port"],
|
||||
domains: [...keys(domain_names_set), ...fast_domain_rules(proxy)],
|
||||
skipFallback: true,
|
||||
expectIPs: function () {
|
||||
let ips = [];
|
||||
if (proxy["align_fast_dns_to_geoip_direct"] === "1") {
|
||||
if (geoip_existence) {
|
||||
const geoip_direct_code_list = map(proxy["geoip_direct_code_list"] || [], v => index(v, ":") > 0 ? v : `geoip:${v}`);
|
||||
const geoip_direct_code_list_v6 = map(proxy["geoip_direct_code_list_v6"] || [], v => index(v, ":") > 0 ? v : `geoip:${v}`);
|
||||
push(ips, ...geoip_direct_code_list, ...geoip_direct_code_list_v6);
|
||||
}
|
||||
}
|
||||
if (length(ips) > 0) {
|
||||
return uniq(ips);
|
||||
}
|
||||
return null;
|
||||
}(),
|
||||
},
|
||||
];
|
||||
|
||||
@@ -228,7 +258,7 @@ export function dns_conf(proxy, config, manual_tproxy, fakedns) {
|
||||
for (let v in manual_tproxy) {
|
||||
if (v.domain_names != null) {
|
||||
for (let d in v.domain_names) {
|
||||
if (index(v.source_addr, ":") == -1) {
|
||||
if (index(v.source_addr, ":") === -1) {
|
||||
hosts[d] = [v.source_addr];
|
||||
}
|
||||
}
|
||||
@@ -245,13 +275,13 @@ export function dns_conf(proxy, config, manual_tproxy, fakedns) {
|
||||
|
||||
export function dns_direct_servers(config) {
|
||||
let result = [];
|
||||
for (let server in filter(values(config), i => i[".type"] == "servers")) {
|
||||
for (let server in filter(values(config), i => i[".type"] === "servers")) {
|
||||
if (iptoarr(server["server"])) {
|
||||
continue;
|
||||
}
|
||||
if (server["domain_resolve_dns"]) {
|
||||
if (index(server["domain_resolve_dns_method"], "local") > 1) {
|
||||
push(result, parse_ip_port(server["domain_resolve_dns"])["ip"]);
|
||||
push(result, parse_ip_port(server["domain_resolve_dns"]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ export function fake_dns_domains(fakedns) {
|
||||
for (let f in fakedns) {
|
||||
push(domains, ...f["fake_dns_domain_names"]);
|
||||
}
|
||||
if (length(domains) == 0) {
|
||||
if (length(domains) === 0) {
|
||||
return [];
|
||||
}
|
||||
return [
|
||||
|
||||
@@ -6,7 +6,7 @@ export function manual_tproxy_outbounds(config, manual_tproxy) {
|
||||
let result = [];
|
||||
for (let v in manual_tproxy) {
|
||||
let tcp_tag = "direct";
|
||||
if (v["force_forward_tcp"] == "1") {
|
||||
if (v["force_forward_tcp"] === "1") {
|
||||
if (v["force_forward_server_tcp"] != null) {
|
||||
tcp_tag = `manual_tproxy:${v[".name"]}@tcp_outbound@force_forward:${v["force_forward_server_tcp"]}`;
|
||||
const force_forward_server_tcp = config[v["force_forward_server_tcp"]];
|
||||
@@ -26,7 +26,7 @@ export function manual_tproxy_outbounds(config, manual_tproxy) {
|
||||
});
|
||||
|
||||
let udp_tag = "direct";
|
||||
if (v["force_forward_udp"] == "1") {
|
||||
if (v["force_forward_udp"] === "1") {
|
||||
if (v["force_forward_server_udp"] != null) {
|
||||
udp_tag = `manual_tproxy:${v[".name"]}@udp_outbound@force_forward:${v["force_forward_server_udp"]}`;
|
||||
const force_forward_server_udp = config[v["force_forward_server_udp"]];
|
||||
@@ -51,10 +51,10 @@ export function manual_tproxy_outbounds(config, manual_tproxy) {
|
||||
export function manual_tproxy_outbound_tags(manual_tproxy) {
|
||||
let result = [];
|
||||
for (let v in manual_tproxy) {
|
||||
if (v["force_forward_tcp"] == "1") {
|
||||
if (v["force_forward_tcp"] === "1") {
|
||||
push(result, `manual_tproxy:${v[".name"]}@tcp_outbound@force_forward:${v["force_forward_server_tcp"]}`);
|
||||
}
|
||||
if (v["force_forward_udp"] == "1") {
|
||||
if (v["force_forward_udp"] === "1") {
|
||||
push(result, `manual_tproxy:${v[".name"]}@udp_outbound@force_forward:${v["force_forward_server_udp"]}`);
|
||||
}
|
||||
}
|
||||
@@ -66,14 +66,14 @@ export function manual_tproxy_rules(manual_tproxy) {
|
||||
for (let v in manual_tproxy) {
|
||||
splice(result, 0, 0, {
|
||||
type: "field",
|
||||
inboundTag: ["tproxy_tcp_inbound_v4", "socks_inbound", "https_inbound", "http_inbound"],
|
||||
inboundTag: ["tproxy_tcp_inbound_v4", "tproxy_tcp_inbound_v6", "socks_inbound", "https_inbound", "http_inbound"],
|
||||
ip: [v["source_addr"]],
|
||||
port: v["source_port"],
|
||||
outboundTag: sprintf("manual_tproxy:%s@tcp_outbound", v[".name"])
|
||||
});
|
||||
splice(result, 0, 0, {
|
||||
type: "field",
|
||||
inboundTag: ["tproxy_udp_inbound_v4"],
|
||||
inboundTag: ["tproxy_udp_inbound_v4", "tproxy_udp_inbound_v6"],
|
||||
ip: [v["source_addr"]],
|
||||
port: v["source_port"],
|
||||
outboundTag: sprintf("manual_tproxy:%s@udp_outbound", v[".name"])
|
||||
|
||||
@@ -14,17 +14,15 @@
|
||||
const udp6_enabled = length(general.udp_balancer_v6 || []) > 0;
|
||||
const uids_direct = uniq(general.uids_direct || []);
|
||||
const gids_direct = uniq(general.gids_direct || []);
|
||||
let wan_bp_ips_no_dns = general.wan_bp_ips || [];
|
||||
let wan_fw_ips_no_dns = general.wan_fw_ips || [];
|
||||
push(wan_bp_ips_no_dns, split(general.fast_dns || "223.5.5.5:53", ":")[0]);
|
||||
for (let i in dns_direct_servers(config)) {
|
||||
push(wan_bp_ips_no_dns, i);
|
||||
}
|
||||
push(wan_fw_ips_no_dns, split(general.secure_dns || "8.8.8.8:53", ":")[0]);
|
||||
const wan_bp_ips_v4 = filter(uniq(wan_bp_ips_no_dns), v => index(v, ":") == -1);
|
||||
const wan_bp_ips_v6 = filter(uniq(wan_bp_ips_no_dns), v => index(v, ":") != -1);
|
||||
const wan_fw_ips_v4 = filter(uniq(wan_fw_ips_no_dns), v => index(v, ":") == -1);
|
||||
const wan_fw_ips_v6 = filter(uniq(wan_fw_ips_no_dns), v => index(v, ":") != -1);
|
||||
let wan_bp_ips = uniq(general.wan_bp_ips || []);
|
||||
let wan_fw_ips = uniq(general.wan_fw_ips || []);
|
||||
let wan_bp_dns = dns_direct_servers(config);
|
||||
const wan_bp_ips_v4 = filter(wan_bp_ips, v => index(v, ":") == -1);
|
||||
const wan_bp_ips_v6 = filter(wan_bp_ips, v => index(v, ":") != -1);
|
||||
const wan_fw_ips_v4 = filter(wan_fw_ips, v => index(v, ":") == -1);
|
||||
const wan_fw_ips_v6 = filter(wan_fw_ips, v => index(v, ":") != -1);
|
||||
const wan_bp_dns_v4 = filter(wan_bp_dns, v => index(v.ip, ":") == -1);
|
||||
const wan_bp_dns_v6 = filter(wan_bp_dns, v => index(v.ip, ":") != -1);
|
||||
const transparent_default_port_policy = general.transparent_default_port_policy || "forwarded";
|
||||
const wan_fw_tcp_ports = general.wan_fw_tcp_ports || [];
|
||||
const wan_fw_udp_ports = general.wan_fw_udp_ports || [];
|
||||
@@ -142,6 +140,28 @@
|
||||
}();
|
||||
%}
|
||||
|
||||
{% if (length(wan_bp_dns_v4) > 0): %}
|
||||
set tp_spec_dp4_bp {
|
||||
typeof ip daddr . udp dport
|
||||
size {{ length(wan_bp_dns_v4) * 2 + 1 }}
|
||||
flags interval
|
||||
elements = {
|
||||
{{ join(", ", uniq(map(wan_bp_dns_v4, v => `${v.ip} . ${v.port}`))) }}
|
||||
}
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
{% if (length(wan_bp_dns_v6) > 0): %}
|
||||
set tp_spec_dp6_bp {
|
||||
typeof ip6 daddr . udp dport
|
||||
size {{ length(wan_bp_dns_v6) * 2 + 1 }}
|
||||
flags interval
|
||||
elements = {
|
||||
{{ join(", ", uniq(map(wan_bp_dns_v6, v => `${v.ip} . ${v.port}`))) }}
|
||||
}
|
||||
}
|
||||
{% endif %}
|
||||
|
||||
set tp_spec_dv4_sp {
|
||||
type ipv4_addr
|
||||
size 32
|
||||
@@ -508,6 +528,14 @@
|
||||
{% if (length(manual_tproxy_source_ips) > 0): %}
|
||||
ip protocol tcp ip daddr @tp_spec_dv4_mt {{ counter }} goto tp_spec_lan_fw comment "Xray manual transparent proxy TCP"
|
||||
ip protocol udp ip daddr @tp_spec_dv4_mt {{ counter }} goto tp_spec_lan_fw comment "Xray manual transparent proxy UDP"
|
||||
{% endif %}
|
||||
{% if (length(wan_bp_dns_v4) > 0): %}
|
||||
ip daddr . tcp dport @tp_spec_dp4_bp {{ counter }} accept
|
||||
ip daddr . udp dport @tp_spec_dp4_bp {{ counter }} accept
|
||||
{% endif %}
|
||||
{% if (length(wan_bp_dns_v6) > 0): %}
|
||||
ip6 daddr . tcp dport @tp_spec_dp6_bp {{ counter }} accept
|
||||
ip6 daddr . udp dport @tp_spec_dp6_bp {{ counter }} accept
|
||||
{% endif %}
|
||||
{{ counter }} return
|
||||
}
|
||||
|
||||
@@ -285,4 +285,4 @@ function gen_config() {
|
||||
});
|
||||
}
|
||||
|
||||
print(gen_config());
|
||||
printf("%.4J", gen_config());
|
||||
|
||||
Binary file not shown.
@@ -38,7 +38,7 @@ export function vless_outbound(server, tag) {
|
||||
email: server["username"],
|
||||
id: server["password"],
|
||||
flow: flow,
|
||||
encryption: server["vless_encryption"]
|
||||
encryption: server["vless_encryption"] || "none"
|
||||
}
|
||||
]
|
||||
};
|
||||
@@ -66,7 +66,7 @@ export function https_vless_inbound(proxy, config) {
|
||||
tag: "https_inbound",
|
||||
settings: {
|
||||
clients: map(proxy["web_server_password"], k => vless_inbound_user(k, flow)),
|
||||
decryption: "none",
|
||||
decryption: proxy["vless_decryption"] || "none",
|
||||
fallbacks: fallbacks(proxy, config)
|
||||
},
|
||||
streamSettings: {
|
||||
|
||||
@@ -242,20 +242,17 @@ return view.extend({
|
||||
transport.init(o, ss, 'transport');
|
||||
o.rmempty = false;
|
||||
|
||||
o = ss.taboption('transport', form.ListValue, 'dialer_proxy', _('Dialer Proxy'), _('Similar to <a href="https://xtls.github.io/config/outbound.html#proxysettingsobject">ProxySettings.Tag</a>'));
|
||||
o.datatype = "uciname";
|
||||
o.value("disabled", _("Disabled"));
|
||||
for (const v of uci.sections(config_data, "servers")) {
|
||||
o.value(v[".name"], server_alias(v));
|
||||
}
|
||||
o.modalonly = true;
|
||||
let dialer_proxy = ss.taboption('transport', form.ListValue, 'dialer_proxy', _('Dialer Proxy'), _('Similar to <a href="https://xtls.github.io/config/outbound.html#proxysettingsobject">ProxySettings.Tag</a>'));
|
||||
dialer_proxy.datatype = "uciname";
|
||||
dialer_proxy.value("disabled", _("Disabled"));
|
||||
dialer_proxy.modalonly = true;
|
||||
|
||||
ss.tab('custom', _('Custom Options'));
|
||||
|
||||
o = ss.taboption('custom', form.TextValue, 'custom_config', _('Custom Configurations'), _(`Configurations here override settings in the previous tabs with the following rules: <ol><li>Object values will be replaced recursively so settings in previous tabs matter.</li><li>Arrays will be replaced entirely instead of being merged.</li><li>Tag <code>tag</code> and mark <code>streamSettings.sockopt.mark</code> are ignored. </li></ol>Aliases are not handled while merging configurations:<ol><li>Use <code>tcpSettings</code> instead of <code>rawSettings</code>.</li><li>Use <code>splithttpSettings</code> instead of <code>xhttpSettings</code>.</li></ol>Some transports like <code>splithttp</code> may use another <code>streamSettings.sockopt</code>:<ol><li><a href="https://github.com/yichya/luci-app-xray/issues/434">Read instructions here</a>, and use <code>${firewall_mark}</code> as <code>sockopt.mark</code> to avoid loopback traffic.</ol>Override rules here may be changed later. Use this only for experimental or pre-release features.`));
|
||||
o = ss.taboption('custom', form.TextValue, 'custom_config', _('Custom Configurations'), _(`Configurations here override settings in the previous tabs with the following rules: <ul><li>Object values will be replaced recursively so settings in previous tabs matter.</li><li>Arrays will be replaced entirely instead of being merged.</li><li>Tag <code>tag</code> and mark <code>streamSettings.sockopt.mark</code> are ignored. </li></ul>Aliases are not handled while merging configurations:<ul><li>Use <code>tcpSettings</code> instead of <code>rawSettings</code>.</li><li>Use <code>splithttpSettings</code> instead of <code>xhttpSettings</code>.</li></ul>Some transports like <code>splithttp</code> may use another <code>streamSettings.sockopt</code>:<ul><li><a href="https://github.com/yichya/luci-app-xray/issues/434">Read instructions here</a>, and use <code>${firewall_mark}</code> as <code>sockopt.mark</code> to avoid loopback traffic.</ul>Override rules here may be changed later. Use this only for experimental or pre-release features.`));
|
||||
o.modalonly = true;
|
||||
o.monospace = true;
|
||||
o.rows = 10;
|
||||
o.rows = 12;
|
||||
o.validate = shared.validate_object;
|
||||
|
||||
s.tab('inbounds', _('Inbounds'));
|
||||
@@ -465,13 +462,6 @@ return view.extend({
|
||||
o.datatype = 'range(0, 50)';
|
||||
o.placeholder = 3;
|
||||
|
||||
o = s.taboption('dns', form.ListValue, 'routing_domain_strategy', _('Routing Domain Strategy'), _("Domain resolution strategy when matching domain against rules. (For tproxy, this is effective only when sniffing is enabled.)"));
|
||||
o.value("AsIs", "AsIs");
|
||||
o.value("IPIfNonMatch", "IPIfNonMatch");
|
||||
o.value("IPOnDemand", "IPOnDemand");
|
||||
o.default = "AsIs";
|
||||
o.rmempty = false;
|
||||
|
||||
s.tab('fake_dns', _('FakeDNS'));
|
||||
|
||||
let tproxy_port_tcp_f4 = s.taboption('fake_dns', form.Value, 'tproxy_port_tcp_f4', _('Transparent proxy port (TCP4)'));
|
||||
@@ -613,24 +603,18 @@ return view.extend({
|
||||
o = ss.option(form.Flag, 'force_forward_tcp', _('Force Forward (TCP)'), _('This destination must be forwarded through an outbound server.'));
|
||||
o.modalonly = true;
|
||||
|
||||
o = ss.option(form.ListValue, 'force_forward_server_tcp', _('Force Forward server (TCP)'));
|
||||
o.depends("force_forward_tcp", "1");
|
||||
o.datatype = "uciname";
|
||||
for (const v of uci.sections(config_data, "servers")) {
|
||||
o.value(v[".name"], server_alias(v));
|
||||
}
|
||||
o.modalonly = true;
|
||||
let force_forward_server_tcp = ss.option(form.ListValue, 'force_forward_server_tcp', _('Force Forward server (TCP)'));
|
||||
force_forward_server_tcp.depends("force_forward_tcp", "1");
|
||||
force_forward_server_tcp.datatype = "uciname";
|
||||
force_forward_server_tcp.modalonly = true;
|
||||
|
||||
o = ss.option(form.Flag, 'force_forward_udp', _('Force Forward (UDP)'), _('This destination must be forwarded through an outbound server.'));
|
||||
o.modalonly = true;
|
||||
|
||||
o = ss.option(form.ListValue, 'force_forward_server_udp', _('Force Forward server (UDP)'));
|
||||
o.depends("force_forward_udp", "1");
|
||||
o.datatype = "uciname";
|
||||
for (const v of uci.sections(config_data, "servers")) {
|
||||
o.value(v[".name"], server_alias(v));
|
||||
}
|
||||
o.modalonly = true;
|
||||
let force_forward_server_udp = ss.option(form.ListValue, 'force_forward_server_udp', _('Force Forward server (UDP)'));
|
||||
force_forward_server_udp.depends("force_forward_udp", "1");
|
||||
force_forward_server_udp.datatype = "uciname";
|
||||
force_forward_server_udp.modalonly = true;
|
||||
|
||||
s.tab('xray_server', _('HTTPS Server'));
|
||||
|
||||
@@ -739,11 +723,8 @@ return view.extend({
|
||||
ss.anonymous = true;
|
||||
ss.addremove = true;
|
||||
|
||||
o = ss.option(form.ListValue, "upstream", _("Upstream"));
|
||||
o.datatype = "uciname";
|
||||
for (const v of uci.sections(config_data, "servers")) {
|
||||
o.value(v[".name"], server_alias(v));
|
||||
}
|
||||
let bridge_upstream = ss.option(form.ListValue, "upstream", _("Upstream"));
|
||||
bridge_upstream.datatype = "uciname";
|
||||
|
||||
o = ss.option(form.Value, "domain", _("Domain"));
|
||||
o.rmempty = false;
|
||||
@@ -759,7 +740,7 @@ return view.extend({
|
||||
custom_configuration_hook.rows = 20;
|
||||
|
||||
const servers = uci.sections(config_data, "servers");
|
||||
for (let selection of [destination, fake_dns_forward_server_tcp, fake_dns_forward_server_udp, tcp_balancer_v4, tcp_balancer_v6, udp_balancer_v4, udp_balancer_v6]) {
|
||||
for (let selection of [destination, fake_dns_forward_server_tcp, fake_dns_forward_server_udp, tcp_balancer_v4, tcp_balancer_v6, udp_balancer_v4, udp_balancer_v6, bridge_upstream, force_forward_server_tcp, force_forward_server_udp, dialer_proxy]) {
|
||||
if (servers.length == 0) {
|
||||
selection.value("direct", _("No server configured"));
|
||||
selection.readonly = true;
|
||||
|
||||
@@ -17,6 +17,7 @@ return view.extend({
|
||||
s.anonymous = true;
|
||||
|
||||
s.tab("dns_hijack", _("DNS Hijacking"));
|
||||
s.taboption('dns_hijack', form.Flag, 'align_fast_dns_to_geoip_direct', _('Align Fast DNS & GeoIP Direct'), _("Return only IP adddresses from GeoIP Direct List for Fast DNS."));
|
||||
|
||||
let dnsmasq_integration_mode = s.taboption('dns_hijack', form.ListValue, 'dnsmasq_integration_mode', _('Dnsmasq Integration Mode'), _('Per Instance mode requires OpenWrt 24.10 or later versions.'));
|
||||
dnsmasq_integration_mode.value("global", _("Global"));
|
||||
@@ -72,6 +73,13 @@ return view.extend({
|
||||
let direct_bittorrent = s.taboption('sniffing', form.Flag, 'direct_bittorrent', _('Bittorrent Direct'), _("If enabled, no bittorrent request will be forwarded through Xray."));
|
||||
direct_bittorrent.depends("tproxy_sniffing", "1");
|
||||
|
||||
let routing_domain_strategy = s.taboption('sniffing', form.ListValue, 'routing_domain_strategy', _('Routing Domain Strategy'), _("Domain resolution strategy when matching domain against rules. (For tproxy, this is effective only when sniffing is enabled.)"));
|
||||
routing_domain_strategy.value("AsIs", "AsIs");
|
||||
routing_domain_strategy.value("IPIfNonMatch", "IPIfNonMatch");
|
||||
routing_domain_strategy.value("IPOnDemand", "IPOnDemand");
|
||||
routing_domain_strategy.depends("tproxy_sniffing", "1");
|
||||
routing_domain_strategy.default = "AsIs";
|
||||
|
||||
s.tab('dynamic_direct', _('Dynamic Direct'));
|
||||
|
||||
s.taboption('dynamic_direct', form.Flag, 'dynamic_direct_tcp4', _('Enable for IPv4 TCP'), _("This should improve performance with large number of connections."));
|
||||
|
||||
@@ -214,10 +214,10 @@ function vmess_client(protocol, sub_section, tab_name) {
|
||||
function vless_client(protocol, sub_section, tab_name) {
|
||||
protocol.value("vless", "VLESS");
|
||||
|
||||
let vless_encryption = sub_section.taboption(tab_name, form.ListValue, "vless_encryption", _("[vless] Encrypt Method"));
|
||||
let vless_encryption = sub_section.taboption(tab_name, form.Value, "vless_encryption", _("[vless] Encrypt Method"));
|
||||
vless_encryption.depends("protocol", "vless");
|
||||
vless_encryption.value("none", "none");
|
||||
vless_encryption.rmempty = false;
|
||||
vless_encryption.placeholder = "none";
|
||||
vless_encryption.rmempty = true;
|
||||
vless_encryption.modalonly = true;
|
||||
|
||||
add_flow_and_stream_security_conf(sub_section, tab_name, "protocol", "vless", true, false);
|
||||
@@ -235,6 +235,12 @@ function http_client(protocol, sub_section, tab_name) {
|
||||
|
||||
function vless_server(protocol, section, tab_name) {
|
||||
protocol.value("vless", "VLESS");
|
||||
|
||||
let vless_decryption = section.taboption(tab_name, form.Value, "vless_decryption", _("[vless] Decrypt Method"));
|
||||
vless_decryption.depends("web_server_protocol", "vless");
|
||||
vless_decryption.placeholder = "none";
|
||||
vless_decryption.rmempty = true;
|
||||
|
||||
add_flow_and_stream_security_conf(section, tab_name, "web_server_protocol", "vless", true, true);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=xray-core
|
||||
PKG_VERSION:=25.12.8
|
||||
PKG_VERSION:=26.1.13
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/XTLS/Xray-core/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=d4519b2d9bb1871f4d7612aa7a8db1c451573b5a44ac824219bb44d63f404e61
|
||||
PKG_HASH:=c814c9b2e6c92e08d3db929792c56e2863a1a0e252c774ec048095efea6b67a1
|
||||
|
||||
PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
|
||||
PKG_LICENSE:=MPL-2.0
|
||||
|
||||
Reference in New Issue
Block a user