From a8a878dde16a1d84bc776a4c9929e74f6ec59574 Mon Sep 17 00:00:00 2001 From: kenzok8 Date: Thu, 15 May 2025 00:28:20 +0800 Subject: [PATCH] update 2025-05-15 00:28:20 --- luci-app-ddns-go/Makefile | 4 +- .../share/rpcd/acl.d/luci-app-ddns-go.json | 14 +- .../root/usr/share/passwall/lease2hosts.sh | 16 +- luci-app-passwall2/Makefile | 2 +- .../cbi/passwall2/client/type/sing-box.lua | 4 + .../luasrc/passwall2/util_sing-box.lua | 11 + .../luasrc/passwall2/util_xray.lua | 10 +- .../passwall2/node_list/link_share_man.htm | 2 + .../root/usr/share/passwall2/haproxy.lua | 469 +++++++++--------- .../root/usr/share/passwall2/haproxy_check.sh | 4 +- .../root/usr/share/passwall2/subscribe.lua | 2 + .../root/usr/share/passwall2/test.sh | 20 +- 12 files changed, 291 insertions(+), 267 deletions(-) diff --git a/luci-app-ddns-go/Makefile b/luci-app-ddns-go/Makefile index c28591432..3731905eb 100644 --- a/luci-app-ddns-go/Makefile +++ b/luci-app-ddns-go/Makefile @@ -7,8 +7,8 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-ddns-go -PKG_VERSION:=1.5.1 -PKG_RELEASE:=20250513 +PKG_VERSION:=1.5.2 +PKG_RELEASE:=20250514 PKG_MAINTAINER:=sirpdboy PKG_CONFIG_DEPENDS:= diff --git a/luci-app-ddns-go/root/usr/share/rpcd/acl.d/luci-app-ddns-go.json b/luci-app-ddns-go/root/usr/share/rpcd/acl.d/luci-app-ddns-go.json index 432a84895..b2fe72b45 100644 --- a/luci-app-ddns-go/root/usr/share/rpcd/acl.d/luci-app-ddns-go.json +++ b/luci-app-ddns-go/root/usr/share/rpcd/acl.d/luci-app-ddns-go.json @@ -2,10 +2,16 @@ "luci-app-ddns-go": { "description": "Grant UCI access for luci-app-ddns-go", "read": { - "ubus": { - "service": [ "list" ] - }, - "uci": [ "ddns-go" ,"ddns-go" ] + "file": { + "/etc/init.d/ddns-go": [ "exec" ], + "/usr/libexec/ddns-go-call": [ "exec" ], + "/etc/ddns-go/ddns-go-config.yaml": [ "read" ], + "/var/log/ddns-go.log": [ "read" ] + }, + "ubus": { + "service": [ "list" ] + }, + "uci": [ "ddns-go" ,"ddns-go" ] }, "write": { "uci": [ "ddns-go" ,"ddns-go" ] diff --git a/luci-app-passwall/root/usr/share/passwall/lease2hosts.sh b/luci-app-passwall/root/usr/share/passwall/lease2hosts.sh index 359297509..db3b98b93 100755 --- a/luci-app-passwall/root/usr/share/passwall/lease2hosts.sh +++ b/luci-app-passwall/root/usr/share/passwall/lease2hosts.sh @@ -30,15 +30,21 @@ reload_dnsmasq_pids() { while true; do - if [ -s "$LEASE_FILE" ]; then - awk 'NF >= 4 {print $3" "$4}' "$LEASE_FILE" | sort > "$TMP_FILE" - if [ -f "$TMP_FILE" ]; then - if [ ! -f "$HOSTS_FILE" ] || [ "$(md5sum "$TMP_FILE" | awk '{print $1}')" != "$(md5sum "$HOSTS_FILE" | awk '{print $1}')" ]; then + if [ -f "$LEASE_FILE" ]; then + awk 'NF >= 4 && $4 != "*" {print $3" "$4}' "$LEASE_FILE" | sort > "$TMP_FILE" + if [ -s "$TMP_FILE" ]; then + if [ ! -f "$HOSTS_FILE" ] || ! cmp -s "$TMP_FILE" "$HOSTS_FILE"; then mv "$TMP_FILE" "$HOSTS_FILE" reload_dnsmasq_pids else - rm -rf "$TMP_FILE" + rm -f "$TMP_FILE" fi + else + if [ -s "$HOSTS_FILE" ]; then + : > "$HOSTS_FILE" + reload_dnsmasq_pids + fi + rm -f "$TMP_FILE" fi fi diff --git a/luci-app-passwall2/Makefile b/luci-app-passwall2/Makefile index 3aabfca8b..305172abe 100644 --- a/luci-app-passwall2/Makefile +++ b/luci-app-passwall2/Makefile @@ -5,7 +5,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=luci-app-passwall2 -PKG_VERSION:=25.5.7 +PKG_VERSION:=25.5.15 PKG_RELEASE:=1 PKG_CONFIG_DEPENDS:= \ diff --git a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/sing-box.lua b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/sing-box.lua index 075199f9b..26a9a09ec 100644 --- a/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/sing-box.lua +++ b/luci-app-passwall2/luasrc/model/cbi/passwall2/client/type/sing-box.lua @@ -335,6 +335,10 @@ o:value("xtls-rprx-vision") o:depends({ [_n("protocol")] = "vless", [_n("tls")] = true }) if singbox_tags:find("with_quic") then + o = s:option(Value, _n("hysteria_hop"), translate("Port hopping range")) + o.description = translate("Format as 1000:2000 or 1000-2000 Multiple groups are separated by commas (,).") + o:depends({ [_n("protocol")] = "hysteria" }) + o = s:option(Value, _n("hysteria_obfs"), translate("Obfs Password")) o:depends({ [_n("protocol")] = "hysteria" }) diff --git a/luci-app-passwall2/luasrc/passwall2/util_sing-box.lua b/luci-app-passwall2/luasrc/passwall2/util_sing-box.lua index db0f3be3f..ef888a8cc 100644 --- a/luci-app-passwall2/luasrc/passwall2/util_sing-box.lua +++ b/luci-app-passwall2/luasrc/passwall2/util_sing-box.lua @@ -292,7 +292,18 @@ function gen_outbound(flag, node, tag, proxy_table) end if node.protocol == "hysteria" then + local server_ports = {} + if node.hysteria_hop then + node.hysteria_hop = string.gsub(node.hysteria_hop, "-", ":") + for range in node.hysteria_hop:gmatch("([^,]+)") do + if range:match("^%d+:%d+$") then + table.insert(server_ports, range) + end + end + end protocol_table = { + server_ports = next(server_ports) and server_ports or nil, + hop_interval = next(server_ports) and "30s" or nil, up_mbps = tonumber(node.hysteria_up_mbps), down_mbps = tonumber(node.hysteria_down_mbps), obfs = node.hysteria_obfs, diff --git a/luci-app-passwall2/luasrc/passwall2/util_xray.lua b/luci-app-passwall2/luasrc/passwall2/util_xray.lua index ca40a7a16..1effe2560 100644 --- a/luci-app-passwall2/luasrc/passwall2/util_xray.lua +++ b/luci-app-passwall2/luasrc/passwall2/util_xray.lua @@ -163,9 +163,9 @@ function gen_outbound(flag, node, tag, proxy_table) spiderX = node.reality_spiderX or "/", fingerprint = (node.type == "Xray" and node.fingerprint and node.fingerprint ~= "") and node.fingerprint or "chrome" } or nil, - rawSettings = ((node.transport == "raw" or node.transport == "tcp") and node.protocol ~= "socks") and { + rawSettings = ((node.transport == "raw" or node.transport == "tcp") and node.protocol ~= "socks" and (node.tcp_guise and node.tcp_guise ~= "none")) and { header = { - type = node.tcp_guise or "none", + type = node.tcp_guise, request = (node.tcp_guise == "http") and { path = node.tcp_guise_http_path or {"/"}, headers = { @@ -729,7 +729,7 @@ function gen_config(var) end if is_new_blc_node then local blc_node = uci:get_all(appname, blc_node_id) - local outbound = gen_outbound(flag, blc_node, blc_node_tag, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.noise == "1" or nil }) + local outbound = gen_outbound(flag, blc_node, blc_node_tag, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.noise == "1" or nil, run_socks_instance = not no_run }) if outbound then outbound.tag = outbound.tag .. ":" .. blc_node.remarks table.insert(outbounds, outbound) @@ -755,7 +755,7 @@ function gen_config(var) if is_new_node then local fallback_node = uci:get_all(appname, fallback_node_id) if fallback_node.protocol ~= "_balancing" then - local outbound = gen_outbound(flag, fallback_node, fallback_node_id, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.noise == "1" or nil }) + local outbound = gen_outbound(flag, fallback_node, fallback_node_id, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.noise == "1" or nil, run_socks_instance = not no_run }) if outbound then outbound.tag = outbound.tag .. ":" .. fallback_node.remarks table.insert(outbounds, outbound) @@ -1146,7 +1146,7 @@ function gen_config(var) sys.call(string.format("mkdir -p %s && touch %s/%s", api.TMP_IFACE_PATH, api.TMP_IFACE_PATH, node.iface)) end else - local outbound = gen_outbound(flag, node, nil, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.fragment == "1" or nil }) + local outbound = gen_outbound(flag, node, nil, { fragment = xray_settings.fragment == "1" or nil, noise = xray_settings.fragment == "1" or nil, run_socks_instance = not no_run }) if outbound then outbound.tag = outbound.tag .. ":" .. node.remarks COMMON.default_outbound_tag, last_insert_outbound = set_outbound_detour(node, outbound, outbounds) diff --git a/luci-app-passwall2/luasrc/view/passwall2/node_list/link_share_man.htm b/luci-app-passwall2/luasrc/view/passwall2/node_list/link_share_man.htm index 44ebddbcd..fdd6d6753 100644 --- a/luci-app-passwall2/luasrc/view/passwall2/node_list/link_share_man.htm +++ b/luci-app-passwall2/luasrc/view/passwall2/node_list/link_share_man.htm @@ -536,6 +536,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin params += opt.query("sni", dom_prefix + "tls_serverName"); params += opt.query("alpn", dom_prefix + "tuic_alpn"); params += opt.query("congestion_control", dom_prefix + "tuic_congestion_control"); + params += opt.query("udp_relay_mode", dom_prefix + "tuic_udp_relay_mode"); params += opt.query("allowinsecure", dom_prefix + "tls_allowInsecure"); params += "#" + encodeURI(v_alias.value); @@ -1428,6 +1429,7 @@ local hysteria2_type = map:get("@global_subscribe[0]", "hysteria2_type") or "sin } } opt.set(dom_prefix + 'tuic_congestion_control', queryParam.congestion_control || 'cubic'); + opt.set(dom_prefix + 'tuic_udp_relay_mode', queryParam.udp_relay_mode || 'native'); opt.set(dom_prefix + 'tuic_alpn', queryParam.alpn || 'default'); opt.set(dom_prefix + 'tls_serverName', queryParam.sni || ''); opt.set(dom_prefix + 'tls_allowInsecure', true); diff --git a/luci-app-passwall2/root/usr/share/passwall2/haproxy.lua b/luci-app-passwall2/root/usr/share/passwall2/haproxy.lua index ca16a8ada..6759bc931 100644 --- a/luci-app-passwall2/root/usr/share/passwall2/haproxy.lua +++ b/luci-app-passwall2/root/usr/share/passwall2/haproxy.lua @@ -1,230 +1,239 @@ -#!/usr/bin/lua - -local api = require ("luci.passwall2.api") -local appname = api.appname -local fs = api.fs -local jsonc = api.jsonc -local uci = api.uci -local sys = api.sys - -local log = function(...) - api.log(...) -end - -function get_ip_port_from(str) - local result_port = sys.exec("echo -n " .. str .. " | sed -n 's/^.*[:#]\\([0-9]*\\)$/\\1/p'") - local result_ip = sys.exec(string.format("__host=%s;__varport=%s;", str, result_port) .. "echo -n ${__host%%${__varport:+[:#]${__varport}*}}") - return result_ip, result_port -end - -local new_port -local function get_new_port() - if new_port then - new_port = tonumber(sys.exec(string.format("echo -n $(/usr/share/%s/app.sh get_new_port %s tcp)", appname, new_port + 1))) - else - new_port = tonumber(sys.exec(string.format("echo -n $(/usr/share/%s/app.sh get_new_port auto tcp)", appname))) - end - return new_port -end - -local var = api.get_args(arg) -local haproxy_path = var["-path"] -local haproxy_conf = var["-conf"] -local haproxy_dns = var["-dns"] or "119.29.29.29:53,223.5.5.5:53" - -local cpu_thread = sys.exec('echo -n $(cat /proc/cpuinfo | grep "processor" | wc -l)') or "1" -local health_check_type = uci:get(appname, "@global_haproxy[0]", "health_check_type") or "tcp" -local health_check_inter = uci:get(appname, "@global_haproxy[0]", "health_check_inter") or "10" -local bind_local = uci:get(appname, "@global_haproxy[0]", "bind_local") or "0" -local bind_address = "0.0.0.0" -if bind_local == "1" then bind_address = "127.0.0.1" end - -log("HAPROXY 负载均衡...") -fs.mkdir(haproxy_path) -local haproxy_file = haproxy_path .. "/" .. haproxy_conf - -local f_out = io.open(haproxy_file, "a") - -local haproxy_config = [[ -global - daemon - log 127.0.0.1 local2 - maxconn 60000 - stats socket {{path}}/haproxy.sock - nbthread {{nbthread}} - external-check - insecure-fork-wanted - -defaults - mode tcp - log global - option tcplog - option dontlognull - option http-server-close - #option forwardfor except 127.0.0.0/8 - option redispatch - retries 2 - timeout http-request 10s - timeout queue 1m - timeout connect 10s - timeout client 1m - timeout server 1m - timeout http-keep-alive 10s - timeout check 10s - maxconn 3000 - -resolvers mydns - resolve_retries 1 - timeout resolve 5s - hold valid 600s -{{dns}} -]] - -haproxy_config = haproxy_config:gsub("{{path}}", haproxy_path) -haproxy_config = haproxy_config:gsub("{{nbthread}}", cpu_thread) - -local mydns = "" -local index = 0 -string.gsub(haproxy_dns, '[^' .. "," .. ']+', function(w) - index = index + 1 - local s = w:gsub("#", ":") - if not s:find(":") then - s = s .. ":53" - end - mydns = mydns .. (index > 1 and "\n" or "") .. " " .. string.format("nameserver dns%s %s", index, s) -end) -haproxy_config = haproxy_config:gsub("{{dns}}", mydns) - -f_out:write(haproxy_config) - -local listens = {} - -uci:foreach(appname, "haproxy_config", function(t) - if t.enabled == "1" then - local server_remark - local server_address - local server_port - local lbss = t.lbss - local listen_port = tonumber(t.haproxy_port) or 0 - local server_node = uci:get_all(appname, lbss) - if server_node and server_node.address and server_node.port then - server_remark = server_node.address .. ":" .. server_node.port - server_address = server_node.address - server_port = server_node.port - t.origin_address = server_address - t.origin_port = server_port - if health_check_type == "passwall_logic" then - if server_node.type ~= "Socks" then - local relay_port = server_node.port - new_port = get_new_port() - local config_file = string.format("haproxy_%s_%s.json", t[".name"], new_port) - sys.call(string.format('/usr/share/%s/app.sh run_socks "%s"> /dev/null', - appname, - string.format("flag=%s node=%s bind=%s socks_port=%s config_file=%s", - new_port, --flag - server_node[".name"], --node - "127.0.0.1", --bind - new_port, --socks port - config_file --config file - ) - ) - ) - server_address = "127.0.0.1" - server_port = new_port - end - end - else - server_address, server_port = get_ip_port_from(lbss) - server_remark = server_address .. ":" .. server_port - t.origin_address = server_address - t.origin_port = server_port - end - if server_address and server_port and listen_port > 0 then - if not listens[listen_port] then - listens[listen_port] = {} - end - t.server_remark = server_remark - t.server_address = server_address - t.server_port = server_port - table.insert(listens[listen_port], t) - else - log(" - 丢弃1个明显无效的节点") - end - end -end) - -local sortTable = {} -for i in pairs(listens) do - if i ~= nil then - table.insert(sortTable, i) - end -end -table.sort(sortTable, function(a,b) return (a < b) end) - -for i, port in pairs(sortTable) do - log(" + 入口 %s:%s" % {bind_address, port}) - - f_out:write("\n" .. string.format([[ -listen %s - bind %s:%s - mode tcp - balance roundrobin -]], port, bind_address, port)) - - if health_check_type == "passwall_logic" then - f_out:write(string.format([[ - option external-check - external-check command "/usr/share/passwall2/haproxy_check.sh" -]], port, port)) - end - - for i, o in ipairs(listens[port]) do - local remark = o.server_remark - local server = o.server_address .. ":" .. o.server_port - local server_conf = "server {{remark}} {{server}} weight {{weight}} {{resolvers}} check inter {{inter}} rise 1 fall 3 {{backup}}" - server_conf = server_conf:gsub("{{remark}}", remark) - server_conf = server_conf:gsub("{{server}}", server) - server_conf = server_conf:gsub("{{weight}}", o.lbweight) - local resolvers = "resolvers mydns" - if api.is_ip(o.server_address) then - resolvers = "" - end - server_conf = server_conf:gsub("{{resolvers}}", resolvers) - server_conf = server_conf:gsub("{{inter}}", tonumber(health_check_inter) .. "s") - server_conf = server_conf:gsub("{{backup}}", o.backup == "1" and "backup" or "") - - f_out:write(" " .. server_conf .. "\n") - - if o.export ~= "0" then - sys.call(string.format("/usr/share/passwall2/app.sh add_ip2route %s %s", o.origin_address, o.export)) - end - - log(string.format(" | - 出口节点:%s:%s,权重:%s", o.origin_address, o.origin_port, o.lbweight)) - end -end - ---控制台配置 -local console_port = uci:get(appname, "@global_haproxy[0]", "console_port") -local console_user = uci:get(appname, "@global_haproxy[0]", "console_user") -local console_password = uci:get(appname, "@global_haproxy[0]", "console_password") -local str = [[ -listen console - bind 0.0.0.0:%s - mode http - stats refresh 30s - stats uri / - stats admin if TRUE - %s -]] -f_out:write("\n" .. string.format(str, console_port, (console_user and console_user ~= "" and console_password and console_password ~= "") and "stats auth " .. console_user .. ":" .. console_password or "")) -log(string.format(" * 控制台端口:%s", console_port)) - -f_out:close() - ---内置健康检查URL -if health_check_type == "passwall_logic" then - local probeUrl = uci:get(appname, "@global_haproxy[0]", "health_probe_url") or "https://www.google.com/generate_204" - local f_url = io.open(haproxy_path .. "/Probe_URL", "w") - f_url:write(probeUrl) - f_url:close() -end +#!/usr/bin/lua + +local api = require ("luci.passwall2.api") +local appname = "passwall2" +local fs = api.fs +local jsonc = api.jsonc +local uci = api.uci +local sys = api.sys + +local log = function(...) + api.log(...) +end + +function get_ip_port_from(str) + local result_port = sys.exec("echo -n " .. str .. " | sed -n 's/^.*[:#]\\([0-9]*\\)$/\\1/p'") + local result_ip = sys.exec(string.format("__host=%s;__varport=%s;", str, result_port) .. "echo -n ${__host%%${__varport:+[:#]${__varport}*}}") + return result_ip, result_port +end + +local new_port +local function get_new_port() + if new_port then + new_port = tonumber(sys.exec(string.format("echo -n $(/usr/share/%s/app.sh get_new_port %s tcp)", appname, new_port + 1))) + else + new_port = tonumber(sys.exec(string.format("echo -n $(/usr/share/%s/app.sh get_new_port auto tcp)", appname))) + end + return new_port +end + +local var = api.get_args(arg) +local haproxy_path = var["-path"] +local haproxy_conf = var["-conf"] +local haproxy_dns = var["-dns"] or "119.29.29.29:53,223.5.5.5:53" + +local cpu_thread = sys.exec('echo -n $(cat /proc/cpuinfo | grep "processor" | wc -l)') or "1" +local health_check_type = uci:get(appname, "@global_haproxy[0]", "health_check_type") or "tcp" +local health_check_inter = uci:get(appname, "@global_haproxy[0]", "health_check_inter") or "10" +local console_port = uci:get(appname, "@global_haproxy[0]", "console_port") +local bind_local = uci:get(appname, "@global_haproxy[0]", "bind_local") or "0" +local bind_address = "0.0.0.0" +if bind_local == "1" then bind_address = "127.0.0.1" end + +log("HAPROXY 负载均衡:") +log(string.format(" * 控制台端口:%s", console_port)) +fs.mkdir(haproxy_path) +local haproxy_file = haproxy_path .. "/" .. haproxy_conf + +local f_out = io.open(haproxy_file, "a") + +local haproxy_config = [[ +global + daemon + log 127.0.0.1 local2 + maxconn 60000 + stats socket {{path}}/haproxy.sock + nbthread {{nbthread}} + external-check + insecure-fork-wanted + +defaults + mode tcp + log global + option tcplog + option dontlognull + option http-server-close + #option forwardfor except 127.0.0.0/8 + option redispatch + retries 2 + timeout http-request 10s + timeout queue 1m + timeout connect 10s + timeout client 1m + timeout server 1m + timeout http-keep-alive 10s + timeout check 10s + maxconn 3000 + +resolvers mydns + resolve_retries 1 + timeout resolve 5s + hold valid 600s +{{dns}} +]] + +haproxy_config = haproxy_config:gsub("{{path}}", haproxy_path) +haproxy_config = haproxy_config:gsub("{{nbthread}}", cpu_thread) + +local mydns = "" +local index = 0 +string.gsub(haproxy_dns, '[^' .. "," .. ']+', function(w) + index = index + 1 + local s = w:gsub("#", ":") + if not s:find(":") then + s = s .. ":53" + end + mydns = mydns .. (index > 1 and "\n" or "") .. " " .. string.format("nameserver dns%s %s", index, s) +end) +haproxy_config = haproxy_config:gsub("{{dns}}", mydns) + +f_out:write(haproxy_config) + +local listens = {} + +uci:foreach(appname, "haproxy_config", function(t) + if t.enabled == "1" then + local server_remark + local server_address + local server_port + local lbss = t.lbss + local listen_port = tonumber(t.haproxy_port) or 0 + local server_node = uci:get_all(appname, lbss) + if server_node and server_node.address and server_node.port then + server_remark = server_node.address .. ":" .. server_node.port + server_address = server_node.address + server_port = server_node.port + t.origin_address = server_address + t.origin_port = server_port + if health_check_type == "passwall_logic" then + if server_node.type ~= "Socks" then + local relay_port = server_node.port + new_port = get_new_port() + local config_file = string.format("haproxy_%s_%s.json", t[".name"], new_port) + sys.call(string.format('/usr/share/%s/app.sh run_socks "%s"> /dev/null', + appname, + string.format("flag=%s node=%s bind=%s socks_port=%s config_file=%s", + new_port, --flag + server_node[".name"], --node + "127.0.0.1", --bind + new_port, --socks port + config_file --config file + ) + ) + ) + server_address = "127.0.0.1" + server_port = new_port + end + end + else + server_address, server_port = get_ip_port_from(lbss) + server_remark = server_address .. ":" .. server_port + t.origin_address = server_address + t.origin_port = server_port + end + if server_address and server_port and listen_port > 0 then + if not listens[listen_port] then + listens[listen_port] = {} + end + t.server_remark = server_remark + t.server_address = server_address + t.server_port = server_port + table.insert(listens[listen_port], t) + else + log(" - 丢弃1个明显无效的节点") + end + end +end) + +local sortTable = {} +for i in pairs(listens) do + if i ~= nil then + table.insert(sortTable, i) + end +end +table.sort(sortTable, function(a,b) return (a < b) end) + +for i, port in pairs(sortTable) do + log(" + 入口 %s:%s" % {bind_address, port}) + + f_out:write("\n" .. string.format([[ +listen %s + bind %s:%s + mode tcp + balance roundrobin +]], port, bind_address, port)) + + if health_check_type == "passwall_logic" then + f_out:write(string.format([[ + option external-check + external-check command "/usr/share/passwall2/haproxy_check.sh" +]], port, port)) + end + + local count_M, count_B = 1, 1 + for i, o in ipairs(listens[port]) do + local remark = o.server_remark or "" + -- 防止重名导致无法运行 + if tostring(o.backup) ~= "1" then + remark = "M" .. count_M .. "-" .. remark + count_M = count_M + 1 + else + remark = "B" .. count_B .. "-" .. remark + count_B = count_B + 1 + end + local server = o.server_address .. ":" .. o.server_port + local server_conf = "server {{remark}} {{server}} weight {{weight}} {{resolvers}} check inter {{inter}} rise 1 fall 3 {{backup}}" + server_conf = server_conf:gsub("{{remark}}", remark) + server_conf = server_conf:gsub("{{server}}", server) + server_conf = server_conf:gsub("{{weight}}", o.lbweight) + local resolvers = "resolvers mydns" + if api.is_ip(o.server_address) then + resolvers = "" + end + server_conf = server_conf:gsub("{{resolvers}}", resolvers) + server_conf = server_conf:gsub("{{inter}}", tonumber(health_check_inter) .. "s") + server_conf = server_conf:gsub("{{backup}}", tostring(o.backup) == "1" and "backup" or "") + + f_out:write(" " .. server_conf .. "\n") + + if o.export ~= "0" then + sys.call(string.format("/usr/share/passwall2/app.sh add_ip2route %s %s", o.origin_address, o.export)) + end + + log(string.format(" | - 出口节点:%s:%s,权重:%s", o.origin_address, o.origin_port, o.lbweight)) + end +end + +--控制台配置 +local console_user = uci:get(appname, "@global_haproxy[0]", "console_user") +local console_password = uci:get(appname, "@global_haproxy[0]", "console_password") +local str = [[ +listen console + bind 0.0.0.0:%s + mode http + stats refresh 30s + stats uri / + stats admin if TRUE + %s +]] +f_out:write("\n" .. string.format(str, console_port, (console_user and console_user ~= "" and console_password and console_password ~= "") and "stats auth " .. console_user .. ":" .. console_password or "")) + +f_out:close() + +--内置健康检查URL +if health_check_type == "passwall_logic" then + local probeUrl = uci:get(appname, "@global_haproxy[0]", "health_probe_url") or "https://www.google.com/generate_204" + local f_url = io.open(haproxy_path .. "/Probe_URL", "w") + f_url:write(probeUrl) + f_url:close() +end diff --git a/luci-app-passwall2/root/usr/share/passwall2/haproxy_check.sh b/luci-app-passwall2/root/usr/share/passwall2/haproxy_check.sh index 7f8653698..709a21bfd 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/haproxy_check.sh +++ b/luci-app-passwall2/root/usr/share/passwall2/haproxy_check.sh @@ -1,5 +1,7 @@ #!/bin/sh +export PATH=/usr/sbin:/usr/bin:/sbin:/bin:/root/bin + listen_address=$1 listen_port=$2 server_address=$3 @@ -17,7 +19,7 @@ if /usr/bin/curl --help all | grep -q "\-\-retry-all-errors"; then extra_params="${extra_params} --retry-all-errors" fi -status=$(/usr/bin/curl -I -o /dev/null -skL ${extra_params} --connect-timeout 3 --retry 1 -w "%{http_code}" "${probeUrl}") +status=$(/usr/bin/curl -I -o /dev/null -skL ${extra_params} --connect-timeout 3 --retry 1 --max-time 10 -w "%{http_code}" "${probeUrl}") case "$status" in 200|204) diff --git a/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua index dec3558ee..661ccfd0d 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua +++ b/luci-app-passwall2/root/usr/share/passwall2/subscribe.lua @@ -1219,6 +1219,7 @@ local function processData(szType, content, add_mode, add_from) result.hysteria_alpn = params.alpn result.hysteria_up_mbps = params.upmbps result.hysteria_down_mbps = params.downmbps + result.hysteria_hop = params.mport if has_singbox then result.type = 'sing-box' @@ -1325,6 +1326,7 @@ local function processData(szType, content, add_mode, add_from) result.tls_serverName = params.sni result.tuic_alpn = params.alpn or "default" result.tuic_congestion_control = params.congestion_control or "cubic" + result.tuic_udp_relay_mode = params.udp_relay_mode or "native" params.allowinsecure = params.allowinsecure or params.insecure if params.allowinsecure then if params.allowinsecure == "1" or params.allowinsecure == "0" then diff --git a/luci-app-passwall2/root/usr/share/passwall2/test.sh b/luci-app-passwall2/root/usr/share/passwall2/test.sh index a985a9cd6..716f4d7d0 100755 --- a/luci-app-passwall2/root/usr/share/passwall2/test.sh +++ b/luci-app-passwall2/root/usr/share/passwall2/test.sh @@ -71,29 +71,11 @@ url_test_node() { sleep 1s result=$(curl --connect-timeout 3 -o /dev/null -I -skL -w "%{http_code}:%{time_starttransfer}" -x $curlx "https://www.google.com/generate_204") pgrep -af "url_test_${node_id}" | awk '! /test\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1 - rm -rf "/tmp/etc/${CONFIG}/url_test_${node_id}"*.json + rm -rf /tmp/etc/${CONFIG}/*url_test_${node_id}*.json } echo $result } -test_node() { - local node_id=$1 - local _type=$(echo $(config_n_get ${node_id} type) | tr 'A-Z' 'a-z') - [ -n "${_type}" ] && { - local _tmp_port=$(/usr/share/${CONFIG}/app.sh get_new_port 61080 tcp,udp) - /usr/share/${CONFIG}/app.sh run_socks flag="test_node_${node_id}" node=${node_id} bind=127.0.0.1 socks_port=${_tmp_port} config_file=test_node_${node_id}.json - local curlx="socks5h://127.0.0.1:${_tmp_port}" - sleep 1s - _proxy_status=$(test_url "https://www.google.com/generate_204" ${retry_num} ${connect_timeout} "-x $curlx") - pgrep -af "test_node_${node_id}" | awk '! /test\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1 - rm -rf "/tmp/etc/${CONFIG}/test_node_${node_id}.json" - if [ "${_proxy_status}" -eq 200 ]; then - return 0 - fi - } - return 1 -} - arg1=$1 shift case $arg1 in