Compare commits

...
2 Commits
Author SHA1 Message Date
action 300b28d2ef update 2026-10-02 11:41:37 2026-10-02 11:41:37 +08:00
action a4813b97a5 update 2026-10-02 07:38:12 2026-10-02 07:38:12 +08:00
9 changed files with 239 additions and 335 deletions

No files matched your search

+8 -17
View File
@@ -14,22 +14,14 @@ set_lock() {
flock -xn 999
}
unset_lock() {
flock -u 999
rm -rf "$LOCK_FILE"
set_lock_wait() {
[ ! -d "$LOCK_PATH" ] && mkdir -p "$LOCK_PATH"
exec 999>"$LOCK_FILE"
flock -x 999
}
unlock() {
failcount=1
while [ "$failcount" -le 10 ]; do
if [ -f "$LOCK_FILE" ]; then
let "failcount++"
sleep 1s
[ "$failcount" -ge 10 ] && unset_lock
else
break
fi
done
unset_lock() {
flock -u 999
}
boot_func() {
@@ -57,9 +49,8 @@ start() {
}
stop() {
unlock
set_lock
[ $? == 1 ] && echolog "停止脚本等待超时,不重复运行,退出." && exit 0
set_lock_wait
[ $? != 0 ] && echolog "无法取得停止锁,退出." && exit 1
$APP_FILE stop $2
unset_lock
}
@@ -378,20 +378,23 @@ if CHNLIST ~= "0" and is_file_nonzero(RULES_PATH .. "/chnlist") then
end
--分流规则
if IS_SHUNT_NODE then
local white_domain, lookup_white_domain = {}, {}
local shunt_domain, lookup_shunt_domain = {}, {}
if IS_SHUNT_NODE and not only_global then
local direct_domain, lookup_direct_domain = {}, {}
local proxy_domain, lookup_proxy_domain = {}, {}
local black_domain, lookup_black_domain = {}, {}
local CACHE_FLAG_PATH = CACHE_RULES_PATH .. "/" .. FLAG
local file_white_host = CACHE_FLAG_PATH .. "/shunt_direct_host"
local file_shunt_host = CACHE_FLAG_PATH .. "/shunt_proxy_host"
local geosite_white_arg, geosite_shunt_arg = "", ""
local shunt_direct_host = CACHE_FLAG_PATH .. "/shunt_direct_host"
local shunt_direct_host_tmp = shunt_direct_host .. "_tmp"
local shunt_proxy_host = CACHE_FLAG_PATH .. "/shunt_proxy_host"
local shunt_black_host = CACHE_FLAG_PATH .. "/shunt_black_host"
local geosite_direct_arg, geosite_proxy_arg, geosite_black_arg = "", "", ""
local SHUNT_LIST = ""
local t = api.uci_get_c(NODE)
local default_node_id = t["default_node"] or "_direct"
api.uci_foreach_c("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 and t["shunt_group"] == s.group then
if _node_id == "_default" then
_node_id = default_node_id
end
@@ -402,9 +405,11 @@ if IS_SHUNT_NODE then
if line:find("geosite:") then
line = string.match(line, ":([^:]+)$")
if _node_id == "_direct" then
geosite_white_arg = geosite_white_arg .. (geosite_white_arg ~= "" and "," or "") .. line
geosite_direct_arg = geosite_direct_arg .. (geosite_direct_arg ~= "" and "," or "") .. line
elseif _node_id == "_blackhole" then
geosite_black_arg = geosite_black_arg .. (geosite_black_arg ~= "" and "," or "") .. line
else
geosite_shunt_arg = geosite_shunt_arg .. (geosite_shunt_arg ~= "" and "," or "") .. line
geosite_proxy_arg = geosite_proxy_arg .. (geosite_proxy_arg ~= "" and "," or "") .. line
end
else
if line:find("domain:") or line:find("full:") then
@@ -413,25 +418,26 @@ if IS_SHUNT_NODE then
line = api.get_std_domain(line)
if line ~= "" and not line:find("#") then
if _node_id == "_direct" then
insert_unique(white_domain, line, lookup_white_domain)
insert_unique(direct_domain, line, lookup_direct_domain)
elseif _node_id == "_blackhole" then
insert_unique(black_domain, line, lookup_black_domain)
else
insert_unique(shunt_domain, line, lookup_shunt_domain)
insert_unique(proxy_domain, line, lookup_proxy_domain)
end
end
end
end
end
SHUNT_LIST = SHUNT_LIST .. domain_list .. _node_id
SHUNT_LIST = SHUNT_LIST .. domain_list .. (_node_id:sub(1, 1) == "_" and "not-node" or "node")
if _node_id ~= "_direct" then
log(string.format(" - Sing-Box/Xray分流规则(%s):%s", s.remarks, DNS_TRUST or "默认"))
end
log(string.format(" - Sing-Box/Xray分流规则(%s):%s", s.remarks, DNS_TRUST or "默认"))
end
end)
local MD5_FILE = CACHE_FLAG_PATH .. "/md5.txt"
local cache_md5 = ""
local USE_CACHE = true
if fs.access(MD5_FILE) then
cache_md5 = fs.readfile(MD5_FILE)
end
@@ -440,86 +446,118 @@ if IS_SHUNT_NODE then
api.remove(CACHE_FLAG_PATH)
sys.call("mkdir -p %s" % CACHE_FLAG_PATH)
fs.writefile(MD5_FILE, new_md5)
USE_CACHE = false
end
if is_file_nonzero(file_white_host) == nil then
if #white_domain > 0 then
local f_out = io.open(file_white_host, "w")
for i = 1, #white_domain do
f_out:write(white_domain[i] .. "\n")
if not is_file_nonzero(shunt_direct_host_tmp) then
if #direct_domain > 0 then
local f_out = io.open(shunt_direct_host_tmp, "w")
for i = 1, #direct_domain do
f_out:write(direct_domain[i] .. "\n")
end
f_out:close()
end
end
if is_file_nonzero(file_shunt_host) == nil then
if #shunt_domain > 0 then
local f_out = io.open(file_shunt_host, "w")
for i = 1, #shunt_domain do
f_out:write(shunt_domain[i] .. "\n")
if not is_file_nonzero(shunt_proxy_host) then
if #proxy_domain > 0 then
local f_out = io.open(shunt_proxy_host, "w")
for i = 1, #proxy_domain do
f_out:write(proxy_domain[i] .. "\n")
end
f_out:close()
end
end
if GFWLIST == "1" and CHNLIST == "0" and USE_GEOVIEW == "1" then --仅GFW模式解析geosite
local return_white, return_shunt
if geosite_white_arg ~= "" then
return_white = get_geosite(geosite_white_arg, file_white_host)
if not is_file_nonzero(shunt_black_host) then
if #black_domain > 0 then
local f_out = io.open(shunt_black_host, "w")
for i = 1, #black_domain do
f_out:write(black_domain[i] .. "\n")
end
f_out:close()
end
if geosite_shunt_arg ~= "" then
return_shunt = get_geosite(geosite_shunt_arg, file_shunt_host)
end
if not USE_CACHE and USE_GEOVIEW == "1" then
local return_direct, return_proxy, return_black
if geosite_direct_arg ~= "" then
return_direct = get_geosite(geosite_direct_arg, shunt_direct_host_tmp)
end
if (return_white == nil or return_white == 0) and (return_shunt == nil or return_shunt == 0) then
if geosite_proxy_arg ~= "" then
return_proxy = get_geosite(geosite_proxy_arg, shunt_proxy_host)
end
if geosite_black_arg ~= "" then
return_black = get_geosite(geosite_black_arg, shunt_black_host)
end
if return_direct == 0 and return_proxy == 0 and return_black == 0 then
log(" - 解析[分流节点] Geosite 完成")
else
log(" - 解析[分流节点] Geosite 失败!")
end
end
local sets = {
setflag .. "psw_shunt",
setflag .. "psw_shunt6"
}
if FLAG ~= "default" then
sets = {
setflag .. "psw_" .. FLAG .. "_shunt",
setflag .. "psw_" .. FLAG .. "_shunt6"
}
end
if is_file_nonzero(file_white_host) then
if USE_DIRECT_LIST == "1" then
--当白名单启用时,添加到白名单组一同处理
for i, v in ipairs(config_lines) do
if v == "group-dnl " .. file_direct_host then
config_lines[i] = "group-dnl " .. file_direct_host .. "," .. file_white_host
break
-- 与 chnlist 比对
if is_file_nonzero(shunt_direct_host_tmp) and CHNLIST ~= "0" and is_file_nonzero(RULES_PATH .. "/chnlist") then
local chn_domain_set = {}
local f_chn = io.open(RULES_PATH .. "/chnlist", "r")
if f_chn then
for line in f_chn:lines() do
if line ~= "" then
chn_domain_set[line] = true
end
end
else
--当白名单不启用时,创建新组,ipset到shuntlist
tmp_lines = {
"group whitelist",
"group-dnl " .. file_white_host,
"group-upstream " .. DNS_LOCAL,
"group-ipset " .. table.concat(sets, ",")
}
insert_array_after(config_lines, tmp_lines, "#--4")
f_chn:close()
end
local f_in = io.open(shunt_direct_host_tmp, "r")
local f_out = io.open(shunt_direct_host, "w")
if f_in and f_out then
for line in f_in:lines() do
line = string.lower(line)
-- 排除 cn、.cn 等缺少有效域名标签的条目
local valid_domain = line ~= "" and line:find("%.") and line:sub(1,1) ~= "."
if valid_domain and not chn_domain_set[line] then
f_out:write(line .. "\n")
end
end
end
if f_in then f_in:close() end
if f_out then f_out:close() end
api.remove(shunt_direct_host_tmp)
elseif is_file_nonzero(shunt_direct_host_tmp) then
os.rename(shunt_direct_host_tmp, shunt_direct_host)
end
if is_file_nonzero(file_shunt_host) then
local shunt_file
if is_file_nonzero(shunt_black_host) then
shunt_file = shunt_black_host
end
if is_file_nonzero(shunt_direct_host) then
shunt_file = (shunt_file and shunt_file .. "," or "") .. shunt_direct_host
end
if is_file_nonzero(shunt_proxy_host) then
shunt_file = (shunt_file and shunt_file .. "," or "") .. shunt_proxy_host
end
if shunt_file then
local sets = {
setflag .. "psw_shunt",
setflag .. "psw_shunt6"
}
if FLAG ~= "default" then
sets = {
setflag .. "psw_" .. FLAG .. "_shunt",
setflag .. "psw_" .. FLAG .. "_shunt6"
}
end
tmp_lines = {
"group shuntlist",
"group-dnl " .. file_shunt_host,
"group-dnl " .. shunt_file,
"group-upstream " .. DNS_TRUST,
"group-ipset " .. table.concat(sets, ",")
}
if NO_IPV6_TRUST == "1" then table.insert(tmp_lines, "no-ipv6 tag:shuntlist") end
insert_array_after(config_lines, tmp_lines, "#--2")
end
end
--只使用gfwlist模式,GFW列表以外的域名及默认使用本地DNS
@@ -193,7 +193,7 @@ function add_rule(var)
local CACHE_TEXT_FILE = CACHE_DNS_PATH .. ".txt"
local USE_CHINADNS_NG = "0"
local IS_SHUNT_NODE = api.uci_get_c(NODE, "protocol") == "_shunt"
local USE_GEOVIEW = api.uci_get_c("@global_rules[0]", "enable_geoview") or "0"
local USE_GEOVIEW = api.uci_get_c("@global_rules[0]", "enable_geoview")
local list1 = {}
local excluded_domain = {}
@@ -351,13 +351,13 @@ function add_rule(var)
local t = api.uci_get_c(NODE)
api.uci_foreach_c("shunt_rules", function(s)
local _node_id = t[s[".name"]]
if _node_id and _node_id ~= "_blackhole" and t["shunt_group"] == s.group then
SHUNT_LIST = SHUNT_LIST .. (s.domain_list or "") .. _node_id
if _node_id and t["shunt_group"] == s.group then
SHUNT_LIST = SHUNT_LIST .. (s.domain_list or "") .. (_node_id:sub(1, 1) == "_" and "not-node" or "node")
end
end)
end
new_rules = new_rules .. api.md5_string(SHUNT_LIST)
return TMP_DNSMASQ_PATH .. DNSMASQ_CONF_FILE .. DEFAULT_DNS .. LOCAL_DNS .. TUN_DNS .. USE_DEFAULT_DNS .. CHINADNS_DNS .. USE_DIRECT_LIST .. USE_PROXY_LIST .. USE_BLOCK_LIST .. USE_GFW_LIST .. CHN_LIST .. DEFAULT_PROXY_MODE .. NO_PROXY_IPV6 .. address_md5 .. new_rules .. NFTFLAG .. USE_GEOVIEW
return TMP_DNSMASQ_PATH .. DNSMASQ_CONF_FILE .. DEFAULT_DNS .. LOCAL_DNS .. TUN_DNS .. USE_DEFAULT_DNS .. CHINADNS_DNS .. USE_DIRECT_LIST .. USE_PROXY_LIST .. USE_BLOCK_LIST .. USE_GFW_LIST .. CHN_LIST .. DEFAULT_PROXY_MODE .. NO_PROXY_IPV6 .. address_md5 .. new_rules .. NFTFLAG
end
local dnsmasq_default_dns
@@ -655,50 +655,27 @@ function add_rule(var)
end
--分流规则
if IS_SHUNT_NODE and USE_CHINADNS_NG == "0" then
if IS_SHUNT_NODE and USE_CHINADNS_NG == "0" and only_global ~= 1 then
local t = api.uci_get_c(NODE)
local default_node_id = t["default_node"] or "_direct"
api.uci_foreach_c("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 and t["shunt_group"] == s.group then
if _node_id == "_default" then
_node_id = default_node_id
end
fwd_dns = nil
no_ipv6 = nil
fwd_dns = TUN_DNS
local sets = {}
if _node_id == "_direct" then
fwd_dns = LOCAL_DNS
if USE_DIRECT_LIST == "1" then
table.insert(sets, setflag_4 .. "psw_white")
table.insert(sets, setflag_6 .. "psw_white6")
else
local set_name = "psw_shunt"
local set6_name = "psw_shunt6"
if FLAG ~= "default" then
set_name = "psw_" .. FLAG .. "_shunt"
set6_name = "psw_" .. FLAG .. "_shunt6"
end
table.insert(sets, setflag_4 .. set_name)
table.insert(sets, setflag_6 .. set6_name)
end
else
local set_name = "psw_shunt"
local set6_name = "psw_shunt6"
if FLAG ~= "default" then
set_name = "psw_" .. FLAG .. "_shunt"
set6_name = "psw_" .. FLAG .. "_shunt6"
end
fwd_dns = TUN_DNS
table.insert(sets, setflag_4 .. set_name)
if NO_PROXY_IPV6 ~= "1" then
table.insert(sets, setflag_6 .. set6_name)
else
no_ipv6 = true
end
local sets = {
setflag_4 .. "psw_shunt",
setflag_6 .. "psw_shunt6"
}
if FLAG ~= "default" then
sets = {
setflag_4 .. "psw_" .. FLAG .. "_shunt",
setflag_6 .. "psw_" .. FLAG .. "_shunt6"
}
end
local domain_list = s.domain_list or ""
@@ -714,10 +691,6 @@ function add_rule(var)
end
line = api.get_std_domain(line)
add_excluded_domain(line)
if no_ipv6 then
set_domain_address(line, "::")
end
set_domain_dns(line, fwd_dns)
set_domain_ipset(line, table.concat(sets, ","))
end
@@ -727,18 +700,13 @@ function add_rule(var)
if USE_GFW_LIST == "1" and CHN_LIST == "0" and USE_GEOVIEW == "1" and geosite_arg ~= "" then --仅GFW模式解析geosite
foreach_geosite(geosite_arg, function(line)
add_excluded_domain(line)
if no_ipv6 then
set_domain_address(line, "::")
end
set_domain_dns(line, fwd_dns)
set_domain_ipset(line, table.concat(sets, ","))
end)
log(string.format(" - 解析分流规则(%s) Geosite 完成", s.remarks))
end
if _node_id ~= "_direct" then
log(string.format(" - Sing-Box/Xray分流规则(%s):%s", s.remarks, fwd_dns or "默认"))
end
log(string.format(" - Sing-Box/Xray分流规则(%s):%s", s.remarks, fwd_dns or "默认"))
end
end)
elseif only_global == 1 and NO_PROXY_IPV6 == "1" then
@@ -186,7 +186,7 @@ if not REMOTE_GROUP or REMOTE_GROUP == "nil" then
end
local force_https_soa = api.uci_get_c("@global[0]", "force_https_soa") or 0
local proxy_server_name = "passwall-proxy-server"
local proxy_server_name = "psw-proxy-server"
config_lines = {
tonumber(LISTEN_PORT) ~= 0 and "bind [::]:" .. LISTEN_PORT .. "@lo" or "",
(tonumber(LOCAL_PORT) ~= 0 and LOCAL_GROUP) and "bind [::]:" .. LOCAL_PORT .. "@lo -group " .. LOCAL_GROUP or "",
@@ -268,7 +268,7 @@ if DEFAULT_DNS_GROUP then
local domain_rules_str = "domain-rules /./ -nameserver " .. DEFAULT_DNS_GROUP
if DEFAULT_DNS_GROUP == REMOTE_GROUP then
domain_rules_str = domain_rules_str .. " -speed-check-mode none -d no -no-serve-expired"
domain_rules_str = domain_rules_str .. " -address " .. (NO_PROXY_IPV6 == "1" and "#6" or "-6")
domain_rules_str = domain_rules_str .. " -address " .. ((only_global and IS_SHUNT_NODE) and "-6" or (NO_PROXY_IPV6 == "1" and "#6" or "-6"))
elseif DEFAULT_DNS_GROUP == LOCAL_GROUP then
domain_rules_str = domain_rules_str .. (LOCAL_EXTEND_ARG ~= "" and " " .. LOCAL_EXTEND_ARG or "")
end
@@ -279,7 +279,7 @@ local setflag = (NFTFLAG == "1") and "inet#passwall#" or ""
local set_type = (NFTFLAG == "1") and "-nftset" or "-ipset"
--预设排序标签(越往后优先级越高)
for i = 1, 8 do
for i = 1, 10 do
table.insert(config_lines, "#--" .. i)
end
@@ -319,12 +319,12 @@ if USE_BLOCK_LIST == "1" and not fs.access(file_block_host) then
end
end
if USE_BLOCK_LIST == "1" and is_file_nonzero(file_block_host) then
local domain_set_name = "passwall-block"
local domain_set_name = "psw-block"
tmp_lines = {
string.format("domain-set -name %s -file %s", domain_set_name, file_block_host),
string.format("domain-rules /domain-set:%s/ -a #", domain_set_name)
}
insert_array_after(config_lines, tmp_lines, "#--7")
insert_array_after(config_lines, tmp_lines, "#--8")
end
--始终用国内DNS解析节点域名
@@ -357,7 +357,7 @@ if not is_file_nonzero(file_vpslist) then
f_out:close()
end
if is_file_nonzero(file_vpslist) then
local domain_set_name = "passwall-vpslist"
local domain_set_name = "psw-vpslist"
tmp_lines = {
string.format("domain-set -name %s -file %s", domain_set_name, file_vpslist)
}
@@ -369,7 +369,7 @@ if is_file_nonzero(file_vpslist) then
domain_rules_str = domain_rules_str .. " " .. set_type .. " " .. table.concat(sets, ",")
domain_rules_str = domain_rules_str .. (LOCAL_EXTEND_ARG ~= "" and " " .. LOCAL_EXTEND_ARG or "")
table.insert(tmp_lines, domain_rules_str)
insert_array_after(config_lines, tmp_lines, "#--8")
insert_array_after(config_lines, tmp_lines, "#--9")
log(string.format(" - 节点列表中的域名(vpslist)使用分组:%s", LOCAL_GROUP or "默认"))
end
@@ -409,7 +409,7 @@ if USE_DIRECT_LIST == "1" and not fs.access(file_direct_host) then
end
end
if USE_DIRECT_LIST == "1" and is_file_nonzero(file_direct_host) then
local domain_set_name = "passwall-directlist"
local domain_set_name = "psw-directlist"
tmp_lines = {
string.format("domain-set -name %s -file %s", domain_set_name, file_direct_host)
}
@@ -421,7 +421,7 @@ if USE_DIRECT_LIST == "1" and is_file_nonzero(file_direct_host) then
domain_rules_str = domain_rules_str .. " " .. set_type .. " " .. table.concat(sets, ",")
domain_rules_str = domain_rules_str .. (LOCAL_EXTEND_ARG ~= "" and " " .. LOCAL_EXTEND_ARG or "")
table.insert(tmp_lines, domain_rules_str)
insert_array_after(config_lines, tmp_lines, "#--6")
insert_array_after(config_lines, tmp_lines, "#--7")
log(string.format(" - 域名白名单(whitelist)使用分组:%s", LOCAL_GROUP or "默认"))
end
@@ -461,7 +461,7 @@ if USE_PROXY_LIST == "1" and not fs.access(file_proxy_host) then
end
end
if USE_PROXY_LIST == "1" and is_file_nonzero(file_proxy_host) then
local domain_set_name = "passwall-proxylist"
local domain_set_name = "psw-proxylist"
tmp_lines = {
string.format("domain-set -name %s -file %s", domain_set_name, file_proxy_host)
}
@@ -478,13 +478,13 @@ if USE_PROXY_LIST == "1" and is_file_nonzero(file_proxy_host) then
domain_rules_str = domain_rules_str .. " -address -6 -d no " .. set_type .. " " .. table.concat(sets, ",")
end
table.insert(tmp_lines, domain_rules_str)
insert_array_after(config_lines, tmp_lines, "#--5")
insert_array_after(config_lines, tmp_lines, "#--6")
log(string.format(" - 代理域名表(blacklist)使用分组:%s", REMOTE_GROUP or "默认"))
end
--GFW列表
if USE_GFW_LIST == "1" and is_file_nonzero(RULES_PATH .. "/gfwlist") then
local domain_set_name = "passwall-gfwlist"
local domain_set_name = "psw-gfwlist"
tmp_lines = {
string.format("domain-set -name %s -file %s", domain_set_name, RULES_PATH .. "/gfwlist")
}
@@ -501,13 +501,13 @@ if USE_GFW_LIST == "1" and is_file_nonzero(RULES_PATH .. "/gfwlist") then
domain_rules_str = domain_rules_str .. " -address -6 -d no " .. set_type .. " " .. table.concat(sets, ",")
end
table.insert(tmp_lines, domain_rules_str)
insert_array_after(config_lines, tmp_lines, "#--1")
insert_array_after(config_lines, tmp_lines, "#--5")
log(string.format(" - 防火墙域名表(gfwlist)使用分组:%s", REMOTE_GROUP or "默认"))
end
--中国列表
if CHN_LIST ~= "0" and is_file_nonzero(RULES_PATH .. "/chnlist") then
local domain_set_name = "passwall-chnlist"
local domain_set_name = "psw-chnlist"
tmp_lines = {
string.format("domain-set -name %s -file %s", domain_set_name, RULES_PATH .. "/chnlist")
}
@@ -521,7 +521,7 @@ if CHN_LIST ~= "0" and is_file_nonzero(RULES_PATH .. "/chnlist") then
domain_rules_str = domain_rules_str .. " " .. set_type .. " " .. table.concat(sets, ",")
domain_rules_str = domain_rules_str .. (LOCAL_EXTEND_ARG ~= "" and " " .. LOCAL_EXTEND_ARG or "")
table.insert(tmp_lines, domain_rules_str)
insert_array_after(config_lines, tmp_lines, "#--2")
insert_array_after(config_lines, tmp_lines, "#--4")
log(string.format(" - 中国域名表(chnlist)使用分组:%s", LOCAL_GROUP or "默认"))
end
@@ -540,26 +540,28 @@ if CHN_LIST ~= "0" and is_file_nonzero(RULES_PATH .. "/chnlist") then
domain_rules_str = domain_rules_str .. " -address -6 -d no " .. set_type .. " " .. table.concat(sets, ",")
end
table.insert(tmp_lines, domain_rules_str)
insert_array_after(config_lines, tmp_lines, "#--2")
insert_array_after(config_lines, tmp_lines, "#--4")
log(string.format(" - 中国域名表(chnlist)使用分组:%s", REMOTE_GROUP or "默认"))
end
end
--分流规则
if IS_SHUNT_NODE then
local white_domain, lookup_white_domain = {}, {}
local shunt_domain, lookup_shunt_domain = {}, {}
if IS_SHUNT_NODE and not only_global then
local direct_domain, lookup_direct_domain = {}, {}
local proxy_domain, lookup_proxy_domain = {}, {}
local black_domain, lookup_black_domain = {}, {}
local CACHE_FLAG_PATH = CACHE_RULES_PATH .. "/" .. FLAG
local file_white_host = CACHE_FLAG_PATH .. "/shunt_direct_host"
local file_shunt_host = CACHE_FLAG_PATH .. "/shunt_proxy_host"
local geosite_white_arg, geosite_shunt_arg = "", ""
local shunt_direct_host = CACHE_FLAG_PATH .. "/shunt_direct_host"
local shunt_proxy_host = CACHE_FLAG_PATH .. "/shunt_proxy_host"
local shunt_black_host = CACHE_FLAG_PATH .. "/shunt_black_host"
local geosite_direct_arg, geosite_proxy_arg, geosite_black_arg = "", "", ""
local SHUNT_LIST = ""
local t = api.uci_get_c(NODE)
local default_node_id = t["default_node"] or "_direct"
api.uci_foreach_c("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 and t["shunt_group"] == s.group then
if _node_id == "_default" then
_node_id = default_node_id
end
@@ -570,9 +572,11 @@ if IS_SHUNT_NODE then
if line:find("geosite:") then
line = string.match(line, ":([^:]+)$")
if _node_id == "_direct" then
geosite_white_arg = geosite_white_arg .. (geosite_white_arg ~= "" and "," or "") .. line
geosite_direct_arg = geosite_direct_arg .. (geosite_direct_arg ~= "" and "," or "") .. line
elseif _node_id == "_blackhole" then
geosite_black_arg = geosite_black_arg .. (geosite_black_arg ~= "" and "," or "") .. line
else
geosite_shunt_arg = geosite_shunt_arg .. (geosite_shunt_arg ~= "" and "," or "") .. line
geosite_proxy_arg = geosite_proxy_arg .. (geosite_proxy_arg ~= "" and "," or "") .. line
end
else
if line:find("domain:") or line:find("full:") then
@@ -581,25 +585,26 @@ if IS_SHUNT_NODE then
line = api.get_std_domain(line)
if line ~= "" and not line:find("#") then
if _node_id == "_direct" then
insert_unique(white_domain, line, lookup_white_domain)
insert_unique(direct_domain, line, lookup_direct_domain)
elseif _node_id == "_blackhole" then
insert_unique(black_domain, line, lookup_black_domain)
else
insert_unique(shunt_domain, line, lookup_shunt_domain)
insert_unique(proxy_domain, line, lookup_proxy_domain)
end
end
end
end
end
SHUNT_LIST = SHUNT_LIST .. domain_list .. _node_id
SHUNT_LIST = SHUNT_LIST .. domain_list .. (_node_id:sub(1, 1) == "_" and "not-node" or "node")
if _node_id ~= "_direct" then
log(string.format(" - Sing-Box/Xray分流规则(%s)使用分组:%s", s.remarks, REMOTE_GROUP or "默认"))
end
log(string.format(" - Sing-Box/Xray分流规则(%s)使用分组:%s", s.remarks, REMOTE_GROUP or "默认"))
end
end)
local MD5_FILE = CACHE_FLAG_PATH .. "/md5.txt"
local cache_md5 = ""
local USE_CACHE = true
if fs.access(MD5_FILE) then
cache_md5 = fs.readfile(MD5_FILE)
end
@@ -608,88 +613,104 @@ if IS_SHUNT_NODE then
api.remove(CACHE_FLAG_PATH)
sys.call("mkdir -p %s" % CACHE_FLAG_PATH)
fs.writefile(MD5_FILE, new_md5)
USE_CACHE = false
end
if is_file_nonzero(file_white_host) == nil then
if #white_domain > 0 then
local f_out = io.open(file_white_host, "w")
for i = 1, #white_domain do
f_out:write(white_domain[i] .. "\n")
if not is_file_nonzero(shunt_direct_host) then
if #direct_domain > 0 then
local f_out = io.open(shunt_direct_host, "w")
for i = 1, #direct_domain do
f_out:write(direct_domain[i] .. "\n")
end
f_out:close()
end
end
if is_file_nonzero(file_shunt_host) == nil then
if #shunt_domain > 0 then
local f_out = io.open(file_shunt_host, "w")
for i = 1, #shunt_domain do
f_out:write(shunt_domain[i] .. "\n")
if not is_file_nonzero(shunt_proxy_host) then
if #proxy_domain > 0 then
local f_out = io.open(shunt_proxy_host, "w")
for i = 1, #proxy_domain do
f_out:write(proxy_domain[i] .. "\n")
end
f_out:close()
end
end
if USE_GFW_LIST == "1" and CHN_LIST == "0" and USE_GEOVIEW == "1" then --仅GFW模式解析geosite
local return_white, return_shunt
if geosite_white_arg ~= "" then
return_white = get_geosite(geosite_white_arg, file_white_host)
if not is_file_nonzero(shunt_black_host) then
if #black_domain > 0 then
local f_out = io.open(shunt_black_host, "w")
for i = 1, #black_domain do
f_out:write(black_domain[i] .. "\n")
end
f_out:close()
end
if geosite_shunt_arg ~= "" then
return_shunt = get_geosite(geosite_shunt_arg, file_shunt_host)
end
if not USE_CACHE and USE_GEOVIEW == "1" then
local return_direct, return_proxy, return_black
if geosite_direct_arg ~= "" then
return_direct = get_geosite(geosite_direct_arg, shunt_direct_host)
end
if (return_white == nil or return_white == 0) and (return_shunt == nil or return_shunt == 0) then
if geosite_proxy_arg ~= "" then
return_proxy = get_geosite(geosite_proxy_arg, shunt_proxy_host)
end
if geosite_black_arg ~= "" then
return_black = get_geosite(geosite_black_arg, shunt_black_host)
end
if return_direct == 0 and return_proxy == 0 and return_black == 0 then
log(" - 解析[分流节点] Geosite 完成")
else
log(" - 解析[分流节点] Geosite 失败!")
end
end
if is_file_nonzero(file_white_host) then
local domain_set_name = "passwall-whitehost"
if is_file_nonzero(shunt_direct_host) then
local domain_set_name = "psw-shunt-direct"
tmp_lines = {
string.format("domain-set -name %s -file %s", domain_set_name, file_white_host)
}
local domain_rules_str = string.format('domain-rules /domain-set:%s/ %s', domain_set_name, LOCAL_GROUP and "-nameserver " .. LOCAL_GROUP or "")
if USE_DIRECT_LIST == "1" then
local sets = {
"#4:" .. setflag .. "psw_white",
"#6:" .. setflag .. "psw_white6"
}
domain_rules_str = domain_rules_str .. " " .. set_type .. " " .. table.concat(sets, ",")
else
local sets = {
"#4:" .. setflag .. "psw_shunt",
"#6:" .. setflag .. "psw_shunt6"
}
domain_rules_str = domain_rules_str .. " " .. set_type .. " " .. table.concat(sets, ",")
end
domain_rules_str = domain_rules_str .. (LOCAL_EXTEND_ARG ~= "" and " " .. LOCAL_EXTEND_ARG or "")
table.insert(tmp_lines, domain_rules_str)
insert_array_after(config_lines, tmp_lines, "#--4")
end
if is_file_nonzero(file_shunt_host) then
local domain_set_name = "passwall-shuntlist"
tmp_lines = {
string.format("domain-set -name %s -file %s", domain_set_name, file_shunt_host)
string.format("domain-set -name %s -file %s", domain_set_name, shunt_direct_host)
}
local domain_rules_str = string.format('domain-rules /domain-set:%s/ -nameserver %s', domain_set_name, REMOTE_GROUP)
domain_rules_str = domain_rules_str .. " -speed-check-mode none"
domain_rules_str = domain_rules_str .. " -no-serve-expired"
domain_rules_str = domain_rules_str .. " -speed-check-mode none -no-serve-expired"
local sets = {
"#4:" .. setflag .. "psw_shunt"
"#4:" .. setflag .. "psw_shunt",
"#6:" .. setflag .. "psw_shunt6"
}
if NO_PROXY_IPV6 == "1" then
domain_rules_str = domain_rules_str .. " -address #6 " .. set_type .. " " .. table.concat(sets, ",")
else
table.insert(sets, "#6:" .. setflag .. "psw_shunt6")
domain_rules_str = domain_rules_str .. " -address -6 -d no " .. set_type .. " " .. table.concat(sets, ",")
end
domain_rules_str = domain_rules_str .. " -address -6 -d no " .. set_type .. " " .. table.concat(sets, ",")
table.insert(tmp_lines, domain_rules_str)
insert_array_after(config_lines, tmp_lines, "#--1")
end
if is_file_nonzero(shunt_proxy_host) then
local domain_set_name = "psw-shunt-proxy"
tmp_lines = {
string.format("domain-set -name %s -file %s", domain_set_name, shunt_proxy_host)
}
local domain_rules_str = string.format('domain-rules /domain-set:%s/ -nameserver %s', domain_set_name, REMOTE_GROUP)
domain_rules_str = domain_rules_str .. " -speed-check-mode none -no-serve-expired"
local sets = {
"#4:" .. setflag .. "psw_shunt",
"#6:" .. setflag .. "psw_shunt6"
}
domain_rules_str = domain_rules_str .. " -address -6 -d no " .. set_type .. " " .. table.concat(sets, ",")
table.insert(tmp_lines, domain_rules_str)
insert_array_after(config_lines, tmp_lines, "#--2")
end
if is_file_nonzero(shunt_black_host) then
local domain_set_name = "psw-shunt-black"
tmp_lines = {
string.format("domain-set -name %s -file %s", domain_set_name, shunt_black_host)
}
local domain_rules_str = string.format('domain-rules /domain-set:%s/ -nameserver %s', domain_set_name, REMOTE_GROUP)
domain_rules_str = domain_rules_str .. " -speed-check-mode none -no-serve-expired"
local sets = {
"#4:" .. setflag .. "psw_shunt",
"#6:" .. setflag .. "psw_shunt6"
}
domain_rules_str = domain_rules_str .. " -address -6 -d no " .. set_type .. " " .. table.concat(sets, ",")
table.insert(tmp_lines, domain_rules_str)
insert_array_after(config_lines, tmp_lines, "#--3")
end
end
if #config_lines > 0 then
+1 -1
View File
@@ -4,7 +4,7 @@ LUCI_TITLE:=luci-app-ssr-plus
LUCI_PKGARCH:=all
PKG_NAME:=luci-app-ssr-plus
PKG_VERSION:=196
PKG_RELEASE:=10
PKG_RELEASE:=11
PKG_CONFIG_DEPENDS:= \
CONFIG_PACKAGE_$(PKG_NAME)_Iptables_Transparent_Proxy \
+6 -20
View File
@@ -1,10 +1,9 @@
# SPDX-License-Identifier: GPL-3.0-only
#
# Copyright (C) 2021-2025 sirpdboy <herboy2008@gmail.com>
# Copyright (C) 2021-2022 sirpdboy <herboy2008@gmail.com>
#
# This is free software, licensed under the Apache License, Version 2.0 .
#
#
include $(TOPDIR)/rules.mk
@@ -26,12 +25,8 @@ ifeq ($(ARCH),x86_64)
LUCKY_ARCH:=x86_64
endif
ifeq ($(ARCH),arm)
ifeq ($(BOARD),bcm53xx)
LUCKY_ARCH:=armv6
else
LUCKY_ARCH:=armv7
endif
endif
ifeq ($(BOARD),bcm53xx)
LUCKY_ARCH:=armv6
ifeq ($(word 2,$(subst +,$(space),$(call qstrip,$(CONFIG_CPU_TYPE)))),)
@@ -50,42 +45,33 @@ PKG_LICENSE_FILES:=LICENSE
PKG_MAINTAINER:=GDY666 <gdy666@foxmail.com>
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)
PKG_HASH:=skip
PKG_HASH:=0216c9a833724875f4a004aa5fc5e6e1a2d9f92f99e933905f76ebf7876b413c
include $(INCLUDE_DIR)/package.mk
define Package/$(PKG_NAME)
SECTION:=net
CATEGORY:=Network
TITLE:=Lucky gdy
TITLE:=Lucky dynamic domain name ddns-go service, socat,frp
DEPENDS:=@(i386||x86_64||arm||aarch64||mipsel||mips)
URL:=https://github.com/gdy666/lucky
endef
define Package/$(PKG_NAME)/description
Main functions of Lucky: ipv4/ipv6 portforward,ddns,IOT wake on lan ,reverse proxy and more...
Main functions of Lucky: dynamic domain name ddns-go service, socat,reverse proxy ,wake on lan
endef
define Build/Prepare
[ ! -f $(PKG_BUILD_DIR)/$(PKG_NAME)_$(PKG_VERSION)_Linux_$(LUCKY_ARCH).tar.gz ] && wget https://github.com/gdy666/lucky/releases/download/v$(PKG_VERSION)/$(PKG_NAME)_$(PKG_VERSION)_Linux_$(LUCKY_ARCH).tar.gz -O $(PKG_BUILD_DIR)/$(PKG_NAME)_$(PKG_VERSION)_Linux_$(LUCKY_ARCH).tar.gz
tar -xzvf $(PKG_BUILD_DIR)/$(PKG_NAME)_$(PKG_VERSION)_Linux_$(LUCKY_ARCH).tar.gz -C $(PKG_BUILD_DIR) || exit 1
tar -xzvf $(PKG_BUILD_DIR)/$(PKG_NAME)_$(PKG_VERSION)_Linux_$(LUCKY_ARCH).tar.gz -C $(PKG_BUILD_DIR)
endef
define Package/$(PKG_NAME)/conffiles
/etc/config/lucky
/etc/lucky/*
endef
define Build/Compile
endef
define Package/$(PKG_NAME)/install
$(INSTALL_DIR) $(1)/usr/bin/
$(INSTALL_DIR) $(1)/etc/init.d/
$(INSTALL_DIR) $(1)/etc/config/
$(INSTALL_DIR) $(1)/usr/bin
$(INSTALL_BIN) $(PKG_BUILD_DIR)/lucky $(1)/usr/bin/lucky
$(INSTALL_BIN) $(CURDIR)/files/luckyarch.bin $(1)/usr/bin/luckyarch
$(INSTALL_BIN) ./files/lucky.init $(1)/etc/init.d/lucky
$(INSTALL_CONF) $(CURDIR)/files/lucky.config $(1)/etc/config/lucky
endef
$(eval $(call BuildPackage,$(PKG_NAME)))
-5
View File
@@ -1,5 +0,0 @@
config lucky 'lucky'
option logger '1'
option port '16601'
option configdir '/etc/lucky'
option enabled '0'
-81
View File
@@ -1,81 +0,0 @@
#!/bin/sh /etc/rc.common
#
# Copyright (C) 2021-2025 sirpdboy <herboy2008@gmail.com> https://github.com/sirpdboy/luci-app-lucky
# This file is part of lucky .
#
# This is free software, licensed under the Apache License, Version 2.0 .
START=99
STOP=15
USE_PROCD=1
CONF=lucky
PROG=/usr/bin/lucky
CONFDIR=/etc/lucky
get_config() {
config_get_bool enabled $1 enabled 0
config_get_bool logger $1 logger 1
config_get port $1 port 16601
config_get SafeURL $1 safe
config_get delay $1 delay 0
}
init_config(){
config_load "$CONF"
config_foreach get_config "$CONF"
}
init_confdir(){
[ -d $CONFDIR ] || mkdir -p $CONFDIR 2>/dev/null
}
LOG(){
echo "$1"
logger -t lucky -p warn "$1"
}
start_instance() {
enabled=$(uci -q get $CONF.$CONF.enabled ) || enabled="0"
logger=$(uci -q get $CONF.$CONF.logger ) || logger="1"
port=$(uci -q get $CONF.$CONF.port ) || port="16601"
SafeURL=$(uci -q get $CONF.$CONF.safe ) || SafeURL=" "
delay=$(uci -q get $CONF.$CONF.delay ) || delay="5"
SafeURL="${SafeURL##*( )}"
SafeURL="${SafeURL%%*( )}"
init_confdir
[ x$enabled = x1 ] || return 1
[ $(awk -F. '{print $1}' /proc/uptime) -lt "120" ] && sleep $delay
$(which lucky) -setconf -key AdminWebListenPort -value $port -cd $CONFDIR
if [ -z "$SafeURL" ] ; then
$(which lucky) -rCancelSafeURL
else
$(which lucky) -setconf -key SafeURL -value "$SafeURL" -cd $CONFDIR
fi
procd_open_instance
procd_set_param command $PROG
procd_append_param command -cd $CONFDIR
procd_set_param respawn
procd_set_param stderr 1
procd_close_instance
LOG "lucky is start."
}
start_service() {
pgrep -f $PROG | xargs kill -9 >/dev/null 2>&1
start_instance
}
stop_service() {
pgrep -f $PROG | xargs kill -9 >/dev/null 2>&1
LOG "lucky is stop."
}
service_triggers() {
procd_add_reload_trigger lucky
}
-14
View File
@@ -1,14 +0,0 @@
#!/bin/sh
cputype=$(uname -ms | tr ' ' '_' | tr '[A-Z]' '[a-z]')
[ -n "$(echo $cputype | grep -E "linux.*armv.*")" ] && cpucore="armv5"
[ -n "$(echo $cputype | grep -E "linux.*armv7.*")" ] && [ -n "$(cat /proc/cpuinfo | grep vfp)" ] && [ ! -d /jffs/clash ] && cpucore="armv7"
[ -n "$(echo $cputype | grep -E "linux.*aarch64.*|linux.*armv8.*")" ] && cpucore="arm64"
[ -n "$(echo $cputype | grep -E "linux.*86.*")" ] && cpucore="i386"
[ -n "$(echo $cputype | grep -E "linux.*86_64.*")" ] && cpucore="x86_64"
if [ -n "$(echo $cputype | grep -E "linux.*mips.*")" ];then
mipstype=$(echo -n I | hexdump -o 2>/dev/null | awk '{ print substr($2,6,1); exit}') #通过判断大小端判断mips或mipsle
[ "$mipstype" = "0" ] && cpucore="mips_softfloat" || cpucore="mipsle_softfloat"
fi
echo $cpucore