🦄 Sync 2024-07-18 09:36

This commit is contained in:
github-actions[bot] 2024-07-18 09:36:18 +08:00
parent df4115b8ee
commit d9bd8999b4
34 changed files with 8431 additions and 2172 deletions

View File

@ -6,7 +6,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
PKG_VERSION:=4.77-6
PKG_VERSION:=4.78-1
PKG_RELEASE:=
PKG_CONFIG_DEPENDS:= \

View File

@ -266,6 +266,20 @@ dns_shunt = s:taboption("DNS", ListValue, "dns_shunt", "DNS " .. translate("Shun
dns_shunt:value("dnsmasq", "Dnsmasq")
dns_shunt:value("chinadns-ng", "Dnsmasq + ChinaDNS-NG")
o = s:taboption("DNS", Value, "direct_dns", translate("Direct DNS"))
o.datatype = "or(ipaddr,ipaddrport)"
o.default = ""
o:value("", translate("Auto"))
o:value("223.5.5.5")
o:value("223.6.6.6")
o:value("114.114.114.114")
o:value("119.29.29.29")
o:value("180.76.76.76")
o:value("1.12.12.12")
o:value("120.53.53.53")
o:depends({dns_shunt = "dnsmasq"})
o:depends({dns_shunt = "chinadns-ng"})
o = s:taboption("DNS", Flag, "filter_proxy_ipv6", translate("Filter Proxy Host IPv6"), translate("Experimental feature."))
o.default = "0"

View File

@ -47,6 +47,7 @@ o:depends("balancing_enable", true)
o = s:option(Flag, "bind_local", translate("Haproxy Port") .. " " .. translate("Bind Local"), translate("When selected, it can only be accessed localhost."))
o.default = "0"
o:depends("balancing_enable", true)
---- Health Check Type
o = s:option(ListValue, "health_check_type", translate("Health Check Type"))

View File

@ -1167,8 +1167,7 @@ function gen_config(var)
elseif w:find("full:") == 1 then
table.insert(domain_table.domain, w:sub(1 + #"full:"))
elseif w:find("domain:") == 1 then
table.insert(domain_table.domain, w:sub(1 + #"domain:"))
table.insert(domain_table.domain_suffix, "." .. w:sub(1 + #"domain:"))
table.insert(domain_table.domain_suffix, w:sub(1 + #"domain:"))
else
table.insert(domain_table.domain_keyword, w)
end

View File

@ -32,7 +32,7 @@ unlock() {
done
}
boot() {
boot_func() {
local delay=$(uci -q get ${CONFIG}.@global_delay[0].start_delay || echo 1)
if [ "$delay" -gt 0 ]; then
$APP_FILE echolog "执行启动延时 $delay 秒后再启动!"
@ -42,6 +42,10 @@ boot() {
touch ${LOCK_FILE_DIR}/${CONFIG}_ready.lock
}
boot() {
boot_func >/dev/null 2>&1 &
}
start() {
set_lock
[ $? == 1 ] && $APP_FILE echolog "脚本已经在运行,不重复运行,退出." && exit 0

View File

@ -330,7 +330,7 @@ run_ipt2socks() {
run_singbox() {
local flag type node tcp_redir_port udp_redir_port socks_address socks_port socks_username socks_password http_address http_port http_username http_password
local dns_listen_port direct_dns_port direct_dns_udp_server remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_fakedns remote_dns_query_strategy dns_cache dns_socks_address dns_socks_port
local dns_listen_port direct_dns_port direct_dns_udp_server direct_dns_tcp_server remote_dns_protocol remote_dns_udp_server remote_dns_tcp_server remote_dns_doh remote_fakedns remote_dns_query_strategy dns_cache dns_socks_address dns_socks_port
local loglevel log_file config_file server_host server_port
local _extra_param=""
eval_set_val $@
@ -371,11 +371,16 @@ run_singbox() {
[ -n "$dns_listen_port" ] && _extra_param="${_extra_param} -dns_listen_port ${dns_listen_port}"
[ -n "$dns_cache" ] && _extra_param="${_extra_param} -dns_cache ${dns_cache}"
local local_dns=$(echo -n $(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n1) | tr " " ",")
[ -z "$direct_dns_udp_server" ] && direct_dns_udp_server=$(echo ${local_dns} | awk -F '#' '{print $1}')
[ -z "$direct_dns_port" ] && direct_dns_port=$(echo ${local_dns} | awk -F '#' '{print $2}')
[ -n "$direct_dns_udp_server" ] && direct_dns_port=$(echo ${direct_dns_udp_server} | awk -F '#' '{print $2}')
[ -n "$direct_dns_tcp_server" ] && direct_dns_port=$(echo ${direct_dns_tcp_server} | awk -F '#' '{print $2}')
[ -z "$direct_dns_udp_server" ] && [ -z "$direct_dns_tcp_server" ] && {
local local_dns=$(echo -n $(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n1) | tr " " ",")
direct_dns_udp_server=$(echo ${local_dns} | awk -F '#' '{print $1}')
direct_dns_port=$(echo ${local_dns} | awk -F '#' '{print $2}')
}
[ -z "$direct_dns_port" ] && direct_dns_port=53
[ -n "$direct_dns_udp_server" ] && _extra_param="${_extra_param} -direct_dns_udp_server ${direct_dns_udp_server}"
[ -n "$direct_dns_tcp_server" ] && _extra_param="${_extra_param} -direct_dns_tcp_server ${direct_dns_tcp_server}"
[ -n "$direct_dns_port" ] && _extra_param="${_extra_param} -direct_dns_port ${direct_dns_port}"
_extra_param="${_extra_param} -direct_dns_query_strategy UseIP"
@ -500,6 +505,26 @@ run_chinadns_ng() {
filter-qtype 65
EOF
# This function may be called multiple times, so add a condition here to avoid repeated execution.
[ ! -f "${TMP_PATH}/vpslist" ] && {
servers=$(uci show "${CONFIG}" | grep ".address=" | cut -d "'" -f 2 | grep -v "engage.cloudflareclient.com")
hosts_foreach "servers" host_from_url | grep '[a-zA-Z]$' | sort -u > "${TMP_PATH}/vpslist"
}
[ -s "${TMP_PATH}/vpslist" ] && {
local vpslist4_set="passwall_vpslist"
local vpslist6_set="passwall_vpslist6"
[ "$nftflag" = "1" ] && {
vpslist4_set="inet@fw4@${vpslist4_set}"
vpslist6_set="inet@fw4@${vpslist6_set}"
}
cat <<-EOF >> ${_CONF_FILE}
group vpslist
group-dnl ${TMP_PATH}/vpslist
group-upstream ${_dns_local}
group-ipset ${vpslist4_set},${vpslist6_set}
EOF
}
[ "${_use_direct_list}" = "1" ] && [ -s "${RULES_PATH}/direct_host" ] && {
local whitelist4_set="passwall_whitelist"
local whitelist6_set="passwall_whitelist6"
@ -879,18 +904,23 @@ run_redir() {
_args="${_args} remote_dns_query_strategy=${DNS_QUERY_STRATEGY}"
DNSMASQ_FILTER_PROXY_IPV6=0
[ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0"
resolve_dns_port=${dns_listen_port}
_args="${_args} dns_listen_port=${resolve_dns_port}"
local local_dns=$(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n1)
_args="${_args} direct_dns_udp_server=${local_dns}"
local v2ray_dns_mode=$(config_t_get global v2ray_dns_mode tcp)
_args="${_args} remote_dns_protocol=${v2ray_dns_mode}"
_args="${_args} dns_listen_port=${dns_listen_port}"
case "$v2ray_dns_mode" in
tcp)
_args="${_args} remote_dns_tcp_server=${REMOTE_DNS}"
resolve_dns_log="Sing-Box DNS(127.0.0.1#${dns_listen_port}) -> tcp://${REMOTE_DNS}"
resolve_dns_log="Sing-Box DNS(127.0.0.1#${resolve_dns_port}) -> tcp://${REMOTE_DNS}"
;;
doh)
remote_dns_doh=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query")
_args="${_args} remote_dns_doh=${remote_dns_doh}"
resolve_dns_log="Sing-Box DNS(127.0.0.1#${dns_listen_port}) -> ${remote_dns_doh}"
resolve_dns_log="Sing-Box DNS(127.0.0.1#${resolve_dns_port}) -> ${remote_dns_doh}"
;;
esac
local remote_fakedns=$(config_t_get global remote_fakedns 0)
@ -899,6 +929,7 @@ run_redir() {
_args="${_args} remote_fakedns=1"
resolve_dns_log="${resolve_dns_log} + FakeDNS"
}
dns_listen_port=$(expr $dns_listen_port + 1)
}
run_singbox flag=$_flag node=$node tcp_redir_port=$local_port config_file=$config_file log_file=$log_file ${_args}
;;
@ -930,16 +961,18 @@ run_redir() {
local _dns_client_ip=$(config_t_get global dns_client_ip)
[ -n "${_dns_client_ip}" ] && _args="${_args} dns_client_ip=${_dns_client_ip}"
[ "${DNS_CACHE}" == "0" ] && _args="${_args} dns_cache=0"
_args="${_args} dns_listen_port=${dns_listen_port}"
resolve_dns_port=${dns_listen_port}
_args="${_args} dns_listen_port=${resolve_dns_port}"
_args="${_args} remote_dns_tcp_server=${REMOTE_DNS}"
local v2ray_dns_mode=$(config_t_get global v2ray_dns_mode tcp)
if [ "$v2ray_dns_mode" = "tcp+doh" ]; then
remote_dns_doh=$(config_t_get global remote_dns_doh "https://1.1.1.1/dns-query")
_args="${_args} remote_dns_doh=${remote_dns_doh}"
resolve_dns_log="Xray DNS(127.0.0.1#${dns_listen_port}) -> (${remote_dns_doh})(A/AAAA) + tcp://${REMOTE_DNS}"
resolve_dns_log="Xray DNS(127.0.0.1#${resolve_dns_port}) -> (${remote_dns_doh})(A/AAAA) + tcp://${REMOTE_DNS}"
else
resolve_dns_log="Xray DNS(127.0.0.1#${dns_listen_port}) -> tcp://${REMOTE_DNS}"
resolve_dns_log="Xray DNS(127.0.0.1#${resolve_dns_port}) -> tcp://${REMOTE_DNS}"
fi
dns_listen_port=$(expr $dns_listen_port + 1)
}
run_xray flag=$_flag node=$node tcp_redir_port=$local_port config_file=$config_file log_file=$log_file ${_args}
;;
@ -1262,6 +1295,7 @@ start_dns() {
echolog "DNS域名解析"
TUN_DNS="127.0.0.1#${dns_listen_port}"
[ "${resolve_dns}" == "1" ] && TUN_DNS="127.0.0.1#${resolve_dns_port}"
case "$DNS_MODE" in
dns2socks)
@ -1368,6 +1402,8 @@ start_dns() {
if [ $(date -d "$chinadns_ng_now" +%s) -lt $(date -d "$chinadns_ng_min" +%s) ]; then
echolog " * 注意:当前 ChinaDNS-NG 版本为[ ${chinadns_ng_now//-/.} ],请更新到[ ${chinadns_ng_min//-/.} ]或以上版本,否则 DNS 有可能无法正常工作!"
fi
local china_ng_local_dns=$(echo -n $(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n2 | awk -v prefix="udp://" '{ for (i=1; i<=NF; i++) print prefix $i }') | tr " " ",")
[ "$FILTER_PROXY_IPV6" = "1" ] && DNSMASQ_FILTER_PROXY_IPV6=0
[ -z "${china_ng_listen_port}" ] && local china_ng_listen_port=$(expr $dns_listen_port + 1)
@ -1377,7 +1413,7 @@ start_dns() {
run_chinadns_ng \
_flag="default" \
_listen_port=${china_ng_listen_port} \
_dns_local=$(echo -n $(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n2) | tr " " ",") \
_dns_local=${china_ng_local_dns} \
_dns_trust=${china_ng_trust_dns} \
_no_ipv6_trust=${FILTER_PROXY_IPV6} \
_use_direct_list=${USE_DIRECT_LIST} \
@ -1387,7 +1423,7 @@ start_dns() {
_default_mode=${TCP_PROXY_MODE} \
_default_tag=$(config_t_get global chinadns_ng_default_tag smart)
echolog " - ChinaDNS-NG(${china_ng_listen})直连DNS$(echo -n $(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n2) | tr " " ",")可信DNS${china_ng_trust_dns}"
echolog " - ChinaDNS-NG(${china_ng_listen})直连DNS${china_ng_local_dns}可信DNS${china_ng_trust_dns}"
USE_DEFAULT_DNS="chinadns_ng"
}
@ -1547,11 +1583,12 @@ acl_app() {
[ "$filter_proxy_ipv6" = "1" ] && dnsmasq_filter_proxy_ipv6=0
chinadns_port=$(expr $chinadns_port + 1)
_china_ng_listen="127.0.0.1#${chinadns_port}"
_chinadns_local_dns=$(echo -n $(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n2 | awk -v prefix="udp://" '{ for (i=1; i<=NF; i++) print prefix $i }') | tr " " ",")
run_chinadns_ng \
_flag="$sid" \
_listen_port=${chinadns_port} \
_dns_local=$(echo -n $(echo "${LOCAL_DNS}" | sed "s/,/\n/g" | head -n2) | tr " " ",") \
_dns_local=${_chinadns_local_dns} \
_dns_trust=127.0.0.1#${_dns_port} \
_no_ipv6_trust=${filter_proxy_ipv6} \
_use_direct_list=${use_direct_list} \
@ -1699,7 +1736,7 @@ acl_app() {
[ -n "$redirect_dns_port" ] && echo "${redirect_dns_port}" > $TMP_ACL_PATH/$sid/var_redirect_dns_port
unset enabled sid remarks sources use_global_config tcp_node udp_node use_direct_list use_proxy_list use_block_list use_gfw_list chn_list tcp_proxy_mode udp_proxy_mode filter_proxy_ipv6 dns_mode remote_dns v2ray_dns_mode remote_dns_doh dns_client_ip
unset _ip _mac _iprange _ipset _ip_or_mac rule_list tcp_port udp_port config_file _extra_param
unset _china_ng_listen chinadns_ng_default_tag dnsmasq_filter_proxy_ipv6
unset _china_ng_listen _chinadns_local_dns chinadns_ng_default_tag dnsmasq_filter_proxy_ipv6
unset redirect_dns_port
done
unset socks_port redir_port dns_port dnsmasq_port chinadns_port
@ -1839,6 +1876,9 @@ DEFAULT_DNSMASQ_CFGID=$(uci show dhcp.@dnsmasq[0] | awk -F '.' '{print $2}' | a
DEFAULT_DNS=$(uci show dhcp.@dnsmasq[0] | grep "\.server=" | awk -F '=' '{print $2}' | sed "s/'//g" | tr ' ' '\n' | grep -v "\/" | head -2 | sed ':label;N;s/\n/,/;b label')
[ -z "${DEFAULT_DNS}" ] && [ "$(echo $ISP_DNS | tr ' ' '\n' | wc -l)" -le 2 ] && DEFAULT_DNS=$(echo -n $ISP_DNS | tr ' ' '\n' | head -2 | tr '\n' ',')
LOCAL_DNS="${DEFAULT_DNS:-119.29.29.29,223.5.5.5}"
DIRECT_DNS=$(config_t_get global direct_dns "auto")
#Automatic logic is already done by default
[ "${DIRECT_DNS}" != "auto" ] && LOCAL_DNS=$(echo ${DIRECT_DNS} | sed 's/:/#/g')
DNS_QUERY_STRATEGY="UseIP"
[ "$FILTER_PROXY_IPV6" = "1" ] && DNS_QUERY_STRATEGY="UseIPv4"

View File

@ -202,15 +202,20 @@ if not fs.access(CACHE_DNS_PATH) then
end
--始终用国内DNS解析节点域名
uci:foreach(appname, "nodes", function(t)
local address = t.address
if address == "engage.cloudflareclient.com" then return end
if datatypes.hostname(address) then
set_domain_dns(address, LOCAL_DNS)
set_domain_ipset(address, setflag_4 .. "passwall_vpslist," .. setflag_6 .. "passwall_vpslist6")
if true then
if USE_DEFAULT_DNS == "chinadns_ng" and CHINADNS_DNS ~= "0" then
else
uci:foreach(appname, "nodes", function(t)
local address = t.address
if address == "engage.cloudflareclient.com" then return end
if datatypes.hostname(address) then
set_domain_dns(address, LOCAL_DNS)
set_domain_ipset(address, setflag_4 .. "passwall_vpslist," .. setflag_6 .. "passwall_vpslist6")
end
end)
end
end)
log(string.format(" - 节点列表中的域名(vpslist)%s", LOCAL_DNS or "默认"))
log(string.format(" - 节点列表中的域名(vpslist)%s", LOCAL_DNS or "默认"))
end
local fwd_dns
local ipset_flag
@ -406,38 +411,40 @@ if not fs.access(CACHE_DNS_PATH) then
}
end
local address_out = io.open(CACHE_DNS_PATH .. "/000-address.conf", "a")
local server_out = io.open(CACHE_DNS_PATH .. "/001-server.conf", "a")
local ipset_out = io.open(CACHE_DNS_PATH .. "/ipset.conf", "a")
local set_name = "ipset"
if NFTFLAG == "1" then
set_name = "nftset"
if list1 and next(list1) then
local address_out = io.open(CACHE_DNS_PATH .. "/000-address.conf", "a")
local server_out = io.open(CACHE_DNS_PATH .. "/001-server.conf", "a")
local ipset_out = io.open(CACHE_DNS_PATH .. "/ipset.conf", "a")
local set_name = "ipset"
if NFTFLAG == "1" then
set_name = "nftset"
end
for key, value in pairs(list1) do
if value.address then
local domain = "." .. key
if key == "#" then
domain = key
end
address_out:write(string.format("address=/%s/%s\n", domain, value.address))
end
if value.dns and #value.dns > 0 then
for i, dns in ipairs(value.dns) do
server_out:write(string.format("server=/.%s/%s\n", key, dns))
end
end
if value.ipsets and #value.ipsets > 0 then
local ipsets_str = ""
for i, ipset in ipairs(value.ipsets) do
ipsets_str = ipsets_str .. ipset .. ","
end
ipsets_str = ipsets_str:sub(1, #ipsets_str - 1)
ipset_out:write(string.format("%s=/.%s/%s\n", set_name, key, ipsets_str))
end
end
address_out:close()
server_out:close()
ipset_out:close()
end
for key, value in pairs(list1) do
if value.address then
local domain = "." .. key
if key == "#" then
domain = key
end
address_out:write(string.format("address=/%s/%s\n", domain, value.address))
end
if value.dns and #value.dns > 0 then
for i, dns in ipairs(value.dns) do
server_out:write(string.format("server=/.%s/%s\n", key, dns))
end
end
if value.ipsets and #value.ipsets > 0 then
local ipsets_str = ""
for i, ipset in ipairs(value.ipsets) do
ipsets_str = ipsets_str .. ipset .. ","
end
ipsets_str = ipsets_str:sub(1, #ipsets_str - 1)
ipset_out:write(string.format("%s=/.%s/%s\n", set_name, key, ipsets_str))
end
end
address_out:close()
server_out:close()
ipset_out:close()
local f_out = io.open(CACHE_TEXT_FILE, "a")
f_out:write(new_text)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -325,6 +325,7 @@ apkmirror.com
apkmonk.com
apkplz.com
apkpure.com
apkpure.net
aplusvpn.com
app.box.com
app.cloudcone.com
@ -626,7 +627,6 @@ blog.tiney.com
blog.workflow.is
blog.xuite.net
blog.youthwant.com.tw
blog.youxu.info
blogblog.com
blogcatalog.com
blogcity.me
@ -938,6 +938,8 @@ changsa.net
channelnewsasia.com
chaoex.com
chapm25.com
chat.lmsys.org
chatgpt.com
chatnook.com
chaturbate.com
checkgfw.com
@ -1337,6 +1339,7 @@ deviantart.com
deviantart.net
devio.us
devpn.com
devv.ai
dfas.mil
dfn.org
dharamsalanet.com
@ -3168,6 +3171,7 @@ liangzhichuanmei.com
lianyue.net
liaowangxizang.net
liberal.org.hk
libertysculpturepark.com
libertytimes.com.tw
library.usc.cuhk.edu.hk
libredd.it
@ -3210,7 +3214,6 @@ livecoin.net
livedoor.jp
liveleak.com
livemint.com
livestation.com
livestream.com
livevideo.com
livingonline.us
@ -3218,7 +3221,6 @@ livingstream.com
liwangyang.com
lizhizhuangbi.com
lkcn.net
llss.me
lncn.org
load.to
lobsangwangyal.com
@ -4064,6 +4066,7 @@ pipii.tv
piposay.com
piraattilahti.org
piring.com
pixeldrain.com
pixelqi.com
pixiv.net
pixnet.net
@ -4216,6 +4219,7 @@ python.com.tw
pythonhackers.com
pytorch.org
qanote.com
qbittorrent.org
qgirl.com.tw
qhigh.com
qi-gong.me
@ -4250,9 +4254,9 @@ qxbbs.org
qz.com
r0.ru
r18.com
ra.gg
radicalparty.org
radiko.jp
radio-canada.ca
radio.garden
radioaustralia.net.au
radiohilight.net
@ -4862,6 +4866,7 @@ tahr.org.tw
taipei.gov.tw
taipeisociety.org
taipeitimes.com
taisounds.com
taiwan-sex.com
taiwanbible.com
taiwancon.com
@ -5832,6 +5837,7 @@ wqyd.org
wrchina.org
wretch.cc
writer.zoho.com
writesonic.com
wsj.com
wsj.net
wsjhk.com
@ -5897,6 +5903,7 @@ x-art.com
x-berry.com
x-wall.org
x.co
x.com
x.company
x1949x.com
x24hr.com
@ -6024,7 +6031,6 @@ yilubbs.com
yingsuoss.com
yinlei.org
yipub.com
yiyechat.com
yizhihongxing.com
yobit.net
yobt.com
@ -6072,13 +6078,13 @@ yuanming.net
yuanzhengtang.org
yulghun.com
yunchao.net
yuntipub.com
yuvutu.com
yvesgeleyn.com
ywpw.com
yx51.net
yyii.org
yyjlymb.xyz
yysub.net
yzzk.com
z-lib.org
zacebook.com

View File

@ -5,7 +5,7 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall2
PKG_VERSION:=1.29-1
PKG_VERSION:=1.30-1
PKG_RELEASE:=
PKG_CONFIG_DEPENDS:= \

View File

@ -2,24 +2,32 @@
module("luci.controller.passwall2", package.seeall)
local api = require "luci.passwall2.api"
local appname = api.appname
local ucic = luci.model.uci.cursor()
local appname = api.appname -- not available
local uci = luci.model.uci.cursor() -- in funtion index()
local http = require "luci.http"
local util = require "luci.util"
local i18n = require "luci.i18n"
function index()
appname = require "luci.passwall2.api".appname
if not nixio.fs.access("/etc/config/passwall2") then
if nixio.fs.access("/usr/share/passwall2/0_default_config") then
luci.sys.call('cp -f /usr/share/passwall2/0_default_config /etc/config/passwall2')
else return end
end
local appname = "passwall2" -- global definitions not available
local uci = luci.model.uci.cursor() -- in function index()
entry({"admin", "services", appname}).dependent = true
entry({"admin", "services", appname, "reset_config"}, call("reset_config")).leaf = true
entry({"admin", "services", appname, "show"}, call("show_menu")).leaf = true
entry({"admin", "services", appname, "hide"}, call("hide_menu")).leaf = true
if not nixio.fs.access("/etc/config/passwall2") then return end
if nixio.fs.access("/etc/config/passwall2_show") then
e = entry({"admin", "services", appname}, alias("admin", "services", appname, "settings"), _("PassWall 2"), -1)
e.dependent = true
e.acl_depends = { "luci-app-passwall2" }
local e
if uci:get(appname, "@global[0]", "hide_from_luci") ~= "1" then
e = entry({"admin", "services", appname}, alias("admin", "services", appname, "settings"), _("Pass Wall"), -1)
else
e = entry({"admin", "services", appname}, alias("admin", "services", appname, "settings"), nil, -1)
end
e.dependent = true
e.acl_depends = { "luci-app-passwall2" }
--[[ Client ]]
entry({"admin", "services", appname, "settings"}, cbi(appname .. "/client/global"), _("Basic Settings"), 1).dependent = true
entry({"admin", "services", appname, "node_list"}, cbi(appname .. "/client/node_list"), _("Node List"), 2).dependent = true
@ -88,14 +96,16 @@ function reset_config()
end
function show_menu()
luci.sys.call("touch /etc/config/passwall2_show")
uci:delete(appname, "@global[0]", "hide_from_luci")
uci:commit(appname)
luci.sys.call("rm -rf /tmp/luci-*")
luci.sys.call("/etc/init.d/rpcd restart >/dev/null")
luci.http.redirect(api.url())
end
function hide_menu()
luci.sys.call("rm -rf /etc/config/passwall2_show")
uci:set(appname, "@global[0]", "hide_from_luci","1")
uci:commit(appname)
luci.sys.call("rm -rf /tmp/luci-*")
luci.sys.call("/etc/init.d/rpcd restart >/dev/null")
luci.http.redirect(luci.dispatcher.build_url("admin", "status", "overview"))
@ -112,9 +122,9 @@ function socks_autoswitch_add_node()
local id = luci.http.formvalue("id")
local key = luci.http.formvalue("key")
if id and id ~= "" and key and key ~= "" then
local new_list = ucic:get(appname, id, "autoswitch_backup_node") or {}
local new_list = uci:get(appname, id, "autoswitch_backup_node") or {}
for i = #new_list, 1, -1 do
if (ucic:get(appname, new_list[i], "remarks") or ""):find(key) then
if (uci:get(appname, new_list[i], "remarks") or ""):find(key) then
table.remove(new_list, i)
end
end
@ -123,8 +133,8 @@ function socks_autoswitch_add_node()
table.insert(new_list, e.id)
end
end
ucic:set_list(appname, id, "autoswitch_backup_node", new_list)
ucic:commit(appname)
uci:set_list(appname, id, "autoswitch_backup_node", new_list)
uci:commit(appname)
end
luci.http.redirect(api.url("socks_config", id))
end
@ -133,14 +143,14 @@ function socks_autoswitch_remove_node()
local id = luci.http.formvalue("id")
local key = luci.http.formvalue("key")
if id and id ~= "" and key and key ~= "" then
local new_list = ucic:get(appname, id, "autoswitch_backup_node") or {}
local new_list = uci:get(appname, id, "autoswitch_backup_node") or {}
for i = #new_list, 1, -1 do
if (ucic:get(appname, new_list[i], "remarks") or ""):find(key) then
if (uci:get(appname, new_list[i], "remarks") or ""):find(key) then
table.remove(new_list, i)
end
end
ucic:set_list(appname, id, "autoswitch_backup_node", new_list)
ucic:commit(appname)
uci:set_list(appname, id, "autoswitch_backup_node", new_list)
uci:commit(appname)
end
luci.http.redirect(api.url("socks_config", id))
end
@ -208,7 +218,7 @@ function socks_status()
local id = luci.http.formvalue("id")
e.index = index
e.socks_status = luci.sys.call(string.format("/bin/busybox top -bn1 | grep -v -E 'grep|acl/|acl_' | grep '%s/bin/' | grep '%s' | grep 'SOCKS_' > /dev/null", appname, id)) == 0
local use_http = ucic:get(appname, id, "http_port") or 0
local use_http = uci:get(appname, id, "http_port") or 0
e.use_http = 0
if tonumber(use_http) > 0 then
e.use_http = 1
@ -279,8 +289,8 @@ function set_node()
local type = luci.http.formvalue("type")
local config = luci.http.formvalue("config")
local section = luci.http.formvalue("section")
ucic:set(appname, type, config, section)
ucic:commit(appname)
uci:set(appname, type, config, section)
uci:commit(appname)
luci.sys.call("/etc/init.d/passwall2 restart > /dev/null 2>&1 &")
luci.http.redirect(api.url("log"))
end
@ -288,76 +298,76 @@ end
function copy_node()
local section = luci.http.formvalue("section")
local uuid = api.gen_short_uuid()
ucic:section(appname, "nodes", uuid)
for k, v in pairs(ucic:get_all(appname, section)) do
uci:section(appname, "nodes", uuid)
for k, v in pairs(uci:get_all(appname, section)) do
local filter = k:find("%.")
if filter and filter == 1 then
else
xpcall(function()
ucic:set(appname, uuid, k, v)
uci:set(appname, uuid, k, v)
end,
function(e)
end)
end
end
ucic:delete(appname, uuid, "add_from")
ucic:set(appname, uuid, "add_mode", 1)
ucic:commit(appname)
uci:delete(appname, uuid, "add_from")
uci:set(appname, uuid, "add_mode", 1)
uci:commit(appname)
luci.http.redirect(api.url("node_config", uuid))
end
function clear_all_nodes()
ucic:set(appname, '@global[0]', "enabled", "0")
ucic:set(appname, '@global[0]', "node", "nil")
ucic:foreach(appname, "socks", function(t)
ucic:delete(appname, t[".name"])
ucic:set_list(appname, t[".name"], "autoswitch_backup_node", {})
uci:set(appname, '@global[0]', "enabled", "0")
uci:set(appname, '@global[0]', "node", "nil")
uci:foreach(appname, "socks", function(t)
uci:delete(appname, t[".name"])
uci:set_list(appname, t[".name"], "autoswitch_backup_node", {})
end)
ucic:foreach(appname, "haproxy_config", function(t)
ucic:delete(appname, t[".name"])
uci:foreach(appname, "haproxy_config", function(t)
uci:delete(appname, t[".name"])
end)
ucic:foreach(appname, "acl_rule", function(t)
ucic:set(appname, t[".name"], "node", "default")
uci:foreach(appname, "acl_rule", function(t)
uci:set(appname, t[".name"], "node", "default")
end)
ucic:foreach(appname, "nodes", function(node)
ucic:delete(appname, node['.name'])
uci:foreach(appname, "nodes", function(node)
uci:delete(appname, node['.name'])
end)
ucic:commit(appname)
uci:commit(appname)
luci.sys.call("/etc/init.d/" .. appname .. " stop")
end
function delete_select_nodes()
local ids = luci.http.formvalue("ids")
string.gsub(ids, '[^' .. "," .. ']+', function(w)
if (ucic:get(appname, "@global[0]", "node") or "nil") == w then
ucic:set(appname, '@global[0]', "node", "nil")
if (uci:get(appname, "@global[0]", "node") or "nil") == w then
uci:set(appname, '@global[0]', "node", "nil")
end
ucic:foreach(appname, "socks", function(t)
uci:foreach(appname, "socks", function(t)
if t["node"] == w then
ucic:delete(appname, t[".name"])
uci:delete(appname, t[".name"])
end
local auto_switch_node_list = ucic:get(appname, t[".name"], "autoswitch_backup_node") or {}
local auto_switch_node_list = uci:get(appname, t[".name"], "autoswitch_backup_node") or {}
for i = #auto_switch_node_list, 1, -1 do
if w == auto_switch_node_list[i] then
table.remove(auto_switch_node_list, i)
end
end
ucic:set_list(appname, t[".name"], "autoswitch_backup_node", auto_switch_node_list)
uci:set_list(appname, t[".name"], "autoswitch_backup_node", auto_switch_node_list)
end)
ucic:foreach(appname, "haproxy_config", function(t)
uci:foreach(appname, "haproxy_config", function(t)
if t["lbss"] == w then
ucic:delete(appname, t[".name"])
uci:delete(appname, t[".name"])
end
end)
ucic:foreach(appname, "acl_rule", function(t)
uci:foreach(appname, "acl_rule", function(t)
if t["node"] == w then
ucic:set(appname, t[".name"], "node", "default")
uci:set(appname, t[".name"], "node", "default")
end
end)
ucic:delete(appname, w)
uci:delete(appname, w)
end)
ucic:commit(appname)
uci:commit(appname)
luci.sys.call("/etc/init.d/" .. appname .. " restart > /dev/null 2>&1 &")
end

View File

@ -217,6 +217,7 @@ o:value("1.1.1.2", "1.1.1.2 (CloudFlare-Security)")
o:value("8.8.4.4", "8.8.4.4 (Google)")
o:value("8.8.8.8", "8.8.8.8 (Google)")
o:value("9.9.9.9", "9.9.9.9 (Quad9-Recommended)")
o:value("149.112.112.112", "149.112.112.112 (Quad9-Recommended)")
o:value("208.67.220.220", "208.67.220.220 (OpenDNS)")
o:value("208.67.222.222", "208.67.222.222 (OpenDNS)")
o:depends("remote_dns_protocol", "tcp")
@ -228,7 +229,8 @@ o:value("https://1.1.1.1/dns-query", "CloudFlare")
o:value("https://1.1.1.2/dns-query", "CloudFlare-Security")
o:value("https://8.8.4.4/dns-query", "Google 8844")
o:value("https://8.8.8.8/dns-query", "Google 8888")
o:value("https://9.9.9.9/dns-query", "Quad9-Recommended")
o:value("https://9.9.9.9/dns-query", "Quad9-Recommended 9.9.9.9")
o:value("https://149.112.112.112/dns-query", "Quad9-Recommended 149.112.112.112")
o:value("https://208.67.222.222/dns-query", "OpenDNS")
o:value("https://dns.adguard.com/dns-query,176.103.130.130", "AdGuard")
o:value("https://doh.libredns.gr/dns-query,116.202.176.26", "LibreDNS")

View File

@ -52,7 +52,7 @@ local doh_validate = function(self, value, t)
for i = 1, #val do
local v = val[i]
if v then
if not datatypes.ipmask4(v) then
if not datatypes.ipmask4(v) and not datatypes.ipmask6(v) then
flag = 1
end
end
@ -238,6 +238,10 @@ node_socks_port = s:taboption("Main", Value, "node_socks_port", translate("Node"
node_socks_port.default = 1070
node_socks_port.datatype = "port"
node_socks_bind_local = s:taboption("Main", Flag, "node_socks_bind_local", translate("Node") .. " Socks " .. translate("Bind Local"), translate("When selected, it can only be accessed localhost."))
node_socks_bind_local.default = "1"
node_socks_bind_local:depends({ node = "nil", ["!reverse"] = true })
s:tab("DNS", translate("DNS"))
o = s:taboption("DNS", ListValue, "remote_dns_protocol", translate("Remote DNS Protocol"))
@ -254,6 +258,7 @@ o:value("1.1.1.2", "1.1.1.2 (CloudFlare-Security)")
o:value("8.8.4.4", "8.8.4.4 (Google)")
o:value("8.8.8.8", "8.8.8.8 (Google)")
o:value("9.9.9.9", "9.9.9.9 (Quad9-Recommended)")
o:value("149.112.112.112", "149.112.112.112 (Quad9-Recommended)")
o:value("208.67.220.220", "208.67.220.220 (OpenDNS)")
o:value("208.67.222.222", "208.67.222.222 (OpenDNS)")
o:depends("remote_dns_protocol", "tcp")
@ -266,7 +271,8 @@ o:value("https://1.1.1.1/dns-query", "CloudFlare")
o:value("https://1.1.1.2/dns-query", "CloudFlare-Security")
o:value("https://8.8.4.4/dns-query", "Google 8844")
o:value("https://8.8.8.8/dns-query", "Google 8888")
o:value("https://9.9.9.9/dns-query", "Quad9-Recommended")
o:value("https://9.9.9.9/dns-query", "Quad9-Recommended 9.9.9.9")
o:value("https://149.112.112.112/dns-query", "Quad9-Recommended 149.112.112.112")
o:value("https://208.67.222.222/dns-query", "OpenDNS")
o:value("https://dns.adguard.com/dns-query,176.103.130.130", "AdGuard")
o:value("https://doh.libredns.gr/dns-query,116.202.176.26", "LibreDNS")

View File

@ -46,6 +46,9 @@ o = s:option(Value, "console_port", translate("Console Port"), translate(
o.default = "1188"
o:depends("balancing_enable", true)
o = s:option(Flag, "bind_local", translate("Haproxy Port") .. " " .. translate("Bind Local"), translate("When selected, it can only be accessed localhost."))
o.default = "0"
---- Health Check Type
o = s:option(ListValue, "health_check_type", translate("Health Check Type"))
o.default = "passwall_logic"

View File

@ -126,25 +126,48 @@ o = s:option(Flag, "auto_update", translate("Enable auto update subscribe"))
o.default = 0
o.rmempty = false
---- Week update rules
o = s:option(ListValue, "week_update", translate("Week update rules"))
---- Week Update
o = s:option(ListValue, "week_update", translate("Update Mode"))
o:value(8, translate("Loop Mode"))
o:value(7, translate("Every day"))
for e = 1, 6 do o:value(e, translate("Week") .. e) end
o:value(0, translate("Week") .. translate("day"))
o.default = 0
o:value(1, translate("Every Monday"))
o:value(2, translate("Every Tuesday"))
o:value(3, translate("Every Wednesday"))
o:value(4, translate("Every Thursday"))
o:value(5, translate("Every Friday"))
o:value(6, translate("Every Saturday"))
o:value(0, translate("Every Sunday"))
o.default = 7
o:depends("auto_update", true)
o.rmempty = true
---- Day update rules
o = s:option(ListValue, "time_update", translate("Day update rules"))
for e = 0, 23 do o:value(e, e .. translate("oclock")) end
---- Time Update
o = s:option(ListValue, "time_update", translate("Update Time(every day)"))
for t = 0, 23 do o:value(t, t .. ":00") end
o.default = 0
o:depends("auto_update", true)
o:depends("week_update", "0")
o:depends("week_update", "1")
o:depends("week_update", "2")
o:depends("week_update", "3")
o:depends("week_update", "4")
o:depends("week_update", "5")
o:depends("week_update", "6")
o:depends("week_update", "7")
o.rmempty = true
---- Interval Update
o = s:option(ListValue, "interval_update", translate("Update Interval(hour)"))
for t = 1, 24 do o:value(t, t .. " " .. translate("hour")) end
o.default = 2
o:depends("week_update", "8")
o.rmempty = true
o = s:option(Value, "user_agent", translate("User-Agent"))
o.default = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0"
o:value("curl")
o:value("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0")
o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0")
o:value("Passwall2/OpenWrt")
o.default = "sing-box/9.9.9"
o:value("curl", "Curl Default")
o:value("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0", "Edge for Linux")
o:value("Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36 Edg/122.0.0.0", "Edge for Windows")
o:value("Passwall2/OpenWrt", "PassWall2")
o:value("sing-box/9.9.9", "Xboard(V2board)")
return m

View File

@ -151,36 +151,29 @@ if has_xray then
o:value("1-3", "1-3")
o:value("1-5", "1-5")
o:depends("fragment", true)
o = s_xray:option(Value, "fragment_length", translate("Fragment Length"), translate("Fragmented packet length (byte)"))
o.default = "100-200"
o:depends("fragment", true)
o = s_xray:option(Value, "fragment_interval", translate("Fragment Interval"), translate("Fragmentation interval (ms)"))
o.default = "10-20"
o:depends("fragment", true)
o = s_xray:option(Flag, "sniffing", translate("Sniffing"), translate("When using the shunt, must be enabled, otherwise the shunt will invalid."))
o.default = 1
o.rmempty = false
o = s_xray:option(Flag, "sniffing_override_dest", translate("Override the connection destination address"), translate("Override the connection destination address with the sniffed domain."))
o.default = 0
o = s_xray:option(Flag, "route_only", translate("Sniffing Route Only"))
o.default = 0
o:depends("sniffing", true)
local domains_excluded = string.format("/usr/share/%s/domains_excluded", appname)
o = s_xray:option(TextValue, "no_sniffing_hosts", translate("No Sniffing Lists"), translate("Hosts added into No Sniffing Lists will not resolve again on server."))
o = s_xray:option(TextValue, "excluded_domains", translate("Excluded Domains"), translate("If the traffic sniffing result is in this list, the destination address will not be overridden."))
o.rows = 15
o.wrap = "off"
o.cfgvalue = function(self, section) return fs.readfile(domains_excluded) or "" end
o.write = function(self, section, value) fs.writefile(domains_excluded, value:gsub("\r\n", "\n")) end
o.remove = function(self, section)
local route_only_value = s_xray.fields["route_only"] and s_xray.fields["route_only"]:formvalue(section) or nil
if not route_only_value or route_only_value == "0" then
fs.writefile(domains_excluded, "")
end
end
o:depends({sniffing = true, route_only = false})
o:depends({sniffing_override_dest = true})
o = s_xray:option(Value, "buffer_size", translate("Buffer Size"), translate("Buffer size for every connection (kB)"))
o.datatype = "uinteger"

View File

@ -30,18 +30,40 @@ o.default = 0
o.rmempty = false
---- Week Update
o = s:option(ListValue, "week_update", translate("Week update rules"))
o = s:option(ListValue, "week_update", translate("Update Mode"))
o:value(8, translate("Loop Mode"))
o:value(7, translate("Every day"))
for e = 1, 6 do o:value(e, translate("Week") .. e) end
o:value(0, translate("Week") .. translate("day"))
o.default = 0
o:value(1, translate("Every Monday"))
o:value(2, translate("Every Tuesday"))
o:value(3, translate("Every Wednesday"))
o:value(4, translate("Every Thursday"))
o:value(5, translate("Every Friday"))
o:value(6, translate("Every Saturday"))
o:value(0, translate("Every Sunday"))
o.default = 7
o:depends("auto_update", true)
o.rmempty = true
---- Time Update
o = s:option(ListValue, "time_update", translate("Day update rules"))
for e = 0, 23 do o:value(e, e .. translate("oclock")) end
o = s:option(ListValue, "time_update", translate("Update Time(every day)"))
for t = 0, 23 do o:value(t, t .. ":00") end
o.default = 0
o:depends("auto_update", true)
o:depends("week_update", "0")
o:depends("week_update", "1")
o:depends("week_update", "2")
o:depends("week_update", "3")
o:depends("week_update", "4")
o:depends("week_update", "5")
o:depends("week_update", "6")
o:depends("week_update", "7")
o.rmempty = true
---- Interval Update
o = s:option(ListValue, "interval_update", translate("Update Interval(hour)"))
for t = 1, 24 do o:value(t, t .. " " .. translate("hour")) end
o.default = 2
o:depends("week_update", "8")
o.rmempty = true
s = m:section(TypedSection, "shunt_rules", "Sing-Box/Xray " .. translate("Shunt Rule"), "<a style='color: red'>" .. translate("Please note attention to the priority, the higher the order, the higher the priority.") .. "</a>")
s.template = "cbi/tblsection"

View File

@ -107,11 +107,13 @@ domain_list.rows = 10
domain_list.wrap = "off"
domain_list.validate = function(self, value)
local hosts= {}
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(hosts, w) end)
value = value:gsub("^%s+", ""):gsub("%s+$","\n"):gsub("\r\n","\n"):gsub("[ \t]*\n[ \t]*", "\n")
string.gsub(value, "[^\r\n]+", function(w) table.insert(hosts, w) end)
for index, host in ipairs(hosts) do
local flag = 1
local tmp_host = host
if host:find("regexp:") and host:find("regexp:") == 1 then
if not host:find("#") and host:find("%s") then
elseif host:find("regexp:") and host:find("regexp:") == 1 then
flag = 0
elseif host:find("domain:.") and host:find("domain:.") == 1 then
tmp_host = host:gsub("domain:", "")
@ -144,10 +146,11 @@ ip_list.rows = 10
ip_list.wrap = "off"
ip_list.validate = function(self, value)
local ipmasks= {}
string.gsub(value, '[^' .. "\r\n" .. ']+', function(w) table.insert(ipmasks, w) end)
value = value:gsub("^%s+", ""):gsub("%s+$","\n"):gsub("\r\n","\n"):gsub("[ \t]*\n[ \t]*", "\n")
string.gsub(value, "[^\r\n]+", function(w) table.insert(ipmasks, w) end)
for index, ipmask in ipairs(ipmasks) do
if ipmask:find("geoip:") and ipmask:find("geoip:") == 1 then
elseif ipmask:find("ext:") and ipmask:find("ext:") == 1 then
if ipmask:find("geoip:") and ipmask:find("geoip:") == 1 and not ipmask:find("%s") then
elseif ipmask:find("ext:") and ipmask:find("ext:") == 1 and not ipmask:find("%s") then
elseif ipmask:find("#") and ipmask:find("#") == 1 then
else
if not (datatypes.ipmask4(ipmask) or datatypes.ipmask6(ipmask)) then

View File

@ -42,6 +42,9 @@ if auto_switch_tip then
socks_node.description = auto_switch_tip
end
o = s:option(Flag, "bind_local", translate("Bind Local"), translate("When selected, it can only be accessed localhost."))
o.default = "0"
local n = 1
uci:foreach(appname, "socks", function(s)
if s[".name"] == section then

View File

@ -27,6 +27,7 @@ local header_type_list = {
"none", "srtp", "utp", "wechat-video", "dtls", "wireguard"
}
local xray_version = api.get_app_version("xray")
-- [[ Xray ]]
s.fields["type"]:value(type_name, "Xray")
@ -106,11 +107,13 @@ o:value("leastPing")
o.default = "leastPing"
-- Fallback Node
if api.compare_versions(api.get_app_version("xray"), ">=", "1.8.10") then
if api.compare_versions(xray_version, ">=", "1.8.10") then
local o = s:option(ListValue, option_name("fallback_node"), translate("Fallback Node"))
o:depends({ [option_name("balancingStrategy")] = "leastPing" })
o:value("",translate("Null"))
o.default = ""
if api.compare_versions(xray_version, ">=", "1.8.12") then
o:depends({ [option_name("protocol")] = "_balancing" })
else
o:depends({ [option_name("balancingStrategy")] = "leastPing" })
end
local function check_fallback_chain(fb)
for k, v in pairs(fallback_table) do
if v.fallback == fb then
@ -128,19 +131,34 @@ if api.compare_versions(api.get_app_version("xray"), ">=", "1.8.10") then
end
-- 探测地址
local o = s:option(Flag, option_name("useCustomProbeUrl"), translate("Use Custome Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL."))
o:depends({ [option_name("balancingStrategy")] = "leastPing" })
local ucpu = s:option(Flag, option_name("useCustomProbeUrl"), translate("Use Custome Probe URL"), translate("By default the built-in probe URL will be used, enable this option to use a custom probe URL."))
ucpu:depends({ [option_name("balancingStrategy")] = "leastPing" })
local o = s:option(Value, option_name("probeUrl"), translate("Probe URL"))
o:depends({ [option_name("useCustomProbeUrl")] = true })
o.default = "https://www.google.com/generate_204"
o.description = translate("The URL used to detect the connection status.")
local pu = s:option(Value, option_name("probeUrl"), translate("Probe URL"))
pu:depends({ [option_name("useCustomProbeUrl")] = true })
pu:value("https://cp.cloudflare.com/", "Cloudflare")
pu:value("https://www.gstatic.com/generate_204", "Gstatic")
pu:value("https://www.google.com/generate_204", "Google")
pu:value("https://www.youtube.com/generate_204", "YouTube")
pu:value("https://connect.rom.miui.com/generate_204", "MIUI (CN)")
pu:value("https://connectivitycheck.platform.hicloud.com/generate_204", "HiCloud (CN)")
pu.default = "https://www.google.com/generate_204"
pu.description = translate("The URL used to detect the connection status.")
-- 探测间隔
local o = s:option(Value, option_name("probeInterval"), translate("Probe Interval"))
o:depends({ [option_name("balancingStrategy")] = "leastPing" })
o.default = "1m"
o.description = translate("The interval between initiating probes. Every time this time elapses, a server status check is performed on a server. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively.")
local pi = s:option(Value, option_name("probeInterval"), translate("Probe Interval"))
pi:depends({ [option_name("balancingStrategy")] = "leastPing" })
pi.default = "1m"
pi.description = translate("The interval between initiating probes. Every time this time elapses, a server status check is performed on a server. The time format is numbers + units, such as '10s', '2h45m', and the supported time units are <code>ns</code>, <code>us</code>, <code>ms</code>, <code>s</code>, <code>m</code>, <code>h</code>, which correspond to nanoseconds, microseconds, milliseconds, seconds, minutes, and hours, respectively.")
if api.compare_versions(xray_version, ">=", "1.8.12") then
ucpu:depends({ [option_name("protocol")] = "_balancing" })
pi:depends({ [option_name("protocol")] = "_balancing" })
else
ucpu:depends({ [option_name("balancingStrategy")] = "leastPing" })
pi:depends({ [option_name("balancingStrategy")] = "leastPing" })
end
-- [[ 分流模块 ]]
if #nodes_table > 0 then
@ -323,7 +341,10 @@ o:depends({ [option_name("tls")] = true, [option_name("transport")] = "grpc" })
o = s:option(ListValue, option_name("alpn"), translate("alpn"))
o.default = "default"
o:value("default", translate("Default"))
o:value("h3,h2,http/1.1")
o:value("h3,h2")
o:value("h2,http/1.1")
o:value("h3")
o:value("h2")
o:value("http/1.1")
o:depends({ [option_name("tls")] = true, [option_name("reality")] = false })
@ -379,6 +400,7 @@ o:value("ds", "DomainSocket")
o:value("quic", "QUIC")
o:value("grpc", "gRPC")
o:value("httpupgrade", "HttpUpgrade")
o:value("splithttp", "SplitHTTP")
o:depends({ [option_name("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "socks" })
@ -401,7 +423,7 @@ o = s:option(Value, option_name("wireguard_mtu"), translate("MTU"))
o.default = "1420"
o:depends({ [option_name("protocol")] = "wireguard" })
if api.compare_versions(api.get_app_version("xray"), ">=", "1.8.0") then
if api.compare_versions(xray_version, ">=", "1.8.0") then
o = s:option(Value, option_name("wireguard_reserved"), translate("Reserved"), translate("Decimal numbers separated by \",\" or Base64-encoded strings."))
o:depends({ [option_name("protocol")] = "wireguard" })
end
@ -544,6 +566,14 @@ o = s:option(Value, option_name("httpupgrade_path"), translate("HttpUpgrade Path
o.placeholder = "/"
o:depends({ [option_name("transport")] = "httpupgrade" })
-- [[ SplitHTTP部分 ]]--
o = s:option(Value, option_name("splithttp_host"), translate("SplitHTTP Host"))
o:depends({ [option_name("transport")] = "splithttp" })
o = s:option(Value, option_name("splithttp_path"), translate("SplitHTTP Path"))
o.placeholder = "/"
o:depends({ [option_name("transport")] = "splithttp" })
-- [[ Mux ]]--
o = s:option(Flag, option_name("mux"), translate("Mux"))
o:depends({ [option_name("protocol")] = "vmess" })

View File

@ -154,7 +154,10 @@ o:depends({ [option_name("reality")] = true })
o = s:option(ListValue, option_name("alpn"), translate("alpn"))
o.default = "h2,http/1.1"
o:value("h3,h2,http/1.1")
o:value("h3,h2")
o:value("h2,http/1.1")
o:value("h3")
o:value("h2")
o:value("http/1.1")
o:depends({ [option_name("tls")] = true })
@ -165,7 +168,6 @@ o:depends({ [option_name("tls")] = true })
--o:depends({ [option_name("tls")] = true })
-- [[ TLS部分 ]] --
o = s:option(FileUpload, option_name("tls_certificateFile"), translate("Public key absolute path"), translate("as:") .. "/etc/ssl/fullchain.pem")
o.default = m:get(s.section, "tls_certificateFile") or "/etc/config/ssl/" .. arg[1] .. ".pem"
o:depends({ [option_name("tls")] = true, [option_name("reality")] = false })
@ -203,6 +205,7 @@ o:value("ds", "DomainSocket")
o:value("quic", "QUIC")
o:value("grpc", "gRPC")
o:value("httpupgrade", "HttpUpgrade")
o:value("splithttp", "SplitHTTP")
o:depends({ [option_name("protocol")] = "vmess" })
o:depends({ [option_name("protocol")] = "vless" })
o:depends({ [option_name("protocol")] = "socks" })
@ -210,7 +213,6 @@ o:depends({ [option_name("protocol")] = "shadowsocks" })
o:depends({ [option_name("protocol")] = "trojan" })
-- [[ WebSocket部分 ]]--
o = s:option(Value, option_name("ws_host"), translate("WebSocket Host"))
o:depends({ [option_name("transport")] = "ws" })
@ -226,13 +228,28 @@ o.placeholder = "/"
o:depends({ [option_name("transport")] = "httpupgrade" })
-- [[ HTTP/2部分 ]]--
o = s:option(Value, option_name("h2_host"), translate("HTTP/2 Host"))
o:depends({ [option_name("transport")] = "h2" })
o = s:option(Value, option_name("h2_path"), translate("HTTP/2 Path"))
o:depends({ [option_name("transport")] = "h2" })
-- [[ SplitHTTP部分 ]]--
o = s:option(Value, option_name("splithttp_host"), translate("SplitHTTP Host"))
o:depends({ [option_name("transport")] = "splithttp" })
o = s:option(Value, option_name("splithttp_path"), translate("SplitHTTP Path"))
o.placeholder = "/"
o:depends({ [option_name("transport")] = "splithttp" })
o = s:option(Value, option_name("splithttp_maxuploadsize"), translate("maxUploadSize"))
o.default = "1000000"
o:depends({ [option_name("transport")] = "splithttp" })
o = s:option(Value, option_name("splithttp_maxconcurrentuploads"), translate("maxConcurrentUploads"))
o.default = "10"
o:depends({ [option_name("transport")] = "splithttp" })
-- [[ TCP部分 ]]--
-- TCP伪装
@ -250,7 +267,6 @@ o = s:option(DynamicList, option_name("tcp_guise_http_path"), translate("HTTP Pa
o:depends({ [option_name("tcp_guise")] = "http" })
-- [[ mKCP部分 ]]--
o = s:option(ListValue, option_name("mkcp_guise"), translate("Camouflage Type"), translate('<br />none: default, no masquerade, data sent is packets with no characteristics.<br />srtp: disguised as an SRTP packet, it will be recognized as video call data (such as FaceTime).<br />utp: packets disguised as uTP will be recognized as bittorrent downloaded data.<br />wechat-video: packets disguised as WeChat video calls.<br />dtls: disguised as DTLS 1.2 packet.<br />wireguard: disguised as a WireGuard packet. (not really WireGuard protocol)'))
for a, t in ipairs(header_type_list) do o:value(t) end
o:depends({ [option_name("transport")] = "mkcp" })
@ -286,7 +302,6 @@ o = s:option(Value, option_name("mkcp_seed"), translate("KCP Seed"))
o:depends({ [option_name("transport")] = "mkcp" })
-- [[ DomainSocket部分 ]]--
o = s:option(Value, option_name("ds_path"), "Path", translate("A legal file path. This file must not exist before running."))
o:depends({ [option_name("transport")] = "ds" })
@ -334,7 +349,7 @@ o:depends({ [option_name("fallback")] = true })
o = s:option(DynamicList, option_name("fallback_list"), "Fallback", translate("dest,path"))
o:depends({ [option_name("fallback")] = true })
o = s:option(Flag, option_name("bind_local"), translate("Bind Local"), translate("When selected, it can only be accessed locally, It is recommended to turn on when using reverse proxies or be fallback."))
o = s:option(Flag, option_name("bind_local"), translate("Bind Local"), translate("When selected, it can only be accessed localhost."))
o.default = "0"
o = s:option(Flag, option_name("accept_lan"), translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!"))

View File

@ -365,7 +365,7 @@ o = s:option(Value, option_name("tcpbrutal_down_mbps"), translate("Max download
o.default = "50"
o:depends({ [option_name("tcpbrutal")] = true })
o = s:option(Flag, option_name("bind_local"), translate("Bind Local"), translate("When selected, it can only be accessed locally, It is recommended to turn on when using reverse proxies or be fallback."))
o = s:option(Flag, option_name("bind_local"), translate("Bind Local"), translate("When selected, it can only be accessed localhost."))
o.default = "0"
o = s:option(Flag, option_name("accept_lan"), translate("Accept LAN Access"), translate("When selected, it can accessed lan , this will not be safe!"))

View File

@ -202,6 +202,10 @@ function gen_outbound(flag, node, tag, proxy_table)
path = node.httpupgrade_path or "/",
host = node.httpupgrade_host
} or nil,
splithttpSettings = (node.transport == "splithttp") and {
path = node.splithttp_path or "/",
host = node.splithttp_host
} or nil,
} or nil,
settings = {
vnext = (node.protocol == "vmess" or node.protocol == "vless") and {
@ -477,6 +481,12 @@ function gen_config_server(node)
path = node.httpupgrade_path or "/",
host = node.httpupgrade_host
} or nil,
splithttpSettings = (node.transport == "splithttp") and {
path = node.splithttp_path or "/",
host = node.splithttp_host,
maxUploadSize = node.splithttp_maxuploadsize,
maxConcurrentUploads = node.splithttp_maxconcurrentuploads
} or nil,
sockopt = {
acceptProxyProtocol = (node.acceptProxyProtocol and node.acceptProxyProtocol == "1") and true or false
}
@ -623,11 +633,11 @@ function gen_config(var)
settings = {network = "tcp,udp", followRedirect = true},
streamSettings = {sockopt = {tproxy = "tproxy"}},
sniffing = {
enabled = xray_settings.sniffing == "1" and true or false,
enabled = xray_settings.sniffing_override_dest == "1" or node.protocol == "_shunt",
destOverride = {"http", "tls", "quic", (remote_dns_fake) and "fakedns"},
metadataOnly = false,
routeOnly = (xray_settings.sniffing == "1" and xray_settings.route_only == "1") and true or nil,
domainsExcluded = (xray_settings.sniffing == "1" and xray_settings.route_only == "0") and get_domain_excluded() or nil
routeOnly = node.protocol == "_shunt" and xray_settings.sniffing_override_dest ~= "1" or nil,
domainsExcluded = xray_settings.sniffing_override_dest == "1" and get_domain_excluded() or nil
}
}
local tcp_inbound = api.clone(inbound)
@ -682,9 +692,7 @@ function gen_config(var)
end
end
end
if fallback_node_id == "" then
fallback_node_id = nil
end
if fallback_node_id == "" then fallback_node_id = nil end
if fallback_node_id then
local is_new_node = true
for _, outbound in ipairs(outbounds) do
@ -720,7 +728,7 @@ function gen_config(var)
fallbackTag = fallback_node_id,
strategy = { type = _node.balancingStrategy or "random" }
})
if _node.balancingStrategy == "leastPing" then
if _node.balancingStrategy == "leastPing" or fallback_node_id then
if not observatory then
observatory = {
subjectSelector = { "blc-" },
@ -962,6 +970,7 @@ function gen_config(var)
if outboundTag and outboundTag ~= "nil" then
table.insert(dns_domain_rules, api.clone(domain_table))
end
if #domains == 0 then domains = nil end
end
local ip = nil
if e.ip_list then
@ -970,6 +979,7 @@ function gen_config(var)
if w:find("#") == 1 then return end
table.insert(ip, w)
end)
if #ip == 0 then ip = nil end
end
local source = nil
if e.source then

View File

@ -640,12 +640,6 @@ msgstr "劫持ICMPv6 (IPv6 PING)"
msgid "Sniffing"
msgstr "流量嗅探"
msgid "When using the shunt, must be enabled, otherwise the shunt will invalid."
msgstr "使用分流时,必须启用,否则分流将无效。"
msgid "Sniffing Route Only"
msgstr "流量嗅探只供路由使用"
msgid "TCP Proxy Way"
msgstr "TCP代理方式"
@ -775,23 +769,44 @@ msgstr "手动更新"
msgid "Enable auto update rules"
msgstr "开启自动更新规则"
msgid "Week update rules"
msgstr "更新时间星期"
msgid "Update Time(every day)"
msgstr "更新时间(每天)"
msgid "Day update rules"
msgstr "更新时间小时"
msgid "Update Interval(hour)"
msgstr "更新间隔(小时)"
msgid "Update Mode"
msgstr "更新模式"
msgid "Loop Mode"
msgstr "循环"
msgid "Every day"
msgstr "每天"
msgid "day"
msgstr "日"
msgid "Every Monday"
msgstr "每周一"
msgid "Week"
msgstr "周"
msgid "Every Tuesday"
msgstr ""
msgid "oclock"
msgstr "点"
msgid "Every Wednesday"
msgstr "每周三"
msgid "Every Thursday"
msgstr "每周四"
msgid "Every Friday"
msgstr "每周五"
msgid "Every Saturday"
msgstr "每周六"
msgid "Every Sunday"
msgstr "每周日"
msgid "hour"
msgstr "小时"
msgid "Location of V2ray/Xray asset"
msgstr "V2ray/Xray 资源文件目录"
@ -1243,8 +1258,8 @@ msgstr "接口"
msgid "Bind Local"
msgstr "本机监听"
msgid "When selected, it can only be accessed locally, It is recommended to turn on when using reverse proxies or be fallback."
msgstr "当勾选时,只能本机访问此端口,当想被反向代理或被回落时建议勾选此项。"
msgid "When selected, it can only be accessed localhost."
msgstr "当勾选时,只能本机访问。"
msgid "Accept LAN Access"
msgstr "接受局域网访问"
@ -1390,11 +1405,11 @@ msgstr "无子连接时的健康检查"
msgid "Initial Windows Size"
msgstr "初始窗口大小"
msgid "No Sniffing Lists"
msgstr "不进行流量嗅探的域名列表"
msgid "Excluded Domains"
msgstr "排除域名"
msgid "Hosts added into No Sniffing Lists will not resolve again on server."
msgstr "加入的域名不会再次在服务器解析。"
msgid "If the traffic sniffing result is in this list, the destination address will not be overridden."
msgstr "如果流量嗅探结果在此列表中,则不会覆盖目标地址。"
msgid "Buffer Size"
msgstr "缓冲区大小"

View File

@ -31,11 +31,17 @@ uci -q batch <<-EOF >/dev/null
commit uhttpd
EOF
touch /etc/config/passwall2_show >/dev/null 2>&1
[ ! -s "/etc/config/passwall2" ] && cp -f /usr/share/passwall2/0_default_config /etc/config/passwall2
chmod +x /usr/share/passwall2/*.sh
[ -e "/etc/config/passwall2_show" ] && rm -rf /etc/config/passwall2_show
[ "$(uci -q get passwall2.@global_xray[0].sniffing)" == "1" ] && [ "$(uci -q get passwall2.@global_xray[0].route_only)" != "1" ] && uci -q set passwall2.@global_xray[0].sniffing_override_dest=1
uci -q delete passwall2.@global_xray[0].sniffing
uci -q delete passwall2.@global_xray[0].route_only
uci -q commit passwall2
rm -f /tmp/luci-indexcache
rm -rf /tmp/luci-modulecache/
killall -HUP rpcd 2>/dev/null

View File

@ -36,8 +36,7 @@ config global_forwarding
option ipv6_tproxy '0'
config global_xray
option sniffing '1'
option route_only '0'
option sniffing_override_dest '0'
config global_other
option auto_detection_time 'tcping'

View File

@ -202,14 +202,15 @@ check_port_exists() {
}
check_depends() {
local depends
local tables=${1}
if [ "$tables" == "iptables" ]; then
for depends in "iptables-mod-tproxy" "iptables-mod-socket" "iptables-mod-iprange" "iptables-mod-conntrack-extra" "kmod-ipt-nat"; do
[ -z "$(opkg status ${depends} 2>/dev/null | grep 'Status' | awk -F ': ' '{print $2}' 2>/dev/null)" ] && echolog "$tables透明代理基础依赖 $depends 未安装..."
[ -s "/usr/lib/opkg/info/${depends}.control" ] || echolog "$tables透明代理基础依赖 $depends 未安装..."
done
else
for depends in "kmod-nft-socket" "kmod-nft-tproxy" "kmod-nft-nat"; do
[ -z "$(opkg status ${depends} 2>/dev/null | grep 'Status' | awk -F ': ' '{print $2}' 2>/dev/null)" ] && echolog "$tables透明代理基础依赖 $depends 未安装..."
[ -s "/usr/lib/opkg/info/${depends}.control" ] || echolog "$tables透明代理基础依赖 $depends 未安装..."
done
fi
}
@ -540,7 +541,7 @@ run_socks() {
[ "$http_port" != "0" ] && {
http_flag=1
config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g")
local _extra_param="-local_http_port $http_port"
local _extra_param="-local_http_address $bind -local_http_port $http_port"
}
[ -n "$relay_port" ] && _extra_param="${_extra_param} -server_host $server_host -server_port $port"
[ "${log_file}" != "/dev/null" ] && {
@ -548,17 +549,17 @@ run_socks() {
[ "$loglevel" = "warning" ] && loglevel="warn"
_extra_param="${_extra_param} -log 1 -loglevel $loglevel -logfile $log_file"
}
lua $UTIL_SINGBOX gen_config -flag SOCKS_$flag -node $node -local_socks_port $socks_port ${_extra_param} > $config_file
lua $UTIL_SINGBOX gen_config -flag SOCKS_$flag -node $node -local_socks_address $bind -local_socks_port $socks_port ${_extra_param} > $config_file
ln_run "$(first_type $(config_t_get global_app singbox_file) sing-box)" "sing-box" /dev/null run -c "$config_file"
;;
xray)
[ "$http_port" != "0" ] && {
http_flag=1
config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g")
local _extra_param="-local_http_port $http_port"
local _extra_param="-local_http_address $bind -local_http_port $http_port"
}
[ -n "$relay_port" ] && _extra_param="${_extra_param} -server_host $server_host -server_port $port"
lua $UTIL_XRAY gen_config -flag SOCKS_$flag -node $node -local_socks_port $socks_port ${_extra_param} > $config_file
lua $UTIL_XRAY gen_config -flag SOCKS_$flag -node $node -local_socks_address $bind -local_socks_port $socks_port ${_extra_param} > $config_file
ln_run "$(first_type $(config_t_get global_app xray_file) xray)" "xray" $log_file run -c "$config_file"
;;
naiveproxy)
@ -566,29 +567,29 @@ run_socks() {
ln_run "$(first_type naive)" naive $log_file "$config_file"
;;
ssr)
lua $UTIL_SS gen_config -node $node -local_addr "0.0.0.0" -local_port $socks_port -server_host $server_host -server_port $port > $config_file
lua $UTIL_SS gen_config -node $node -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $port > $config_file
ln_run "$(first_type ssr-local)" "ssr-local" $log_file -c "$config_file" -v -u
;;
ss)
lua $UTIL_SS gen_config -node $node -local_addr "0.0.0.0" -local_port $socks_port -server_host $server_host -server_port $port -mode tcp_and_udp > $config_file
lua $UTIL_SS gen_config -node $node -local_addr $bind -local_port $socks_port -server_host $server_host -server_port $port -mode tcp_and_udp > $config_file
ln_run "$(first_type ss-local)" "ss-local" $log_file -c "$config_file" -v
;;
ss-rust)
[ "$http_port" != "0" ] && {
http_flag=1
config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g")
local _extra_param="-local_http_port $http_port"
local _extra_param="-local_http_address $bind -local_http_port $http_port"
}
lua $UTIL_SS gen_config -node $node -local_socks_port $socks_port -server_host $server_host -server_port $port ${_extra_param} > $config_file
lua $UTIL_SS gen_config -node $node -local_socks_address $bind -local_socks_port $socks_port -server_host $server_host -server_port $port ${_extra_param} > $config_file
ln_run "$(first_type sslocal)" "sslocal" $log_file -c "$config_file" -v
;;
hysteria2)
[ "$http_port" != "0" ] && {
http_flag=1
config_file=$(echo $config_file | sed "s/SOCKS/HTTP_SOCKS/g")
local _extra_param="-local_http_port $http_port"
local _extra_param="-local_http_address $bind -local_http_port $http_port"
}
lua $UTIL_HYSTERIA2 gen_config -node $node -local_socks_port $socks_port -server_host $server_host -server_port $port ${_extra_param} > $config_file
lua $UTIL_HYSTERIA2 gen_config -node $node -local_socks_address $bind -local_socks_port $socks_port -server_host $server_host -server_port $port ${_extra_param} > $config_file
ln_run "$(first_type $(config_t_get global_app hysteria_file))" "hysteria" $log_file -c "$config_file" client
;;
tuic)
@ -627,6 +628,9 @@ socks_node_switch() {
cmd=$(cat ${TMP_SCRIPT_FUNC_PATH}/${filename})
[ -n "$(echo $cmd | grep "${flag}")" ] && rm -f ${TMP_SCRIPT_FUNC_PATH}/${filename}
done
local bind_local=$(config_n_get $flag bind_local 0)
local bind="0.0.0.0"
[ "$bind_local" = "1" ] && bind="127.0.0.1"
local port=$(config_n_get $flag port)
local config_file="SOCKS_${flag}.json"
local log_file="SOCKS_${flag}.log"
@ -635,7 +639,7 @@ socks_node_switch() {
local http_port=$(config_n_get $flag http_port 0)
local http_config_file="HTTP2SOCKS_${flag}.json"
LOG_FILE="/dev/null"
run_socks flag=$flag node=$new_node bind=0.0.0.0 socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file
run_socks flag=$flag node=$new_node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file
echo $new_node > $TMP_ID_PATH/socks_${flag}
}
}
@ -692,7 +696,10 @@ run_global() {
V2RAY_ARGS="${V2RAY_ARGS} log_file=${V2RAY_LOG} config_file=${V2RAY_CONFIG}"
node_socks_port=$(config_t_get global node_socks_port 1070)
V2RAY_ARGS="${V2RAY_ARGS} socks_port=${node_socks_port}"
node_socks_bind_local=$(config_t_get global node_socks_bind_local 1)
node_socks_bind="127.0.0.1"
[ "${node_socks_bind_local}" != "1" ] && node_socks_bind="0.0.0.0"
V2RAY_ARGS="${V2RAY_ARGS} socks_address=${node_socks_bind} socks_port=${node_socks_port}"
echo "127.0.0.1:$node_socks_port" > $TMP_ACL_PATH/default/SOCKS_server
node_http_port=$(config_t_get global node_http_port 0)
@ -722,6 +729,9 @@ start_socks() {
[ "$enabled" == "0" ] && continue
local node=$(config_n_get $id node nil)
[ "$node" == "nil" ] && continue
local bind_local=$(config_n_get $id bind_local 0)
local bind="0.0.0.0"
[ "$bind_local" = "1" ] && bind="127.0.0.1"
local port=$(config_n_get $id port)
local config_file="SOCKS_${id}.json"
local log_file="SOCKS_${id}.log"
@ -729,7 +739,7 @@ start_socks() {
[ "$log" == "0" ] && log_file=""
local http_port=$(config_n_get $id http_port 0)
local http_config_file="HTTP2SOCKS_${id}.json"
run_socks flag=$id node=$node bind=0.0.0.0 socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file
run_socks flag=$id node=$node bind=$bind socks_port=$port config_file=$config_file http_port=$http_port http_config_file=$http_config_file log_file=$log_file
echo $node > $TMP_ID_PATH/socks_${id}
#自动切换逻辑
@ -749,19 +759,36 @@ clean_log() {
}
clean_crontab() {
[ -f "/tmp/lock/${CONFIG}_cron.lock" ] && return
touch /etc/crontabs/root
#sed -i "/${CONFIG}/d" /etc/crontabs/root >/dev/null 2>&1
sed -i "/$(echo "/etc/init.d/${CONFIG}" | sed 's#\/#\\\/#g')/d" /etc/crontabs/root >/dev/null 2>&1
sed -i "/$(echo "lua ${APP_PATH}/rule_update.lua log" | sed 's#\/#\\\/#g')/d" /etc/crontabs/root >/dev/null 2>&1
sed -i "/$(echo "lua ${APP_PATH}/subscribe.lua start" | sed 's#\/#\\\/#g')/d" /etc/crontabs/root >/dev/null 2>&1
pgrep -af "${CONFIG}/" | awk '/tasks\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1
rm -rf /tmp/lock/${CONFIG}_tasks.lock
}
start_crontab() {
if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then
start_daemon=$(config_t_get global_delay start_daemon 0)
[ "$start_daemon" = "1" ] && $APP_PATH/monitor.sh > /dev/null 2>&1 &
fi
[ -f "/tmp/lock/${CONFIG}_cron.lock" ] && {
rm -rf "/tmp/lock/${CONFIG}_cron.lock"
echolog "当前为计划任务自动运行,不重新配置定时任务。"
return
}
clean_crontab
[ "$ENABLED" != 1 ] && {
/etc/init.d/cron restart
return
}
auto_on=$(config_t_get global_delay auto_on 0)
if [ "$auto_on" = "1" ]; then
time_off=$(config_t_get global_delay time_off)
@ -787,7 +814,11 @@ start_crontab() {
if [ "$autoupdate" = "1" ]; then
local t="0 $dayupdate * * $weekupdate"
[ "$weekupdate" = "7" ] && t="0 $dayupdate * * *"
echo "$t lua $APP_PATH/rule_update.lua log > /dev/null 2>&1 &" >>/etc/crontabs/root
if [ "$weekupdate" = "8" ]; then
update_loop=1
else
echo "$t lua $APP_PATH/rule_update.lua log all cron > /dev/null 2>&1 &" >>/etc/crontabs/root
fi
echolog "配置定时任务:自动更新规则。"
fi
@ -808,17 +839,23 @@ start_crontab() {
for name in $(ls ${TMP_SUB_PATH}); do
week_update=$(echo $name | awk -F '_' '{print $1}')
time_update=$(echo $name | awk -F '_' '{print $2}')
cfgids=$(echo -n $(cat ${TMP_SUB_PATH}/${name}) | sed 's# #,#g')
local t="0 $time_update * * $week_update"
[ "$week_update" = "7" ] && t="0 $time_update * * *"
cfgids=$(echo -n $(cat ${TMP_SUB_PATH}/${name}) | sed 's# #,#g')
echo "$t lua $APP_PATH/subscribe.lua start $cfgids > /dev/null 2>&1 &" >>/etc/crontabs/root
if [ "$week_update" = "8" ]; then
update_loop=1
else
echo "$t lua $APP_PATH/subscribe.lua start $cfgids cron > /dev/null 2>&1 &" >>/etc/crontabs/root
fi
done
rm -rf $TMP_SUB_PATH
}
if [ "$ENABLED_DEFAULT_ACL" == 1 ] || [ "$ENABLED_ACLS" == 1 ]; then
start_daemon=$(config_t_get global_delay start_daemon 0)
[ "$start_daemon" = "1" ] && $APP_PATH/monitor.sh > /dev/null 2>&1 &
[ "$update_loop" = "1" ] && {
$APP_PATH/tasks.sh > /dev/null 2>&1 &
echolog "自动更新:启动循环更新进程。"
}
else
echolog "运行于非代理模式,仅允许服务启停的定时任务。"
fi
@ -827,6 +864,7 @@ start_crontab() {
}
stop_crontab() {
[ -f "/tmp/lock/${CONFIG}_cron.lock" ] && return
clean_crontab
/etc/init.d/cron restart
#echolog "清除定时执行命令。"
@ -1075,7 +1113,7 @@ stop() {
delete_ip2route
kill_all v2ray-plugin obfs-local
pgrep -f "sleep.*(6s|9s|58s)" | xargs kill -9 >/dev/null 2>&1
pgrep -af "${CONFIG}/" | awk '! /app\.sh|subscribe\.lua|rule_update\.lua/{print $1}' | xargs kill -9 >/dev/null 2>&1
pgrep -af "${CONFIG}/" | awk '! /app\.sh|subscribe\.lua|rule_update\.lua|tasks\.sh/{print $1}' | xargs kill -9 >/dev/null 2>&1
unset V2RAY_LOCATION_ASSET
unset XRAY_LOCATION_ASSET
stop_crontab

View File

@ -35,6 +35,9 @@ 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)
@ -159,14 +162,14 @@ end
table.sort(sortTable, function(a,b) return (a < b) end)
for i, port in pairs(sortTable) do
log(" + 入口 0.0.0.0:%s..." % port)
log(" + 入口 %s:%s" % {bind_address, port})
f_out:write("\n" .. string.format([[
listen %s
bind 0.0.0.0:%s
bind %s:%s
mode tcp
balance roundrobin
]], port, port))
]], port, bind_address, port))
if health_check_type == "passwall_logic" then
f_out:write(string.format([[

View File

@ -724,7 +724,8 @@ add_firewall_rule() {
WAN_IP=$(get_wan_ip)
if [ -n "${WAN_IP}" ]; then
[ -n "${is_tproxy}" ] && nft "add rule inet fw4 PSW2_MANGLE ip daddr ${WAN_IP} counter return comment \"WAN_IP_RETURN\"" || nft "add rule inet fw4 PSW2_NAT ip daddr ${WAN_IP} counter return comment \"WAN_IP_RETURN\""
nft "add rule inet fw4 PSW2_MANGLE ip daddr ${WAN_IP} counter return comment \"WAN_IP_RETURN\""
[ -z "${is_tproxy}" ] && nft "add rule inet fw4 PSW2_NAT ip daddr ${WAN_IP} counter return comment \"WAN_IP_RETURN\""
fi
unset WAN_IP

View File

@ -8,6 +8,8 @@ local jsonc = require "luci.jsonc"
local name = 'passwall2'
local api = require "luci.passwall2.api"
local arg1 = arg[1]
local arg2 = arg[2]
local arg3 = arg[3]
local reboot = 0
local geoip_update = 0
@ -20,6 +22,10 @@ local geosite_api = ucic:get_first(name, 'global_rules', "geosite_url", "https:/
--
local use_nft = ucic:get(name, "@global_forwarding[0]", "use_nft") or "0"
if arg3 == "cron" then
arg2 = nil
end
local log = function(...)
if arg1 then
if arg1 == "log" then
@ -145,8 +151,8 @@ local function fetch_geosite()
return 0
end
if arg[2] then
string.gsub(arg[2], '[^' .. "," .. ']+', function(w)
if arg2 then
string.gsub(arg2, '[^' .. "," .. ']+', function(w)
if w == "geoip" then
geoip_update = 1
end
@ -184,6 +190,12 @@ ucic:save(name)
luci.sys.call("uci commit " .. name)
if reboot == 1 then
if arg3 == "cron" then
if not nixio.fs.access("/var/lock/" .. name .. ".lock") then
luci.sys.call("touch /tmp/lock/" .. name .. "_cron.lock")
end
end
log("重启服务,应用新的规则。")
if use_nft == "1" then
luci.sys.call("sh /usr/share/" .. name .. "/nftables.sh flush_nftset_reload > /dev/null 2>&1 &")

View File

@ -816,7 +816,7 @@ local function processData(szType, content, add_mode, add_from)
end
result.remarks = UrlDecode(alias)
local dat = split(content, '%?')
local dat = split(content:gsub("/%?", "?"), '%?')
local host_port = dat[1]
local params = {}
for _, v in pairs(split(dat[2], '&')) do
@ -1157,6 +1157,13 @@ local function update_node(manual)
uci:commit(appname)
end
if arg[3] == "cron" then
if not nixio.fs.access("/var/lock/" .. appname .. ".lock") then
luci.sys.call("touch /tmp/lock/" .. appname .. "_cron.lock")
end
end
luci.sys.call("/etc/init.d/" .. appname .. " restart > /dev/null 2>&1 &")
end

View File

@ -0,0 +1,75 @@
#!/bin/sh
## 循环更新脚本
CONFIG=passwall2
APP_PATH=/usr/share/$CONFIG
TMP_PATH=/tmp/etc/$CONFIG
LOCK_FILE=/tmp/lock/${CONFIG}_tasks.lock
CFG_UPDATE_INT=0
config_n_get() {
local ret=$(uci -q get "${CONFIG}.${1}.${2}" 2>/dev/null)
echo "${ret:=$3}"
}
config_t_get() {
local index=${4:-0}
local ret=$(uci -q get "${CONFIG}.@${1}[${index}].${2}" 2>/dev/null)
echo "${ret:=${3}}"
}
exec 99>"$LOCK_FILE"
flock -n 99
if [ "$?" != 0 ]; then
exit 0
fi
while true
do
if [ "$CFG_UPDATE_INT" -ne 0 ]; then
autoupdate=$(config_t_get global_rules auto_update)
weekupdate=$(config_t_get global_rules week_update)
hourupdate=$(config_t_get global_rules interval_update)
hourupdate=$(expr "$hourupdate" \* 60)
if [ "$autoupdate" = "1" ]; then
[ "$weekupdate" = "8" ] && {
[ "$(expr "$CFG_UPDATE_INT" % "$hourupdate")" -eq 0 ] && lua $APP_PATH/rule_update.lua log all cron > /dev/null 2>&1 &
}
fi
TMP_SUB_PATH=$TMP_PATH/sub_tasks
mkdir -p $TMP_SUB_PATH
for item in $(uci show ${CONFIG} | grep "=subscribe_list" | cut -d '.' -sf 2 | cut -d '=' -sf 1); do
if [ "$(config_n_get $item auto_update 0)" = "1" ]; then
cfgid=$(uci show ${CONFIG}.$item | head -n 1 | cut -d '.' -sf 2 | cut -d '=' -sf 1)
remark=$(config_n_get $item remark)
week_update=$(config_n_get $item week_update)
hour_update=$(config_n_get $item interval_update)
echo "$cfgid" >> $TMP_SUB_PATH/${week_update}_${hour_update}
fi
done
[ -d "${TMP_SUB_PATH}" ] && {
for name in $(ls ${TMP_SUB_PATH}); do
week_update=$(echo $name | awk -F '_' '{print $1}')
hour_update=$(echo $name | awk -F '_' '{print $2}')
hour_update=$(expr "$hour_update" \* 60)
cfgids=$(echo -n $(cat ${TMP_SUB_PATH}/${name}) | sed 's# #,#g')
[ "$week_update" = "8" ] && {
[ "$(expr "$CFG_UPDATE_INT" % "$hour_update")" -eq 0 ] && lua $APP_PATH/subscribe.lua start $cfgids cron > /dev/null 2>&1 &
}
done
rm -rf $TMP_SUB_PATH
}
fi
CFG_UPDATE_INT=$(expr "$CFG_UPDATE_INT" + 10)
sleep 600
done 2>/dev/null