update 2026-08-15 00:44:02

This commit is contained in:
action committed 2026-08-15 00:44:02 +08:00
1 parent 58e04d6ceb
commit a59171002f
84 files changed
+919 -835

No files matched your search

@@ -23,11 +23,11 @@ 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 "20"
local balancingStrategy = uci:get(appname, "@global_haproxy[0]", "balancingStrategy") or "roundrobin"
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 health_check_type = uci:get(api.c_config, "@global_haproxy[0]", "health_check_type") or "tcp"
local health_check_inter = uci:get(api.c_config, "@global_haproxy[0]", "health_check_inter") or "20"
local balancingStrategy = uci:get(api.c_config, "@global_haproxy[0]", "balancingStrategy") or "roundrobin"
local console_port = uci:get(api.c_config, "@global_haproxy[0]", "console_port")
local bind_local = uci:get(api.c_config, "@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
@@ -94,15 +94,15 @@ f_out:write(haproxy_config)
local listens = {}
uci:foreach(appname, "haproxy_config", function(t)
uci:foreach(api.c_config, "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)
local hop = (health_check_type == "passwall_logic") and (server_node.hysteria_hop or server_node.hysteria2_hop) or nil
local server_node = uci:get_all(api.c_config, lbss)
local hop = (health_check_type == "script_logic") and (server_node.hysteria_hop or server_node.hysteria2_hop) or nil
hop = hop and hop:gsub(":", "-") or nil
if server_node and server_node.address and (server_node.port or hop) then
server_remark = server_node.address .. ":" .. (server_node.port or hop)
@@ -110,7 +110,7 @@ uci:foreach(appname, "haproxy_config", function(t)
server_port = server_node.port or hop
t.origin_address = server_address
t.origin_port = server_port
if health_check_type == "passwall_logic" then
if health_check_type == "script_logic" then
if server_node.type ~= "Socks" then
local relay_port = server_node.port
local new_port = api.get_new_port()
@@ -172,7 +172,7 @@ listen %s
balance %s
]], port, bind_address, port, balancingStrategy))
if health_check_type == "passwall_logic" then
if health_check_type == "script_logic" then
f_out:write(string.format([[
option external-check
external-check command "/usr/share/%s/haproxy_check.sh"
@@ -214,8 +214,8 @@ listen %s
end
--控制台配置
local console_user = uci:get(appname, "@global_haproxy[0]", "console_user")
local console_password = uci:get(appname, "@global_haproxy[0]", "console_password")
local console_user = uci:get(api.c_config, "@global_haproxy[0]", "console_user")
local console_password = uci:get(api.c_config, "@global_haproxy[0]", "console_password")
local str = [[
listen console
bind 0.0.0.0:%s
@@ -230,8 +230,8 @@ f_out:write("\n" .. string.format(str, console_port, (console_user and console_u
f_out:close()
--passwall内置健康检查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"
if health_check_type == "script_logic" then
local probeUrl = uci:get(api.c_config, "@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()
@@ -31,8 +31,8 @@ local RULES_PATH = "/usr/share/" .. appname .. "/rules"
local FLAG_PATH = TMP_ACL_PATH .. "/" .. FLAG
local config_lines = {}
local tmp_lines = {}
local USE_GEOVIEW = uci:get(appname, "@global_rules[0]", "enable_geoview")
local IS_SHUNT_NODE = uci:get(appname, TCP_NODE, "protocol") == "_shunt"
local USE_GEOVIEW = uci:get(api.c_config, "@global_rules[0]", "enable_geoview")
local IS_SHUNT_NODE = uci:get(api.c_config, TCP_NODE, "protocol") == "_shunt"
if not api.is_finded("geoview") then
USE_GEOVIEW = "0"
@@ -92,7 +92,7 @@ local function insert_array_after(array1, array2, target) --将array2插入到ar
end
local function get_geosite(list_arg, out_path)
local geosite_path = uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
local geosite_path = uci:get(api.c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
geosite_path = geosite_path:match("^(.*)/") .. "/geosite.dat"
if not is_file_nonzero(geosite_path) then return 1 end
local bin = api.finded_com("geoview")
@@ -183,7 +183,7 @@ if not is_file_nonzero(file_vpslist) then
written_domains[address] = true
end
end
uci:foreach(appname, "nodes", function(t)
uci:foreach(api.c_config, "nodes", function(t)
process_address(t.address)
process_address(t.download_address)
local dns, _ = api.get_domain_port_from_url(t.domain_resolver_dns or t.domain_resolver_dns_https or "")
@@ -191,7 +191,7 @@ if not is_file_nonzero(file_vpslist) then
process_address(dns)
end
end)
uci:foreach(appname, "subscribe_list", function(t) --订阅链接
uci:foreach(api.c_config, "subscribe_list", function(t) --订阅链接
local url, _ = api.get_domain_port_from_url(t.url or "")
if url and url ~= "" then
process_address(url)
@@ -387,9 +387,9 @@ if IS_SHUNT_NODE then
local file_shunt_host = FLAG_PATH .. "/shunt_proxy_host"
local geosite_white_arg, geosite_shunt_arg = "", ""
local t = uci:get_all(appname, TCP_NODE)
local t = uci:get_all(api.c_config, TCP_NODE)
local default_node_id = t["default_node"] or "_direct"
uci:foreach(appname, "shunt_rules", function(s)
uci:foreach(api.c_config, "shunt_rules", function(s)
local _node_id = t[s[".name"]]
if _node_id and _node_id ~= "_blackhole" and t["shunt_group"] == s.group then
if _node_id == "_default" then
@@ -24,8 +24,8 @@ end
local function backup_servers()
local DNSMASQ_DNS = uci:get("dhcp", "@dnsmasq[0]", "server")
if DNSMASQ_DNS and #DNSMASQ_DNS > 0 then
uci:set(appname, "@global[0]", "dnsmasq_servers", DNSMASQ_DNS)
api.uci_save(uci, appname, true)
uci:set(api.c_config, "@global[0]", "dnsmasq_servers", DNSMASQ_DNS)
api.uci_save(uci, api.c_config, true)
end
end
@@ -37,13 +37,13 @@ local function restore_servers()
tinsert(dns_table, v)
end
end
local OLD_SERVER = uci:get(appname, "@global[0]", "dnsmasq_servers")
local OLD_SERVER = uci:get(api.c_config, "@global[0]", "dnsmasq_servers")
if OLD_SERVER and #OLD_SERVER > 0 then
for k, v in ipairs(OLD_SERVER) do
tinsert(dns_table, v)
end
uci:delete(appname, "@global[0]", "dnsmasq_servers")
api.uci_save(uci, appname, true)
uci:delete(api.c_config, "@global[0]", "dnsmasq_servers")
api.uci_save(uci, api.c_config, true)
end
if dns_table and #dns_table > 0 then
uci:set_list("dhcp", "@dnsmasq[0]", "server", dns_table)
@@ -180,8 +180,8 @@ function add_rule(var)
local CACHE_DNS_PATH = CACHE_PATH .. "/" .. CACHE_FLAG
local CACHE_TEXT_FILE = CACHE_DNS_PATH .. ".txt"
local USE_CHINADNS_NG = "0"
local IS_SHUNT_NODE = uci:get(appname, TCP_NODE, "protocol") == "_shunt"
local USE_GEOVIEW = uci:get(appname, "@global_rules[0]", "enable_geoview")
local IS_SHUNT_NODE = uci:get(api.c_config, TCP_NODE, "protocol") == "_shunt"
local USE_GEOVIEW = uci:get(api.c_config, "@global_rules[0]", "enable_geoview")
local list1 = {}
local excluded_domain = {}
@@ -307,7 +307,7 @@ function add_rule(var)
end
local function foreach_geosite(list_arg, callback)
local geosite_path = uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
local geosite_path = uci:get(api.c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
geosite_path = geosite_path:match("^(.*)/") .. "/geosite.dat"
if not fs.access(geosite_path) then return end
local bin = api.finded_com("geoview")
@@ -412,7 +412,7 @@ function add_rule(var)
set_domain_ipset(address, table.concat(sets, ","))
end
end
uci:foreach(appname, "nodes", function(t)
uci:foreach(api.c_config, "nodes", function(t)
process_address(t.address)
process_address(t.download_address)
local dns, _ = api.get_domain_port_from_url(t.domain_resolver_dns or t.domain_resolver_dns_https or "")
@@ -420,7 +420,7 @@ function add_rule(var)
process_address(dns)
end
end)
uci:foreach(appname, "subscribe_list", function(t) --订阅链接
uci:foreach(api.c_config, "subscribe_list", function(t) --订阅链接
local url, _ = api.get_domain_port_from_url(t.url or "")
if url and url ~= "" then
process_address(url)
@@ -615,9 +615,9 @@ function add_rule(var)
--分流规则
if IS_SHUNT_NODE and USE_CHINADNS_NG == "0" then
local t = uci:get_all(appname, TCP_NODE)
local t = uci:get_all(api.c_config, TCP_NODE)
local default_node_id = t["default_node"] or "_direct"
uci:foreach(appname, "shunt_rules", function(s)
uci:foreach(api.c_config, "shunt_rules", function(s)
local _node_id = t[s[".name"]]
if _node_id and _node_id ~= "_blackhole" and t["shunt_group"] == s.group then
if _node_id == "_default" then
@@ -37,8 +37,8 @@ local FLAG_PATH = TMP_ACL_PATH .. "/" .. FLAG
local TMP_CONF_FILE = FLAG_PATH .. "/smartdns.conf"
local config_lines = {}
local tmp_lines = {}
local USE_GEOVIEW = uci:get(appname, "@global_rules[0]", "enable_geoview")
local IS_SHUNT_NODE = uci:get(appname, TCP_NODE, "protocol") == "_shunt"
local USE_GEOVIEW = uci:get(api.c_config, "@global_rules[0]", "enable_geoview")
local IS_SHUNT_NODE = uci:get(api.c_config, TCP_NODE, "protocol") == "_shunt"
if not api.is_finded("geoview") then
USE_GEOVIEW = "0"
@@ -98,7 +98,7 @@ local function insert_array_after(array1, array2, target) --将array2插入到ar
end
local function get_geosite(list_arg, out_path)
local geosite_path = uci:get(appname, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
local geosite_path = uci:get(api.c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
geosite_path = geosite_path:match("^(.*)/") .. "/geosite.dat"
if not is_file_nonzero(geosite_path) then return 1 end
local bin = api.finded_com("geoview")
@@ -187,7 +187,7 @@ if not REMOTE_GROUP or REMOTE_GROUP == "nil" then
sys.call('sed -i "/passwall/d" /etc/smartdns/custom.conf >/dev/null 2>&1')
end
local force_https_soa = uci:get(appname, "@global[0]", "force_https_soa") or 0
local force_https_soa = uci:get(api.c_config, "@global[0]", "force_https_soa") or 0
local proxy_server_name = "passwall-proxy-server"
config_lines = {
tonumber(LISTEN_PORT) ~= 0 and "bind [::]:" .. LISTEN_PORT .. "@lo" or "",
@@ -342,7 +342,7 @@ if not is_file_nonzero(file_vpslist) then
written_domains[address] = true
end
end
uci:foreach(appname, "nodes", function(t)
uci:foreach(api.c_config, "nodes", function(t)
process_address(t.address)
process_address(t.download_address)
local dns, _ = api.get_domain_port_from_url(t.domain_resolver_dns or t.domain_resolver_dns_https or "")
@@ -350,7 +350,7 @@ if not is_file_nonzero(file_vpslist) then
process_address(dns)
end
end)
uci:foreach(appname, "subscribe_list", function(t) --订阅链接
uci:foreach(api.c_config, "subscribe_list", function(t) --订阅链接
local url, _ = api.get_domain_port_from_url(t.url or "")
if url and url ~= "" then
process_address(url)
@@ -555,9 +555,9 @@ if IS_SHUNT_NODE then
local file_shunt_host = FLAG_PATH .. "/shunt_proxy_host"
local geosite_white_arg, geosite_shunt_arg = "", ""
local t = uci:get_all(appname, TCP_NODE)
local t = uci:get_all(api.c_config, TCP_NODE)
local default_node_id = t["default_node"] or "_direct"
uci:foreach(appname, "shunt_rules", function(s)
uci:foreach(api.c_config, "shunt_rules", function(s)
local _node_id = t[s[".name"]]
if _node_id and _node_id ~= "_blackhole" and t["shunt_group"] == s.group then
if _node_id == "_default" then
@@ -2,6 +2,7 @@
local api = require ("luci.passwall.api")
local name = api.appname
local c_config = api.c_config
local uci = api.uci
local sys = api.sys
local jsonc = api.jsonc
@@ -23,14 +24,14 @@ local geosite_update = "0"
local excluded_domain = {"apple.com","sina.cn","sina.com.cn","baidu.com","byr.cn","jlike.com","weibo.com","zhongsou.com","youdao.com","sogou.com","so.com","soso.com","aliyun.com","taobao.com","jd.com","qq.com","bing.com"}
local gfwlist_url = uci:get(name, "@global_rules[0]", "gfwlist_url") or {"https://fastly.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/gfw.txt"}
local chnroute_url = uci:get(name, "@global_rules[0]", "chnroute_url") or {"https://ispip.clang.cn/all_cn.txt"}
local chnroute6_url = uci:get(name, "@global_rules[0]", "chnroute6_url") or {"https://ispip.clang.cn/all_cn_ipv6.txt"}
local chnlist_url = uci:get(name, "@global_rules[0]", "chnlist_url") or {"https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/accelerated-domains.china.conf","https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/apple.china.conf","https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/google.china.conf"}
local geoip_url = uci:get(name, "@global_rules[0]", "geoip_url") or "https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip.dat"
local geosite_url = uci:get(name, "@global_rules[0]", "geosite_url") or "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat"
local asset_location = uci:get(name, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
local geo2rule = uci:get(name, "@global_rules[0]", "geo2rule") or "0"
local gfwlist_url = uci:get(c_config, "@global_rules[0]", "gfwlist_url") or {"https://fastly.jsdelivr.net/gh/Loyalsoldier/v2ray-rules-dat@release/gfw.txt"}
local chnroute_url = uci:get(c_config, "@global_rules[0]", "chnroute_url") or {"https://ispip.clang.cn/all_cn.txt"}
local chnroute6_url = uci:get(c_config, "@global_rules[0]", "chnroute6_url") or {"https://ispip.clang.cn/all_cn_ipv6.txt"}
local chnlist_url = uci:get(c_config, "@global_rules[0]", "chnlist_url") or {"https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/accelerated-domains.china.conf","https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/apple.china.conf","https://fastly.jsdelivr.net/gh/felixonmars/dnsmasq-china-list/google.china.conf"}
local geoip_url = uci:get(c_config, "@global_rules[0]", "geoip_url") or "https://github.com/Loyalsoldier/geoip/releases/latest/download/geoip.dat"
local geosite_url = uci:get(c_config, "@global_rules[0]", "geosite_url") or "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/latest/download/geosite.dat"
local asset_location = uci:get(c_config, "@global_rules[0]", "v2ray_location_asset") or "/usr/share/v2ray/"
local geo2rule = uci:get(c_config, "@global_rules[0]", "geo2rule") or "0"
local geoip_update_ok, geosite_update_ok = false, false
asset_location = asset_location:match("/$") and asset_location or (asset_location .. "/")
local backup_path = "/tmp/bak_v2ray/"
@@ -659,12 +660,12 @@ if arg2 then
end)
if rollback then arg2 = nil end
else
gfwlist_update = uci:get(name, "@global_rules[0]", "gfwlist_update") or "1"
chnroute_update = uci:get(name, "@global_rules[0]", "chnroute_update") or "1"
chnroute6_update = uci:get(name, "@global_rules[0]", "chnroute6_update") or "1"
chnlist_update = uci:get(name, "@global_rules[0]", "chnlist_update") or "1"
geoip_update = uci:get(name, "@global_rules[0]", "geoip_update") or "1"
geosite_update = uci:get(name, "@global_rules[0]", "geosite_update") or "1"
gfwlist_update = uci:get(c_config, "@global_rules[0]", "gfwlist_update") or "1"
chnroute_update = uci:get(c_config, "@global_rules[0]", "chnroute_update") or "1"
chnroute6_update = uci:get(c_config, "@global_rules[0]", "chnroute6_update") or "1"
chnlist_update = uci:get(c_config, "@global_rules[0]", "chnlist_update") or "1"
geoip_update = uci:get(c_config, "@global_rules[0]", "geoip_update") or "1"
geosite_update = uci:get(c_config, "@global_rules[0]", "geosite_update") or "1"
end
if geo2rule ~= "1" and gfwlist_update == "0" and chnroute_update == "0" and chnroute6_update == "0" and chnlist_update == "0" and geoip_update == "0" and geosite_update == "0" then
os.exit(0)
@@ -777,13 +778,13 @@ else
end
if not rollback then
uci:set(name, "@global_rules[0]", "gfwlist_update", gfwlist_update)
uci:set(name, "@global_rules[0]", "chnroute_update", chnroute_update)
uci:set(name, "@global_rules[0]", "chnroute6_update", chnroute6_update)
uci:set(name, "@global_rules[0]", "chnlist_update", chnlist_update)
uci:set(name, "@global_rules[0]", "geoip_update", geoip_update)
uci:set(name, "@global_rules[0]", "geosite_update", geosite_update)
api.uci_save(uci, name, true)
uci:set(c_config, "@global_rules[0]", "gfwlist_update", gfwlist_update)
uci:set(c_config, "@global_rules[0]", "chnroute_update", chnroute_update)
uci:set(c_config, "@global_rules[0]", "chnroute6_update", chnroute6_update)
uci:set(c_config, "@global_rules[0]", "chnlist_update", chnlist_update)
uci:set(c_config, "@global_rules[0]", "geoip_update", geoip_update)
uci:set(c_config, "@global_rules[0]", "geosite_update", geosite_update)
api.uci_save(uci, c_config, true)
end
if reboot == 1 then
@@ -794,8 +795,8 @@ if reboot == 1 then
end
log("重启服务,应用新的规则。")
uci:set(name, "@global[0]", "flush_set", "1")
api.uci_save(uci, name, true, true)
uci:set(c_config, "@global[0]", "flush_set", "1")
api.uci_save(uci, c_config, true, true)
end
log("规则更新完毕...\n")
@@ -6,8 +6,9 @@
require 'luci.util'
require 'luci.jsonc'
require 'luci.sys'
local appname = 'passwall'
local api = require ("luci.passwall.api")
local api = require "luci.passwall.api"
local appname = api.appname
local c_config = api.c_config
local datatypes = require "luci.cbi.datatypes"
loadfile("/usr/share/" .. appname .. "/clash_subconverter.lua")()
@@ -30,9 +31,9 @@ local has_singbox = api.finded_com("sing-box")
local has_xray = api.finded_com("xray")
local has_hysteria2 = api.finded_com("hysteria")
local DEFAULT_ALLOWINSECURE = true
local DEFAULT_FILTER_KEYWORD_MODE = uci:get(appname, "@global_subscribe[0]", "filter_keyword_mode") or "0"
local DEFAULT_FILTER_KEYWORD_DISCARD_LIST = uci:get(appname, "@global_subscribe[0]", "filter_discard_list") or {}
local DEFAULT_FILTER_KEYWORD_KEEP_LIST = uci:get(appname, "@global_subscribe[0]", "filter_keep_list") or {}
local DEFAULT_FILTER_KEYWORD_MODE = uci:get(c_config, "@global_subscribe[0]", "filter_keyword_mode") or "0"
local DEFAULT_FILTER_KEYWORD_DISCARD_LIST = uci:get(c_config, "@global_subscribe[0]", "filter_discard_list") or {}
local DEFAULT_FILTER_KEYWORD_KEEP_LIST = uci:get(c_config, "@global_subscribe[0]", "filter_keep_list") or {}
-- 取节点使用core类型(节点订阅页面未设置时,自动取默认)
local DEFAULT_SS_TYPE = api.get_core("ss_type", {{has_ss_rust,"shadowsocks-rust"},{has_singbox,"sing-box"},{has_xray,"xray"}})
local DEFAULT_TROJAN_TYPE = api.get_core("trojan_type", {{has_singbox,"sing-box"},{has_xray,"xray"}})
@@ -141,13 +142,13 @@ do
local szType = "@global[0]"
local option = protocol .. "_node"
local node_id = uci:get(appname, szType, option)
local node_id = uci:get(c_config, szType, option)
CONFIG[#CONFIG + 1] = {
log = true,
remarks = name .. "节点",
currentNode = node_id and uci:get_all(appname, node_id) or nil,
currentNode = node_id and uci:get_all(c_config, node_id) or nil,
set = function(o, server)
uci:set(appname, szType, option, server)
uci:set(c_config, szType, option, server)
o.newNodeId = server
end
}
@@ -158,7 +159,7 @@ do
if true then
local i = 0
local option = "node"
uci:foreach(appname, "socks", function(t)
uci:foreach(c_config, "socks", function(t)
i = i + 1
local id = t[".name"]
local node_id = t[option]
@@ -166,14 +167,14 @@ do
log = true,
id = id,
remarks = "Socks节点列表[" .. i .. "]",
currentNode = node_id and uci:get_all(appname, node_id) or nil,
currentNode = node_id and uci:get_all(c_config, node_id) or nil,
set = function(o, server)
if not server or server == "" then
if #nodes_table > 0 then
server = nodes_table[1][".name"]
end
end
uci:set(appname, t[".name"], option, server)
uci:set(c_config, t[".name"], option, server)
o.newNodeId = server
end
}
@@ -183,7 +184,7 @@ do
local newNodes = {}
for k, asb_node_id in ipairs(t.autoswitch_backup_node) do
if asb_node_id then
local currentNode = uci:get_all(appname, asb_node_id) or {}
local currentNode = uci:get_all(c_config, asb_node_id) or {}
if currentNode[".type"] == "nodes" then
currentNodes[#currentNodes + 1] = {
log = true,
@@ -205,7 +206,7 @@ do
set = function(o, newNodes)
if o then
if not newNodes then newNodes = o.newNodes end
uci:set_list(appname, id, "autoswitch_backup_node", newNodes or {})
uci:set_list(c_config, id, "autoswitch_backup_node", newNodes or {})
end
end
}
@@ -221,25 +222,25 @@ do
local ip, port = str:match("^([%d%.]+):(%d+)$")
return ip and datatypes.ipaddr(ip) and tonumber(port) and tonumber(port) <= 65535
end
uci:foreach(appname, "haproxy_config", function(t)
uci:foreach(c_config, "haproxy_config", function(t)
i = i + 1
local node_id = t[option]
CONFIG[#CONFIG + 1] = {
log = true,
id = t[".name"],
remarks = "HAProxy负载均衡节点列表[" .. i .. "]",
currentNode = node_id and uci:get_all(appname, node_id) or nil,
currentNode = node_id and uci:get_all(c_config, node_id) or nil,
set = function(o, server)
-- 如果当前 lbss 值不是 ip:port 格式,才进行修改
if not is_ip_port(t[option]) then
uci:set(appname, t[".name"], option, server)
uci:set(c_config, t[".name"], option, server)
o.newNodeId = server
end
end,
delete = function(o)
-- 如果当前 lbss 值不是 ip:port 格式,才进行删除
if not is_ip_port(t[option]) then
uci:delete(appname, t[".name"])
uci:delete(c_config, t[".name"])
end
end
}
@@ -249,7 +250,7 @@ do
if true then
local i = 0
local options = {"tcp", "udp"}
uci:foreach(appname, "acl_rule", function(t)
uci:foreach(c_config, "acl_rule", function(t)
i = i + 1
for index, value in ipairs(options) do
local option = value .. "_node"
@@ -258,9 +259,9 @@ do
log = true,
id = t[".name"],
remarks = "访问控制列表[" .. i .. "]",
currentNode = node_id and uci:get_all(appname, node_id) or nil,
currentNode = node_id and uci:get_all(c_config, node_id) or nil,
set = function(o, server)
uci:set(appname, t[".name"], option, server)
uci:set(c_config, t[".name"], option, server)
o.newNodeId = server
end
}
@@ -268,11 +269,11 @@ do
end)
end
uci:foreach(appname, "nodes", function(node)
uci:foreach(c_config, "nodes", function(node)
local node_id = node[".name"]
if node.protocol and node.protocol == '_shunt' then
local rules = {}
uci:foreach(appname, "shunt_rules", function(e)
uci:foreach(c_config, "shunt_rules", function(e)
if e[".name"] and e.remarks then
table.insert(rules, e)
table.insert(rules, {
@@ -293,7 +294,7 @@ do
for k, e in pairs(rules) do
local _node_id = node[e[".name"]] or nil
if _node_id then
local section = uci:get_all(appname, _node_id) or {}
local section = uci:get_all(c_config, _node_id) or {}
if section[".type"] == "nodes" then
CONFIG[#CONFIG + 1] = {
log = false,
@@ -301,7 +302,7 @@ do
remarks = "分流" .. e.remarks .. "节点",
set = function(o, server)
if not server then server = "" end
uci:set(appname, node_id, e[".name"], server)
uci:set(c_config, node_id, e[".name"], server)
o.newNodeId = server
end
}
@@ -318,7 +319,7 @@ do
log = true,
node = b_node_id,
currentNode = (function()
local section = uci:get_all(appname, b_node_id) or {}
local section = uci:get_all(c_config, b_node_id) or {}
if section[".type"] == "socks" then
return { Socks = b_node_id }
end
@@ -340,15 +341,15 @@ do
set = function(o, newNodes)
if o then
if not newNodes then newNodes = o.newNodes end
uci:set_list(appname, node_id, "balancing_node", newNodes or {})
uci:set_list(c_config, node_id, "balancing_node", newNodes or {})
end
end
}
--后备节点
local currentNode = uci:get_all(appname, node_id) or nil
local currentNode = uci:get_all(c_config, node_id) or nil
if currentNode and currentNode.fallback_node then
local section = uci:get_all(appname, currentNode.fallback_node) or {}
local section = uci:get_all(c_config, currentNode.fallback_node) or {}
if section[".type"] == "nodes" then
CONFIG[#CONFIG + 1] = {
log = true,
@@ -356,11 +357,11 @@ do
remarks = "Xray负载均衡节点[" .. node_id .. "]后备节点",
currentNode = section,
set = function(o, server)
uci:set(appname, node_id, "fallback_node", server)
uci:set(c_config, node_id, "fallback_node", server)
o.newNodeId = server
end,
delete = function(o)
uci:delete(appname, node_id, "fallback_node")
uci:delete(c_config, node_id, "fallback_node")
end
}
end
@@ -375,7 +376,7 @@ do
log = true,
node = u_node_id,
currentNode = (function()
local section = uci:get_all(appname, u_node_id) or {}
local section = uci:get_all(c_config, u_node_id) or {}
if section[".type"] == "socks" then
return { Socks = u_node_id }
end
@@ -397,47 +398,47 @@ do
set = function(o, newNodes)
if o then
if not newNodes then newNodes = o.newNodes end
uci:set_list(appname, node_id, "urltest_node", newNodes or {})
uci:set_list(c_config, node_id, "urltest_node", newNodes or {})
end
end
}
else
--前置代理节点
local currentNode = uci:get_all(appname, node_id) or nil
local currentNode = uci:get_all(c_config, node_id) or nil
if currentNode and currentNode.preproxy_node then
local section = uci:get_all(appname, currentNode.preproxy_node) or {}
local section = uci:get_all(c_config, currentNode.preproxy_node) or {}
if section[".type"] == "nodes" then
CONFIG[#CONFIG + 1] = {
log = true,
id = node_id,
remarks = "节点[" .. node_id .. "]前置代理节点",
currentNode = uci:get_all(appname, currentNode.preproxy_node) or nil,
currentNode = uci:get_all(c_config, currentNode.preproxy_node) or nil,
set = function(o, server)
uci:set(appname, node_id, "preproxy_node", server)
uci:set(c_config, node_id, "preproxy_node", server)
o.newNodeId = server
end,
delete = function(o)
uci:delete(appname, node_id, "preproxy_node")
uci:delete(c_config, node_id, "preproxy_node")
end
}
end
end
--落地节点
local currentNode = uci:get_all(appname, node_id) or nil
local currentNode = uci:get_all(c_config, node_id) or nil
if currentNode and currentNode.to_node then
local section = uci:get_all(appname, currentNode.to_node) or {}
local section = uci:get_all(c_config, currentNode.to_node) or {}
if section[".type"] == "nodes" then
CONFIG[#CONFIG + 1] = {
log = true,
id = node_id,
remarks = "节点[" .. node_id .. "]落地节点",
currentNode = uci:get_all(appname, currentNode.to_node) or nil,
currentNode = uci:get_all(c_config, currentNode.to_node) or nil,
set = function(o, server)
uci:set(appname, node_id, "to_node", server)
uci:set(c_config, node_id, "to_node", server)
o.newNodeId = server
end,
delete = function(o)
uci:delete(appname, node_id, "to_node")
uci:delete(c_config, node_id, "to_node")
end
}
end
@@ -1756,19 +1757,19 @@ local function truncate_nodes(group)
end
end
end
uci:foreach(appname, "nodes", function(node)
uci:foreach(c_config, "nodes", function(node)
if node.add_mode == "2" then
if (not group) or (group:lower() == (node.group or ""):lower()) then
uci:delete(appname, node['.name'])
uci:delete(c_config, node['.name'])
end
end
end)
uci:foreach(appname, "subscribe_list", function(o)
uci:foreach(c_config, "subscribe_list", function(o)
if (not group) or (group:lower() == (o.remark or ""):lower()) then
uci:delete(appname, o['.name'], "md5")
uci:delete(c_config, o['.name'], "md5")
end
end)
api.uci_save(uci, appname, true)
api.uci_save(uci, c_config, true)
end
local function select_node(nodes, config, parentConfig)
@@ -1907,10 +1908,10 @@ local function update_node(manual)
end
if manual == 0 and next(group) then
uci:foreach(appname, "nodes", function(node)
uci:foreach(c_config, "nodes", function(node)
-- 如果未发现新节点或手动导入的节点就不要删除了...
if node.add_mode == "2" and (node.group and group[node.group:lower()] == true) then
uci:delete(appname, node['.name'])
uci:delete(c_config, node['.name'])
end
end)
end
@@ -1923,9 +1924,9 @@ local function update_node(manual)
-- Subscription Group Chain Agent
local function valid_chain_node(node)
if not node then return "" end
local cp = uci:get(appname, node, "chain_proxy") or ""
local am = uci:get(appname, node, "add_mode") or "0"
chain_node_type = (cp == "" and am ~= "2") and (uci:get(appname, node, "type") or "") or ""
local cp = uci:get(c_config, node, "chain_proxy") or ""
local am = uci:get(c_config, node, "add_mode") or "0"
chain_node_type = (cp == "" and am ~= "2") and (uci:get(c_config, node, "type") or "") or ""
if chain_node_type ~= "Xray" and chain_node_type ~= "sing-box" then
chain_node_type = ""
return ""
@@ -1944,22 +1945,22 @@ local function update_node(manual)
chain_node_type = (outbound_iface_group ~= "") and "iface" or chain_node_type
end
for _, vv in ipairs(list) do
local cfgid = uci:section(appname, "nodes", api.gen_random_char())
local cfgid = uci:section(c_config, "nodes", api.gen_random_char())
for kkk, vvv in pairs(vv) do
if type(vvv) == "table" and next(vvv) ~= nil then
uci:set_list(appname, cfgid, kkk, vvv)
uci:set_list(c_config, cfgid, kkk, vvv)
else
if kkk ~= "group" or vvv ~= "default" then
uci:set(appname, cfgid, kkk, vvv)
uci:set(c_config, cfgid, kkk, vvv)
end
-- sing-box/xray 节点域名解析
if kkk == "type" and (vvv == "Xray" or vvv == "sing-box") then
if domain_resolver then
uci:set(appname, cfgid, "domain_resolver", domain_resolver)
uci:set(c_config, cfgid, "domain_resolver", domain_resolver)
if domain_resolver_dns then
uci:set(appname, cfgid, "domain_resolver_dns", domain_resolver_dns)
uci:set(c_config, cfgid, "domain_resolver_dns", domain_resolver_dns)
elseif domain_resolver_dns_https then
uci:set(appname, cfgid, "domain_resolver_dns_https", domain_resolver_dns_https)
uci:set(c_config, cfgid, "domain_resolver_dns_https", domain_resolver_dns_https)
end
end
if domain_strategy then
@@ -1968,20 +1969,20 @@ local function update_node(manual)
local map = { UseIPv4v6 = "prefer_ipv4", UseIPv6v4 = "prefer_ipv6", UseIPv4 = "ipv4_only", UseIPv6 = "ipv6_only" }
ds = map[ds] or ""
end
uci:set(appname, cfgid, "domain_strategy", ds)
uci:set(c_config, cfgid, "domain_strategy", ds)
end
end
-- 订阅组链式代理
if chain_node_type ~= "" and kkk == "type" and (vvv == "Xray" or vvv == "sing-box") then
if preproxy_node_group ~="" then
uci:set(appname, cfgid, "chain_proxy", "1")
uci:set(appname, cfgid, "preproxy_node", preproxy_node_group)
uci:set(c_config, cfgid, "chain_proxy", "1")
uci:set(c_config, cfgid, "preproxy_node", preproxy_node_group)
elseif to_node_group ~= "" then
uci:set(appname, cfgid, "chain_proxy", "2")
uci:set(appname, cfgid, "to_node", to_node_group)
uci:set(c_config, cfgid, "chain_proxy", "2")
uci:set(c_config, cfgid, "to_node", to_node_group)
elseif outbound_iface_group ~= "" then
uci:set(appname, cfgid, "chain_proxy", "3")
uci:set(appname, cfgid, "outbound_iface", outbound_iface_group)
uci:set(c_config, cfgid, "chain_proxy", "3")
uci:set(c_config, cfgid, "outbound_iface", outbound_iface_group)
end
end
end
@@ -1992,16 +1993,16 @@ local function update_node(manual)
for cfgid, info in pairs(subscribe_info) do
for key, value in pairs(info) do
if value ~= "" then
uci:set(appname, cfgid, key, value)
uci:set(c_config, cfgid, key, value)
else
uci:delete(appname, cfgid, key)
uci:delete(c_config, cfgid, key)
end
end
end
if next(CONFIG) then
local nodes = {}
uci:foreach(appname, "nodes", function(node)
uci:foreach(c_config, "nodes", function(node)
nodes[#nodes + 1] = node
end)
@@ -2020,11 +2021,11 @@ local function update_node(manual)
end
end
api.uci_save(uci, appname, true)
api.uci_save(uci, c_config, true)
if arg[3] == "cron" then
if not fs.access("/var/lock/" .. appname .. ".lock") then
luci.sys.call("touch /tmp/lock/" .. appname .. "_cron.lock")
if not fs.access("/var/lock/" .. c_config .. ".lock") then
luci.sys.call("touch /tmp/lock/" .. c_config .. "_cron.lock")
end
end
@@ -2133,10 +2134,10 @@ local execute = function()
local fail_list = {}
if arg[2] ~= "all" then
string.gsub(arg[2], '[^' .. "," .. ']+', function(w)
subscribe_list[#subscribe_list + 1] = uci:get_all(appname, w) or {}
subscribe_list[#subscribe_list + 1] = uci:get_all(c_config, w) or {}
end)
else
uci:foreach(appname, "subscribe_list", function(o)
uci:foreach(c_config, "subscribe_list", function(o)
subscribe_list[#subscribe_list + 1] = o
end)
end
@@ -2182,7 +2183,7 @@ local execute = function()
raw_data = parseClashNode(raw_data)
subscribe_info[cfgid] = parse_clash_sub_info(headers)
parse_link(raw_data, "2", remark, value)
uci:set(appname, cfgid, "md5", new_md5)
uci:set(c_config, cfgid, "md5", new_md5)
end
else
fail_list[#fail_list + 1] = value
@@ -2216,7 +2217,7 @@ local function check_instance(action)
os.exit(0)
else
luci.sys.call("touch " .. sub_lock)
uci:revert(appname)
uci:revert(c_config)
end
elseif action == "end" then
luci.sys.call("rm -f " .. sub_lock)