update 2025-05-14 20:43:39

This commit is contained in:
kenzok8 2025-05-14 20:43:39 +08:00
parent 7046da83c4
commit feada62c4b
3 changed files with 248 additions and 239 deletions

View File

@ -1,239 +1,239 @@
#!/usr/bin/lua #!/usr/bin/lua
local api = require ("luci.passwall.api") local api = require ("luci.passwall.api")
local appname = "passwall" local appname = "passwall"
local fs = api.fs local fs = api.fs
local jsonc = api.jsonc local jsonc = api.jsonc
local uci = api.uci local uci = api.uci
local sys = api.sys local sys = api.sys
local log = function(...) local log = function(...)
api.log(...) api.log(...)
end end
function get_ip_port_from(str) function get_ip_port_from(str)
local result_port = sys.exec("echo -n " .. str .. " | sed -n 's/^.*[:#]\\([0-9]*\\)$/\\1/p'") 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}*}}") local result_ip = sys.exec(string.format("__host=%s;__varport=%s;", str, result_port) .. "echo -n ${__host%%${__varport:+[:#]${__varport}*}}")
return result_ip, result_port return result_ip, result_port
end end
local new_port local new_port
local function get_new_port() local function get_new_port()
if new_port then 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))) new_port = tonumber(sys.exec(string.format("echo -n $(/usr/share/%s/app.sh get_new_port %s tcp)", appname, new_port + 1)))
else else
new_port = tonumber(sys.exec(string.format("echo -n $(/usr/share/%s/app.sh get_new_port auto tcp)", appname))) new_port = tonumber(sys.exec(string.format("echo -n $(/usr/share/%s/app.sh get_new_port auto tcp)", appname)))
end end
return new_port return new_port
end end
local var = api.get_args(arg) local var = api.get_args(arg)
local haproxy_path = var["-path"] local haproxy_path = var["-path"]
local haproxy_conf = var["-conf"] local haproxy_conf = var["-conf"]
local haproxy_dns = var["-dns"] or "119.29.29.29:53,223.5.5.5:53" 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 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_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 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 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_local = uci:get(appname, "@global_haproxy[0]", "bind_local") or "0"
local bind_address = "0.0.0.0" local bind_address = "0.0.0.0"
if bind_local == "1" then bind_address = "127.0.0.1" end if bind_local == "1" then bind_address = "127.0.0.1" end
log("HAPROXY 负载均衡:") log("HAPROXY 负载均衡:")
log(string.format(" * 控制台端口:%s", console_port)) log(string.format(" * 控制台端口:%s", console_port))
fs.mkdir(haproxy_path) fs.mkdir(haproxy_path)
local haproxy_file = haproxy_path .. "/" .. haproxy_conf local haproxy_file = haproxy_path .. "/" .. haproxy_conf
local f_out = io.open(haproxy_file, "a") local f_out = io.open(haproxy_file, "a")
local haproxy_config = [[ local haproxy_config = [[
global global
daemon daemon
log 127.0.0.1 local2 log 127.0.0.1 local2
maxconn 60000 maxconn 60000
stats socket {{path}}/haproxy.sock stats socket {{path}}/haproxy.sock
nbthread {{nbthread}} nbthread {{nbthread}}
external-check external-check
insecure-fork-wanted insecure-fork-wanted
defaults defaults
mode tcp mode tcp
log global log global
option tcplog option tcplog
option dontlognull option dontlognull
option http-server-close option http-server-close
#option forwardfor except 127.0.0.0/8 #option forwardfor except 127.0.0.0/8
option redispatch option redispatch
retries 2 retries 2
timeout http-request 10s timeout http-request 10s
timeout queue 1m timeout queue 1m
timeout connect 10s timeout connect 10s
timeout client 1m timeout client 1m
timeout server 1m timeout server 1m
timeout http-keep-alive 10s timeout http-keep-alive 10s
timeout check 10s timeout check 10s
maxconn 3000 maxconn 3000
resolvers mydns resolvers mydns
resolve_retries 1 resolve_retries 1
timeout resolve 5s timeout resolve 5s
hold valid 600s hold valid 600s
{{dns}} {{dns}}
]] ]]
haproxy_config = haproxy_config:gsub("{{path}}", haproxy_path) haproxy_config = haproxy_config:gsub("{{path}}", haproxy_path)
haproxy_config = haproxy_config:gsub("{{nbthread}}", cpu_thread) haproxy_config = haproxy_config:gsub("{{nbthread}}", cpu_thread)
local mydns = "" local mydns = ""
local index = 0 local index = 0
string.gsub(haproxy_dns, '[^' .. "," .. ']+', function(w) string.gsub(haproxy_dns, '[^' .. "," .. ']+', function(w)
index = index + 1 index = index + 1
local s = w:gsub("#", ":") local s = w:gsub("#", ":")
if not s:find(":") then if not s:find(":") then
s = s .. ":53" s = s .. ":53"
end end
mydns = mydns .. (index > 1 and "\n" or "") .. " " .. string.format("nameserver dns%s %s", index, s) mydns = mydns .. (index > 1 and "\n" or "") .. " " .. string.format("nameserver dns%s %s", index, s)
end) end)
haproxy_config = haproxy_config:gsub("{{dns}}", mydns) haproxy_config = haproxy_config:gsub("{{dns}}", mydns)
f_out:write(haproxy_config) f_out:write(haproxy_config)
local listens = {} local listens = {}
uci:foreach(appname, "haproxy_config", function(t) uci:foreach(appname, "haproxy_config", function(t)
if t.enabled == "1" then if t.enabled == "1" then
local server_remark local server_remark
local server_address local server_address
local server_port local server_port
local lbss = t.lbss local lbss = t.lbss
local listen_port = tonumber(t.haproxy_port) or 0 local listen_port = tonumber(t.haproxy_port) or 0
local server_node = uci:get_all(appname, lbss) local server_node = uci:get_all(appname, lbss)
if server_node and server_node.address and server_node.port then if server_node and server_node.address and server_node.port then
server_remark = server_node.address .. ":" .. server_node.port server_remark = server_node.address .. ":" .. server_node.port
server_address = server_node.address server_address = server_node.address
server_port = server_node.port server_port = server_node.port
t.origin_address = server_address t.origin_address = server_address
t.origin_port = server_port t.origin_port = server_port
if health_check_type == "passwall_logic" then if health_check_type == "passwall_logic" then
if server_node.type ~= "Socks" then if server_node.type ~= "Socks" then
local relay_port = server_node.port local relay_port = server_node.port
new_port = get_new_port() new_port = get_new_port()
local config_file = string.format("haproxy_%s_%s.json", t[".name"], 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', sys.call(string.format('/usr/share/%s/app.sh run_socks "%s"> /dev/null',
appname, appname,
string.format("flag=%s node=%s bind=%s socks_port=%s config_file=%s", string.format("flag=%s node=%s bind=%s socks_port=%s config_file=%s",
new_port, --flag new_port, --flag
server_node[".name"], --node server_node[".name"], --node
"127.0.0.1", --bind "127.0.0.1", --bind
new_port, --socks port new_port, --socks port
config_file --config file config_file --config file
) )
) )
) )
server_address = "127.0.0.1" server_address = "127.0.0.1"
server_port = new_port server_port = new_port
end end
end end
else else
server_address, server_port = get_ip_port_from(lbss) server_address, server_port = get_ip_port_from(lbss)
server_remark = server_address .. ":" .. server_port server_remark = server_address .. ":" .. server_port
t.origin_address = server_address t.origin_address = server_address
t.origin_port = server_port t.origin_port = server_port
end end
if server_address and server_port and listen_port > 0 then if server_address and server_port and listen_port > 0 then
if not listens[listen_port] then if not listens[listen_port] then
listens[listen_port] = {} listens[listen_port] = {}
end end
t.server_remark = server_remark t.server_remark = server_remark
t.server_address = server_address t.server_address = server_address
t.server_port = server_port t.server_port = server_port
table.insert(listens[listen_port], t) table.insert(listens[listen_port], t)
else else
log(" - 丢弃1个明显无效的节点") log(" - 丢弃1个明显无效的节点")
end end
end end
end) end)
local sortTable = {} local sortTable = {}
for i in pairs(listens) do for i in pairs(listens) do
if i ~= nil then if i ~= nil then
table.insert(sortTable, i) table.insert(sortTable, i)
end end
end end
table.sort(sortTable, function(a,b) return (a < b) end) table.sort(sortTable, function(a,b) return (a < b) end)
for i, port in pairs(sortTable) do for i, port in pairs(sortTable) do
log(" + 入口 %s:%s" % {bind_address, port}) log(" + 入口 %s:%s" % {bind_address, port})
f_out:write("\n" .. string.format([[ f_out:write("\n" .. string.format([[
listen %s listen %s
bind %s:%s bind %s:%s
mode tcp mode tcp
balance roundrobin balance roundrobin
]], port, bind_address, port)) ]], port, bind_address, port))
if health_check_type == "passwall_logic" then if health_check_type == "passwall_logic" then
f_out:write(string.format([[ f_out:write(string.format([[
option external-check option external-check
external-check command "/usr/share/passwall/haproxy_check.sh" external-check command "/usr/share/passwall/haproxy_check.sh"
]], port, port)) ]], port, port))
end end
local count_M, count_B = 1, 1 local count_M, count_B = 1, 1
for i, o in ipairs(listens[port]) do for i, o in ipairs(listens[port]) do
local remark = o.server_remark or "" local remark = o.server_remark or ""
-- 防止重名导致无法运行 -- 防止重名导致无法运行
if tostring(o.backup) ~= "1" then if tostring(o.backup) ~= "1" then
remark = "M" .. count_M .. "-" .. remark remark = "M" .. count_M .. "-" .. remark
count_M = count_M + 1 count_M = count_M + 1
else else
remark = "B" .. count_B .. "-" .. remark remark = "B" .. count_B .. "-" .. remark
count_B = count_B + 1 count_B = count_B + 1
end end
local server = o.server_address .. ":" .. o.server_port 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}}" 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("{{remark}}", remark)
server_conf = server_conf:gsub("{{server}}", server) server_conf = server_conf:gsub("{{server}}", server)
server_conf = server_conf:gsub("{{weight}}", o.lbweight) server_conf = server_conf:gsub("{{weight}}", o.lbweight)
local resolvers = "resolvers mydns" local resolvers = "resolvers mydns"
if api.is_ip(o.server_address) then if api.is_ip(o.server_address) then
resolvers = "" resolvers = ""
end end
server_conf = server_conf:gsub("{{resolvers}}", resolvers) server_conf = server_conf:gsub("{{resolvers}}", resolvers)
server_conf = server_conf:gsub("{{inter}}", tonumber(health_check_inter) .. "s") server_conf = server_conf:gsub("{{inter}}", tonumber(health_check_inter) .. "s")
server_conf = server_conf:gsub("{{backup}}", tostring(o.backup) == "1" and "backup" or "") server_conf = server_conf:gsub("{{backup}}", tostring(o.backup) == "1" and "backup" or "")
f_out:write(" " .. server_conf .. "\n") f_out:write(" " .. server_conf .. "\n")
if o.export ~= "0" then if o.export ~= "0" then
sys.call(string.format("/usr/share/passwall/app.sh add_ip2route %s %s", o.origin_address, o.export)) sys.call(string.format("/usr/share/passwall/app.sh add_ip2route %s %s", o.origin_address, o.export))
end end
log(string.format(" | - 出口节点:%s:%s权重%s", o.origin_address, o.origin_port, o.lbweight)) log(string.format(" | - 出口节点:%s:%s权重%s", o.origin_address, o.origin_port, o.lbweight))
end end
end end
--控制台配置 --控制台配置
local console_user = uci:get(appname, "@global_haproxy[0]", "console_user") local console_user = uci:get(appname, "@global_haproxy[0]", "console_user")
local console_password = uci:get(appname, "@global_haproxy[0]", "console_password") local console_password = uci:get(appname, "@global_haproxy[0]", "console_password")
local str = [[ local str = [[
listen console listen console
bind 0.0.0.0:%s bind 0.0.0.0:%s
mode http mode http
stats refresh 30s stats refresh 30s
stats uri / stats uri /
stats admin if TRUE stats admin if TRUE
%s %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: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() f_out:close()
--passwall内置健康检查URL --passwall内置健康检查URL
if health_check_type == "passwall_logic" then 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 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") local f_url = io.open(haproxy_path .. "/Probe_URL", "w")
f_url:write(probeUrl) f_url:write(probeUrl)
f_url:close() f_url:close()
end end

View File

@ -1,5 +1,7 @@
#!/bin/sh #!/bin/sh
export PATH=/usr/sbin:/usr/bin:/sbin:/bin:/root/bin
listen_address=$1 listen_address=$1
listen_port=$2 listen_port=$2
server_address=$3 server_address=$3

View File

@ -24,6 +24,13 @@
#【说在前面的话】此次酷猫主题研发借鉴:Opentopd主题、Jerryk大神argon主题、以及thinktip大神的neobird主题的部分灵感及参考借用部分代码在这里表示感谢感谢有你们珠玉在前 #【说在前面的话】此次酷猫主题研发借鉴:Opentopd主题、Jerryk大神argon主题、以及thinktip大神的neobird主题的部分灵感及参考借用部分代码在这里表示感谢感谢有你们珠玉在前
#目前源码暂不开源,如果你们需要联系本人可以免费获取。 #目前源码暂不开源,如果你们需要联系本人可以免费获取。
# 特殊说明
- 当系统中 有进阶设置又有 KUCAT主题设置工具时 以进阶设置中的设置为准。
- 如果设置上有问题可以在SSH登陆后用4号功能恢复设置。
- 如果是进阶设置,恢复默认设置,可以用:/etc/init.d/advancedplus reset
-
# 为什么叫酷猫 # 为什么叫酷猫
## 二个原因: ## 二个原因: