luci-app-passwall: sync with upstream source

This commit is contained in:
CN_SZTL 2020-02-15 22:07:08 +08:00
parent fde41fea37
commit 80584900ee
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
11 changed files with 650 additions and 763 deletions

View File

@ -6,8 +6,8 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=luci-app-passwall
PKG_VERSION:=3.5.6
PKG_RELEASE:=20200213
PKG_VERSION:=3.5.8
PKG_RELEASE:=20200215
PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION)

View File

@ -9,7 +9,8 @@ local v2ray = require "luci.model.cbi.passwall.api.v2ray"
function index()
if not nixio.fs.access("/etc/config/passwall") then return end
entry({"admin", "vpn"}, firstchild(), "VPN", 45).dependent = false
entry({"admin", "vpn", "passwall", "reset_config"}, call("reset_config")).leaf = true
entry({"admin", "vpn", "passwall", "reset_config"}, call("reset_config")).leaf =
true
entry({"admin", "vpn", "passwall", "show"}, call("show_menu")).leaf = true
entry({"admin", "vpn", "passwall", "hide"}, call("hide_menu")).leaf = true
if nixio.fs.access("/etc/config/passwall") and
@ -81,7 +82,8 @@ local function http_write_json(content)
end
function reset_config()
luci.sys.call('[ -f "/usr/share/passwall/config.default" ] && cp -f /usr/share/passwall/config.default /etc/config/passwall && /etc/init.d/passwall reload')
luci.sys.call(
'[ -f "/usr/share/passwall/config.default" ] && cp -f /usr/share/passwall/config.default /etc/config/passwall && /etc/init.d/passwall reload')
luci.http.redirect(luci.dispatcher.build_url("admin", "vpn", "passwall"))
end
@ -99,7 +101,7 @@ function link_add_node()
local link = luci.http.formvalue("link")
luci.sys.call('rm -f /tmp/links.conf && echo "' .. link ..
'" >> /tmp/links.conf')
luci.sys.call("/usr/share/passwall/subscription.sh add >/dev/null")
luci.sys.call("lua /usr/share/passwall/subscribe.lua add >> /var/log/passwall.log")
end
function get_log()
@ -115,9 +117,9 @@ function status()
local e = {}
e.dns_mode_status = luci.sys.call("netstat -apn | grep 7913 >/dev/null") ==
0
e.haproxy_status = luci.sys.call(
"ps -w | grep -v grep | grep -i 'haproxy -f /var/etc/" ..
appname .. "/haproxy.cfg' >/dev/null") == 0
e.haproxy_status = luci.sys.call(string.format(
"ps -w | grep -v grep | grep '%s/bin/' | grep haproxy >/dev/null",
appname)) == 0
e.kcptun_status = luci.sys.call(
"ps -w | grep -v grep | grep -i 'log /var/etc/" ..
appname .. "/kcptun' >/dev/null") == 0
@ -132,7 +134,7 @@ function status()
i, i))
e["tcp_node%s_status" % i] = luci.sys.call(
string.format(
"ps -w | grep -v grep | grep -i -E '%s/TCP_%s|brook tproxy -l 0.0.0.0:%s|ipt2socks -T -l %s' >/dev/null",
"ps -w | grep -v grep | grep '%s/bin/' | grep -i -E 'TCP_%s|brook tproxy -l 0.0.0.0:%s|ipt2socks -T -l %s' >/dev/null",
appname, i, listen_port,
listen_port)) == 0
end
@ -147,7 +149,7 @@ function status()
i, i))
e["udp_node%s_status" % i] = luci.sys.call(
string.format(
"ps -w | grep -v grep | grep -i -E '%s/UDP_%s|brook tproxy -l 0.0.0.0:%s|ipt2socks -U -l %s' >/dev/null",
"ps -w | grep -v grep | grep '%s/bin/' | grep -i -E 'UDP_%s|brook tproxy -l 0.0.0.0:%s|ipt2socks -U -l %s' >/dev/null",
appname, i, listen_port,
listen_port)) == 0
end
@ -162,7 +164,7 @@ function status()
i, i))
e["socks5_node%s_status" % i] = luci.sys.call(
string.format(
"ps -w | grep -v grep | grep -i -E '%s/SOCKS5_%s|brook client -l 0.0.0.0:%s' >/dev/null",
"ps -w | grep -v grep | grep '%s/bin/' | grep -i -E 'SOCKS5_%s|brook client -l 0.0.0.0:%s' >/dev/null",
appname, i, listen_port)) == 0
end
luci.http.prepare_content("application/json")
@ -170,7 +172,9 @@ function status()
end
function connect_status()
local os = require "os"
local e = {}
local start_time = os.time()
if luci.http.formvalue("type") == "google" then
e.status = luci.sys.call(
"echo `/usr/share/passwall/test.sh test_url 'www.google.com'` | grep 200 >/dev/null") ==
@ -180,6 +184,8 @@ function connect_status()
"echo `/usr/share/passwall/test.sh test_url 'www.baidu.com'` | grep 200 >/dev/null") ==
0
end
local use_time = os.difftime(os.time(), start_time)
e.use_time = use_time
luci.http.prepare_content("application/json")
luci.http.write_json(e)
end

View File

@ -56,8 +56,10 @@ if node.v2ray_balancing_node then
users = {
{
id = api.uci_get_type_id(id, "v2ray_VMess_id"),
alterId = tonumber(api.uci_get_type_id(id, "v2ray_VMess_alterId")),
level = tonumber(api.uci_get_type_id(id, "v2ray_VMess_level")),
alterId = tonumber(api.uci_get_type_id(id,
"v2ray_VMess_alterId")),
level = tonumber(
api.uci_get_type_id(id, "v2ray_VMess_level")),
security = api.uci_get_type_id(id, "v2ray_security")
}
}
@ -106,6 +108,17 @@ local v2ray = {
allowInsecure = (node.tls_allowInsecure == "1") and true or
false
} or nil,
tcpSettings = (node.v2ray_transport == "tcp") and {
header = {
type = node.v2ray_tcp_guise,
request = {
path = node.v2ray_tcp_guise_http_path or {"/"},
headers = {
Host = node.v2ray_tcp_guise_http_host or {}
}
} or {}
}
} or nil,
kcpSettings = (node.v2ray_transport == "mkcp") and {
mtu = tonumber(node.v2ray_mkcp_mtu),
tti = tonumber(node.v2ray_mkcp_tti),
@ -118,7 +131,7 @@ local v2ray = {
header = {type = node.v2ray_mkcp_guise}
} or nil,
wsSettings = (node.v2ray_transport == "ws") and {
path = node.v2ray_ws_path,
path = node.v2ray_ws_path or "",
headers = (node.v2ray_ws_host ~= nil) and
{Host = node.v2ray_ws_host} or nil
} or nil,

View File

@ -62,8 +62,8 @@ o:depends("auto_update_subscribe", 1)
o = s:option(Button, "_update", translate("Manual subscription"))
o.inputstyle = "apply"
function o.write(e, e)
luci.sys
.call("nohup /usr/share/passwall/subscription.sh > /dev/null 2>&1 &")
luci.sys.call(
"lua /usr/share/passwall/subscribe.lua start >> /var/log/passwall.log 2>&1 &")
luci.http.redirect(luci.dispatcher.build_url("admin", "vpn", "passwall",
"log"))
end
@ -72,7 +72,8 @@ end
o = s:option(Button, "_stop", translate("Delete All Subscribe Node"))
o.inputstyle = "remove"
function o.write(e, e)
luci.sys.call("/usr/share/passwall/subscription.sh stop")
luci.sys.call(
"lua /usr/share/passwall/subscribe.lua truncate >> /var/log/passwall.log 2>&1 &")
luci.http.redirect(luci.dispatcher.build_url("admin", "vpn", "passwall",
"log"))
end

View File

@ -365,23 +365,23 @@ https://github.com/pure-css/pure/blob/master/LICENSE.md
},
function(x, rv) {
if (rv.status) {
var time = ((new Date()).getTime() - sendDate) / 1000;
var use_time = rv.use_time;
var speed = "";
if (time < 0.5) {
if (use_time < 1) {
s.className="green";
speed = "<%:very good%>";
} else if (time < 0.8) {
speed = "<%:Very Fast%>";
} else if (use_time < 2) {
s.className="green";
speed = "<%:good%>";
} else if (time < 1.5) {
speed = "<%:Fast%>";
} else if (use_time < 3) {
s.className="yellow";
speed = "<%:general%>";
} else if (time < 3) {
speed = "<%:General%>";
} else if (use_time < 4) {
s.className="red";
speed = "<%:bad%>";
} else if (time >= 3) {
speed = "<%:Slow%>";
} else if (use_time >= 4) {
s.className="red";
speed = "<%:very bad%>";
speed = "<%:Very Slow%>";
}
s.innerHTML = speed;
}

View File

@ -223,24 +223,24 @@ local status_show_ip111 = api.uci_get_type("global_other", "status_show_ip111",
var s = document.getElementById('_' + type + '_status');
if(s) {
if(rv.status) {
var time = ((new Date()).getTime() - sendDate) / 1000;
var use_time = rv.use_time;
var speed = "";
var color="red";
if (time < 0.5) {
if (use_time < 1) {
color = "green";
speed = "<%:very good%>";
} else if (time < 0.8) {
speed = "<%:Very Fast%>";
} else if (use_time < 2) {
color = "green";
speed = "<%:good%>";
} else if (time < 1.5) {
speed = "<%:Fast%>";
} else if (use_time < 3) {
color = "#b9b90b";
speed = "<%:general%>";
} else if (time < 3) {
speed = "<%:General%>";
} else if (use_time < 4) {
color = "red";
speed = "<%:bad%>";
} else if (time >= 3) {
speed = "<%:Slow%>";
} else if (use_time >= 4) {
color = "red";
speed = "<%:very bad%>";
speed = "<%:Very Slow%>";
}
//s.setAttribute("color", color);
btn.setAttribute("style","background-color: " + color + " !important; border-color: " + color + " !important;");

View File

@ -16,20 +16,20 @@ msgstr "连接正常"
msgid "Problem detected!"
msgstr "连接失败"
msgid "very good"
msgstr "非常"
msgid "Very Fast"
msgstr "非常"
msgid "good"
msgstr ""
msgid "Fast"
msgstr "很快"
msgid "general"
msgid "General"
msgstr "一般般"
msgid "bad"
msgstr ""
msgid "Slow"
msgstr "很慢"
msgid "very bad"
msgstr "非常"
msgid "Very Slow"
msgstr "非常"
msgid "Touch Check"
msgstr "点我检测"

View File

@ -6,6 +6,7 @@
CONFIG=passwall
CONFIG_PATH=/var/etc/$CONFIG
RUN_BIN_PATH=$CONFIG_PATH/bin
RUN_PID_PATH=$CONFIG_PATH/pid
RUN_ID_PATH=$CONFIG_PATH/id
RUN_IP_PATH=$CONFIG_PATH/ip
@ -41,7 +42,6 @@ find_bin() {
result=$(find /usr/*bin -iname "$bin_name" -type f)
if [ -z "$result" ]; then
echo ""
echolog "找不到$bin_name主程序,无法启动!"
else
echo "$result"
fi
@ -201,6 +201,7 @@ load_config() {
echolog "没有选择节点!"
return 1
}
DNS_MODE=$(config_t_get global dns_mode pdnsd)
DNS_FORWARD=$(config_t_get global dns_forward 8.8.4.4)
use_tcp_node_resolve_dns=$(config_t_get global use_tcp_node_resolve_dns 0)
@ -236,7 +237,38 @@ load_config() {
SOCKS5_PROXY_PORT2=$(expr $SOCKS5_PROXY_PORT1 + 1)
SOCKS5_PROXY_PORT3=$(expr $SOCKS5_PROXY_PORT2 + 1)
PROXY_IPV6=$(config_t_get global_forwarding proxy_ipv6 0)
mkdir -p /var/etc $CONFIG_PATH $RUN_PID_PATH $RUN_ID_PATH $RUN_IP_PATH $RUN_PORT_PATH
mkdir -p /var/etc $CONFIG_PATH $RUN_BIN_PATH $RUN_PID_PATH $RUN_ID_PATH $RUN_IP_PATH $RUN_PORT_PATH
#配置环境
ss_redir_bin=$(find_bin ss-redir)
[ -n "$ss_redir_bin" -a -f "$ss_redir_bin" ] && ln -s $ss_redir_bin ${RUN_BIN_PATH}/ss-redir && ss_redir_bin=${RUN_BIN_PATH}/ss-redir
ss_local_bin=$(find_bin ss-local)
[ -n "$ss_local_bin" -a -f "$ss_local_bin" ] && ln -s $ss_local_bin ${RUN_BIN_PATH}/ss-local && ss_local_bin=${RUN_BIN_PATH}/ss-local
ssr_redir_bin=$(find_bin ssr-redir)
[ -n "$ssr_redir_bin" -a -f "$ssr_redir_bin" ] && ln -s $ssr_redir_bin ${RUN_BIN_PATH}/ssr-redir && ssr_redir_bin=${RUN_BIN_PATH}/ssr-redir
ssr_local_bin=$(find_bin ssr-local)
[ -n "$ssr_local_bin" -a -f "$ssr_local_bin" ] && ln -s $ssr_local_bin ${RUN_BIN_PATH}/ssr-local && ssr_local_bin=${RUN_BIN_PATH}/ssr-local
trojan_bin=$(find_bin trojan)
[ -n "$trojan_bin" -a -f "$trojan_bin" ] && ln -s $trojan_bin ${RUN_BIN_PATH}/trojan && trojan_bin=${RUN_BIN_PATH}/trojan
v2ray_path=$(config_t_get global_app v2ray_file $(find_bin v2ray))
[ -n "$v2ray_path" -a -f "${v2ray_path}/v2ray" ]&& ln -s ${v2ray_path}/v2ray ${RUN_BIN_PATH}/v2ray && v2ray_bin=${RUN_BIN_PATH}/v2ray
brook_bin=$(config_t_get global_app brook_file $(find_bin brook))
[ -n "$brook_bin" -a -f "$brook_bin" ] && ln -s $brook_bin ${RUN_BIN_PATH}/brook && brook_bin=${RUN_BIN_PATH}/brook
kcptun_bin=$(config_t_get global_app kcptun_client_file $(find_bin kcptun-client))
[ -n "$kcptun_bin" -a -f "$kcptun_bin" ] && ln -s $kcptun_bin ${RUN_BIN_PATH}/kcptun-client && kcptun_bin=${RUN_BIN_PATH}/kcptun-client
redsocks2_bin=$(find_bin redsocks2)
[ -n "$redsocks2_bin" -a -f "$redsocks2_bin" ] && ln -s $redsocks2_bin ${RUN_BIN_PATH}/redsocks2 && redsocks2_bin=${RUN_BIN_PATH}/redsocks2
ipt2socks_bin=$(find_bin ipt2socks)
[ -n "$ipt2socks_bin" -a -f "$ipt2socks_bin" ] && ln -s $ipt2socks_bin ${RUN_BIN_PATH}/ipt2socks && ipt2socks_bin=${RUN_BIN_PATH}/ipt2socks
dns2socks_bin=$(find_bin dns2socks)
[ -n "$dns2socks_bin" -a -f "$dns2socks_bin" ] && ln -s $dns2socks_bin ${RUN_BIN_PATH}/dns2socks && dns2socks_bin=${RUN_BIN_PATH}/dns2socks
pdnsd_bin=$(find_bin pdnsd)
[ -n "$pdnsd_bin" -a -f "$pdnsd_bin" ] && ln -s $pdnsd_bin ${RUN_BIN_PATH}/pdnsd && pdnsd_bin=${RUN_BIN_PATH}/pdnsd
chinadns_ng_bin=$(find_bin chinadns-ng)
[ -n "$chinadns_ng_bin" -a -f "$chinadns_ng_bin" ] && ln -s $chinadns_ng_bin ${RUN_BIN_PATH}/chinadns-ng && chinadns_ng_bin=${RUN_BIN_PATH}/chinadns-ng
haproxy_bin=$(find_bin haproxy)
[ -n "$haproxy_bin" -a -f "$haproxy_bin" ] && ln -s $haproxy_bin ${RUN_BIN_PATH}/haproxy && haproxy_bin=${RUN_BIN_PATH}/haproxy
config_load $CONFIG
return 0
}
@ -259,23 +291,23 @@ gen_ss_ssr_config_file() {
}
cat <<-EOF >$configfile
{
"_comment": "$server_ip",
"server": "$server_host",
"server_port": $port,
"local_address": "0.0.0.0",
"local_port": $local_port,
"password": "$(config_n_get $node password)",
"timeout": $(config_n_get $node timeout),
"method": "$encrypt_method",
"fast_open": $(config_n_get $node tcp_fast_open false),
"reuse_port": true,
"_comment": "$server_ip",
"server": "$server_host",
"server_port": $port,
"local_address": "0.0.0.0",
"local_port": $local_port,
"password": "$(config_n_get $node password)",
"timeout": $(config_n_get $node timeout),
"method": "$encrypt_method",
"fast_open": $(config_n_get $node tcp_fast_open false),
"reuse_port": true,
EOF
[ "$1" == "ssr" ] && {
cat <<-EOF >>$configfile
"protocol": "$(config_n_get $node protocol)",
"protocol_param": "$(config_n_get $node protocol_param)",
"obfs": "$(config_n_get $node obfs)",
"obfs_param": "$(config_n_get $node obfs_param)"
"protocol": "$(config_n_get $node protocol)",
"protocol_param": "$(config_n_get $node protocol_param)",
"obfs": "$(config_n_get $node obfs)",
"obfs_param": "$(config_n_get $node obfs_param)"
EOF
}
echo -e "}" >>$configfile
@ -310,9 +342,8 @@ gen_start_config() {
echolog "Socks5节点不能使用Socks5代理节点"
elif [ "$type" == "v2ray" ]; then
lua $API_GEN_V2RAY $node nil nil $local_port >$config_file
v2ray_path=$(config_t_get global_app v2ray_file $(find_bin v2ray))
if [ -f "${v2ray_path}/v2ray" ]; then
${v2ray_path}/v2ray -config=$config_file >/dev/null &
if [ -f "$v2ray_bin" ]; then
$v2ray_bin -config=$config_file >/dev/null &
else
echolog "找不到V2ray客户端主程序无法启用"
fi
@ -332,19 +363,16 @@ gen_start_config() {
balancing_node_address="$temp"
done
lua $API_GEN_V2RAY $node nil nil $local_port >$config_file
v2ray_path=$(config_t_get global_app v2ray_file $(find_bin v2ray))
if [ -f "${v2ray_path}/v2ray" ]; then
${v2ray_path}/v2ray -config=$config_file >/dev/null &
if [ -f "$v2ray_bin" ]; then
$v2ray_bin -config=$config_file >/dev/null &
else
echolog "找不到V2ray客户端主程序无法启用"
fi
elif [ "$type" == "trojan" ]; then
lua $API_GEN_TROJAN $node client "0.0.0.0" $local_port >$config_file
trojan_bin=$(find_bin trojan)
[ -f "$trojan_bin" ] && $trojan_bin -c $config_file >/dev/null 2>&1 &
elif [ "$type" == "brook" ]; then
BROOK_SOCKS5_CMD="client -l 0.0.0.0:$local_port -i 0.0.0.0 -s $server_ip:$port -p $(config_n_get $node password)"
brook_bin=$(config_t_get global_app brook_file $(find_bin brook))
if [ -f "$brook_bin" ]; then
$brook_bin $BROOK_SOCKS5_CMD &>/dev/null &
else
@ -352,12 +380,10 @@ gen_start_config() {
fi
elif [ "$type" == "ssr" ]; then
gen_ss_ssr_config_file ssr $local_port 0 $node $config_file
ssr_bin=$(find_bin ssr-local)
[ -n "$ssr_bin" ] && $ssr_bin -c $config_file -b 0.0.0.0 -u >/dev/null 2>&1 &
[ -f "$ssr_local_bin" ] && $ssr_local_bin -c $config_file -b 0.0.0.0 -u >/dev/null 2>&1 &
elif [ "$type" == "ss" ]; then
gen_ss_ssr_config_file ss $local_port 0 $node $config_file
ss_bin=$(find_bin ss-local)
[ -n "$ss_bin" ] && {
[ -n "$ss_local_bin" ] && {
local plugin_params=""
local plugin=$(config_n_get $node ss_plugin)
if [ "$plugin" != "none" ]; then
@ -366,7 +392,7 @@ gen_start_config() {
plugin_params="--plugin $plugin --plugin-opts $opts"
}
fi
$ss_bin -c $config_file -b 0.0.0.0 -u $plugin_params >/dev/null 2>&1 &
$ss_local_bin -c $config_file -b 0.0.0.0 -u $plugin_params >/dev/null 2>&1 &
}
fi
fi
@ -385,20 +411,17 @@ gen_start_config() {
local server_username=$(config_n_get $node username)
local server_password=$(config_n_get $node password)
eval port=\$UDP_REDIR_PORT$5
ipt2socks_bin=$(find_bin ipt2socks)
[ -f "$ipt2socks_bin" ] && $ipt2socks_bin -U -l $port -b 0.0.0.0 -s $node_address -p $node_port -R >/dev/null &
#redsocks_bin=$(find_bin redsocks2)
#[ -n "$redsocks_bin" ] && {
#[ -f "$redsocks2_bin" ] && {
# local redsocks_config_file=$CONFIG_PATH/UDP_$i.conf
# gen_redsocks_config $redsocks_config_file udp $port $node_address $node_port $server_username $server_password
# $redsocks_bin -c $redsocks_config_file >/dev/null &
# $redsocks2_bin -c $redsocks_config_file >/dev/null &
#}
elif [ "$type" == "v2ray" ]; then
lua $API_GEN_V2RAY $node udp $local_port nil >$config_file
v2ray_path=$(config_t_get global_app v2ray_file $(find_bin v2ray))
if [ -f "${v2ray_path}/v2ray" ]; then
${v2ray_path}/v2ray -config=$config_file >/dev/null &
if [ -f "$v2ray_bin" ]; then
$v2ray_bin -config=$config_file >/dev/null &
else
echolog "找不到V2ray客户端主程序无法启用"
fi
@ -418,9 +441,8 @@ gen_start_config() {
balancing_node_address="$temp"
done
lua $API_GEN_V2RAY $node udp $local_port nil >$config_file
v2ray_path=$(config_t_get global_app v2ray_file $(find_bin v2ray))
if [ -f "${v2ray_path}/v2ray" ]; then
${v2ray_path}/v2ray -config=$config_file >/dev/null &
if [ -f "$v2ray_bin" ]; then
$v2ray_bin -config=$config_file >/dev/null &
else
echolog "找不到V2ray客户端主程序无法启用"
fi
@ -429,7 +451,6 @@ gen_start_config() {
local_port=$(get_not_exists_port_after $SOCKS5_PROXY_PORT4 tcp)
socks5_port=$local_port
lua $API_GEN_TROJAN $node client "127.0.0.1" $socks5_port >$config_file
trojan_bin=$(find_bin trojan)
[ -f "$trojan_bin" ] && $trojan_bin -c $config_file >/dev/null 2>&1 &
local node_address=$(config_n_get $node address)
@ -437,18 +458,15 @@ gen_start_config() {
local server_username=$(config_n_get $node username)
local server_password=$(config_n_get $node password)
eval port=\$UDP_REDIR_PORT$5
ipt2socks_bin=$(find_bin ipt2socks)
[ -f "$ipt2socks_bin" ] && $ipt2socks_bin -U -l $port -b 0.0.0.0 -s 127.0.0.1 -p $socks5_port -R >/dev/null &
#redsocks_bin=$(find_bin redsocks2)
#[ -n "$redsocks_bin" ] && {
#[ -f "$redsocks2_bin" ] && {
# local redsocks_config_file=$CONFIG_PATH/redsocks_UDP_$i.conf
# gen_redsocks_config $redsocks_config_file udp $port "127.0.0.1" $socks5_port
# $redsocks_bin -c $redsocks_config_file >/dev/null &
# $redsocks2_bin -c $redsocks_config_file >/dev/null &
#}
elif [ "$type" == "brook" ]; then
BROOK_UDP_CMD="tproxy -l 0.0.0.0:$local_port -s $server_ip:$port -p $(config_n_get $node password)"
brook_bin=$(config_t_get global_app brook_file $(find_bin brook))
if [ -f "$brook_bin" ]; then
$brook_bin $BROOK_UDP_CMD &>/dev/null &
else
@ -456,16 +474,14 @@ gen_start_config() {
fi
elif [ "$type" == "ssr" ]; then
gen_ss_ssr_config_file ssr $local_port 0 $node $config_file
ssr_bin=$(find_bin ssr-redir)
if [ -f "$ssr_bin" ]; then
$ssr_bin -c $config_file -f $RUN_PID_PATH/udp_ssr_1_$5 -U >/dev/null 2>&1 &
if [ -f "$ssr_redir_bin" ]; then
$ssr_redir_bin -c $config_file -f $RUN_PID_PATH/udp_ssr_1_$5 -U >/dev/null 2>&1 &
else
echolog "找不到ssr客户端主程序无法启用"
fi
elif [ "$type" == "ss" ]; then
gen_ss_ssr_config_file ss $local_port 0 $node $config_file
ss_bin=$(find_bin ss-redir)
[ -f "$ss_bin" ] && {
[ -f "$ss_redir_bin" ] && {
local plugin_params=""
local plugin=$(config_n_get $node ss_plugin)
if [ "$plugin" != "none" ]; then
@ -474,7 +490,7 @@ gen_start_config() {
plugin_params="--plugin $plugin --plugin-opts $opts"
}
fi
$ss_bin -c $config_file -f $RUN_PID_PATH/udp_ss_1_$5 -U $plugin_params >/dev/null 2>&1 &
$ss_redir_bin -c $config_file -f $RUN_PID_PATH/udp_ss_1_$5 -U $plugin_params >/dev/null 2>&1 &
}
fi
fi
@ -493,20 +509,17 @@ gen_start_config() {
local server_username=$(config_n_get $node username)
local server_password=$(config_n_get $node password)
eval port=\$TCP_REDIR_PORT$5
ipt2socks_bin=$(find_bin ipt2socks)
[ -f "$ipt2socks_bin" ] && $ipt2socks_bin -l $port -b 0.0.0.0 -s $node_address -p $socks5_port -R >/dev/null &
#redsocks_bin=$(find_bin redsocks2)
#[ -n "$redsocks_bin" ] && {
#[ -f "$redsocks2_bin" ] && {
# local redsocks_config_file=$CONFIG_PATH/TCP_$i.conf
# gen_redsocks_config $redsocks_config_file tcp $port $node_address $socks5_port $server_username $server_password
# $redsocks_bin -c $redsocks_config_file >/dev/null &
# $redsocks2_bin -c $redsocks_config_file >/dev/null &
#}
elif [ "$type" == "v2ray" ]; then
lua $API_GEN_V2RAY $node tcp $local_port nil >$config_file
v2ray_path=$(config_t_get global_app v2ray_file $(find_bin v2ray))
if [ -f "${v2ray_path}/v2ray" ]; then
${v2ray_path}/v2ray -config=$config_file >/dev/null &
if [ -f "$v2ray_bin" ]; then
$v2ray_bin -config=$config_file >/dev/null &
else
echolog "找不到V2ray客户端主程序无法启用"
fi
@ -526,59 +539,54 @@ gen_start_config() {
balancing_node_address="$temp"
done
lua $API_GEN_V2RAY $node tcp $local_port nil >$config_file
v2ray_path=$(config_t_get global_app v2ray_file $(find_bin v2ray))
if [ -f "${v2ray_path}/v2ray" ]; then
${v2ray_path}/v2ray -config=$config_file >/dev/null &
if [ -f "$v2ray_bin" ]; then
$v2ray_bin -config=$config_file >/dev/null &
else
echolog "找不到V2ray客户端主程序无法启用"
fi
elif [ "$type" == "trojan" ]; then
lua $API_GEN_TROJAN $node nat "0.0.0.0" $local_port >$config_file
trojan_bin=$(find_bin trojan)
[ -f "$trojan_bin" ] && $trojan_bin -c $config_file >/dev/null 2>&1 &
else
local kcptun_use kcptun_server_host kcptun_port kcptun_config
kcptun_use=$(config_n_get $node use_kcp 0)
kcptun_server_host=$(config_n_get $node kcp_server)
kcptun_port=$(config_n_get $node kcp_port)
kcptun_config="$(config_n_get $node kcp_opts)"
kcptun_bin=$(config_t_get global_app kcptun_client_file $(find_bin kcptun-client))
lbenabled=$(config_t_get global_haproxy balancing_enable 0)
if [ -z "$kcptun_bin" ]; then
echolog "【未安装Kcptun主程序请到自动更新下载Kcptun】跳过~"
force_stop
fi
if [ "$kcptun_use" == "1" ] && ([ -z "$kcptun_port" ] || [ -z "$kcptun_config" ]); then
echolog "【未配置Kcptun参数】跳过~"
force_stop
fi
if [ "$kcptun_use" == "1" -a -n "$kcptun_port" -a -n "$kcptun_config" -a "$lbenabled" == "0" -a -f "$kcptun_bin" ]; then
local run_kcptun_ip=$server_ip
if [ -n "$kcptun_server_host" ]; then
kcptun_use_ipv6=$(config_n_get $node kcp_use_ipv6)
network_type="ipv4"
[ "$kcptun_use_ipv6" == "1" ] && network_type="ipv6"
kcptun_server_ip=$(get_host_ip $network_type $kcptun_server_host)
eval TCP_NODE${5}_IP=$kcptun_server_ip
run_kcptun_ip=$kcptun_server_ip
echolog "Kcptun节点IP地址:$kcptun_server_ip"
local kcptun_use=$(config_n_get $node use_kcp 0)
if [ "$kcptun_use" == "1" ]; then
local kcptun_server_host=$(config_n_get $node kcp_server)
local kcptun_port=$(config_n_get $node kcp_port)
local kcptun_config="$(config_n_get $node kcp_opts)"
local lbenabled=$(config_t_get global_haproxy balancing_enable 0)
if [ ! -f "$kcptun_bin" ]; then
echolog "【未安装Kcptun主程序请到自动更新下载Kcptun】跳过~"
force_stop
fi
if [ -z "$kcptun_port" -o -z "$kcptun_config" ]; then
echolog "【未配置Kcptun参数】跳过~"
force_stop
fi
if [ -n "$kcptun_port" -a -n "$kcptun_config" -a "$lbenabled" == "0" -a -f "$kcptun_bin" ]; then
local run_kcptun_ip=$server_ip
if [ -n "$kcptun_server_host" ]; then
kcptun_use_ipv6=$(config_n_get $node kcp_use_ipv6)
network_type="ipv4"
[ "$kcptun_use_ipv6" == "1" ] && network_type="ipv6"
kcptun_server_ip=$(get_host_ip $network_type $kcptun_server_host)
eval TCP_NODE${5}_IP=$kcptun_server_ip
run_kcptun_ip=$kcptun_server_ip
echolog "Kcptun节点IP地址:$kcptun_server_ip"
fi
KCPTUN_REDIR_PORT=$(get_not_exists_port_after $KCPTUN_REDIR_PORT udp)
$kcptun_bin --log $CONFIG_PATH/kcptun_${5}.log -l 0.0.0.0:$KCPTUN_REDIR_PORT -r $run_kcptun_ip:$kcptun_port $kcptun_config >/dev/null 2>&1 &
fi
KCPTUN_REDIR_PORT=$(get_not_exists_port_after $KCPTUN_REDIR_PORT udp)
$kcptun_bin --log $CONFIG_PATH/kcptun_${5}.log -l 0.0.0.0:$KCPTUN_REDIR_PORT -r $run_kcptun_ip:$kcptun_port $kcptun_config >/dev/null 2>&1 &
fi
if [ "$type" == "ssr" ]; then
gen_ss_ssr_config_file ssr $local_port $kcptun_use $node $config_file
ssr_bin=$(find_bin ssr-redir)
[ -f "$ssr_bin" ] && {
[ -f "$ssr_redir_bin" ] && {
for k in $(seq 1 $process); do
$ssr_bin -c $config_file -f $RUN_PID_PATH/tcp_ssr_${k}_${5} >/dev/null 2>&1 &
$ssr_redir_bin -c $config_file -f $RUN_PID_PATH/tcp_ssr_${k}_${5} >/dev/null 2>&1 &
done
}
elif [ "$type" == "ss" ]; then
gen_ss_ssr_config_file ss $local_port $kcptun_use $node $config_file
ss_bin=$(find_bin ${type}-redir)
[ -f "$ss_bin" ] && {
[ -f "$ss_redir_bin" ] && {
local plugin_params=""
local plugin=$(config_n_get $node ss_plugin)
if [ "$plugin" != "none" ]; then
@ -588,7 +596,7 @@ gen_start_config() {
}
fi
for k in $(seq 1 $process); do
$ss_bin -c $config_file -f $RUN_PID_PATH/tcp_ss_${k}_${5} $plugin_params >/dev/null 2>&1 &
$ss_redir_bin -c $config_file -f $RUN_PID_PATH/tcp_ss_${k}_${5} $plugin_params >/dev/null 2>&1 &
done
}
elif [ "$type" == "brook" ]; then
@ -597,7 +605,6 @@ gen_start_config() {
port=$KCPTUN_REDIR_PORT
}
BROOK_TCP_CMD="tproxy -l 0.0.0.0:$local_port -s $server_ip:$port -p $(config_n_get $node password)"
brook_bin=$(config_t_get global_app brook_file $(find_bin brook))
if [ -f "$brook_bin" ]; then
$brook_bin $BROOK_TCP_CMD &>/dev/null &
else
@ -692,10 +699,10 @@ start_crontab() {
if [ "$autoupdatesubscribe" = "1" ]; then
if [ "$weekupdatesubscribe" = "7" ]; then
echo "0 $dayupdatesubscribe * * * $APP_PATH/subscription.sh" >>/etc/crontabs/root
echo "0 $dayupdatesubscribe * * * lua $APP_PATH/subscribe.lua >> /var/log/passwall.log" >>/etc/crontabs/root
echolog "设置节点订阅自动更新规则在每天 $dayupdatesubscribe 点。"
else
echo "0 $dayupdatesubscribe * * $weekupdate $APP_PATH/subscription.sh" >>/etc/crontabs/root
echo "0 $dayupdatesubscribe * * $weekupdate lua $APP_PATH/subscribe.lua >> /var/log/passwall.log" >>/etc/crontabs/root
echolog "设置节点订阅自动更新规则在星期 $weekupdate$dayupdatesubscribe 点。"
fi
else
@ -723,8 +730,7 @@ start_dns() {
;;
dns2socks)
if [ -n "$SOCKS5_NODE1" -a "$SOCKS5_NODE1" != "nil" ]; then
dns2socks_bin=$(find_bin dns2socks)
[ -n "$dns2socks_bin" ] && {
[ -f "$dns2socks_bin" ] && {
DNS2SOCKS_FORWARD=$(config_t_get global dns2socks_forward 8.8.4.4)
nohup $dns2socks_bin 127.0.0.1:$SOCKS5_PROXY_PORT1 $DNS2SOCKS_FORWARD 127.0.0.1:$DNS_PORT >/dev/null 2>&1 &
echolog "DNSdns2socks..."
@ -735,8 +741,7 @@ start_dns() {
fi
;;
pdnsd)
pdnsd_bin=$(find_bin pdnsd)
[ -n "$pdnsd_bin" ] && {
[ -f "$pdnsd_bin" ] && {
use_tcp_node_resolve_dns=1
gen_pdnsd_config $DNS_PORT 10240
DNS_FORWARD=$(echo $DNS_FORWARD | sed 's/,/ /g')
@ -745,8 +750,7 @@ start_dns() {
}
;;
chinadns-ng)
chinadns_ng_bin=$(find_bin chinadns-ng)
[ -n "$chinadns_ng_bin" ] && {
[ -f "$chinadns_ng_bin" ] && {
other_port=$(expr $DNS_PORT + 1)
cat $RULE_PATH/gfwlist.conf | sort | uniq | sed -e '/127.0.0.1/d' | sed 's/ipset=\/.//g' | sed 's/\/gfwlist//g' > $CONFIG_PATH/gfwlist.txt
[ -f "$CONFIG_PATH/gfwlist.txt" ] && local gfwlist_param="-g $CONFIG_PATH/gfwlist.txt"
@ -760,8 +764,7 @@ start_dns() {
else
use_tcp_node_resolve_dns=1
gen_pdnsd_config $other_port 0
pdnsd_bin=$(find_bin pdnsd)
[ -n "$pdnsd_bin" ] && {
[ -f "$pdnsd_bin" ] && {
DNS_FORWARD=$(echo $DNS_FORWARD | sed 's/,/ /g')
nohup $pdnsd_bin --daemon -c $pdnsd_dir/pdnsd.conf -d >/dev/null 2>&1 &
nohup $chinadns_ng_bin -l $DNS_PORT -c $UP_CHINA_DNS -t 127.0.0.1#$other_port $gfwlist_param $chnlist_param >/dev/null 2>&1 &
@ -770,8 +773,7 @@ start_dns() {
fi
elif [ "$up_trust_chinadns_ng_dns" == "dns2socks" ]; then
if [ -n "$SOCKS5_NODE1" -a "$SOCKS5_NODE1" != "nil" ]; then
dns2socks_bin=$(find_bin dns2socks)
[ -n "$dns2socks_bin" ] && {
[ -f "$dns2socks_bin" ] && {
DNS2SOCKS_FORWARD=$(config_t_get global dns2socks_forward 8.8.4.4)
nohup $dns2socks_bin 127.0.0.1:$SOCKS5_PROXY_PORT1 $DNS2SOCKS_FORWARD 127.0.0.1:$other_port >/dev/null 2>&1 &
nohup $chinadns_ng_bin -l $DNS_PORT -c $UP_CHINA_DNS -t 127.0.0.1#$other_port $gfwlist_param $chnlist_param >/dev/null 2>&1 &
@ -978,8 +980,7 @@ stop_dnsmasq() {
start_haproxy() {
enabled=$(config_t_get global_haproxy balancing_enable 0)
[ "$enabled" = "1" ] && {
haproxy_bin=$(find_bin haproxy)
[ -n "$haproxy_bin" ] && {
[ -f "$haproxy_bin" ] && {
bport=$(config_t_get global_haproxy haproxy_port)
cat <<-EOF >$HAPROXY_FILE
global
@ -1133,8 +1134,7 @@ stop() {
done
clean_log
source $APP_PATH/iptables.sh stop
kill_all brook dns2socks haproxy chinadns-ng ipt2socks v2ray-plugin obfs-local
ps -w | grep -E "$CONFIG_TCP_FILE|$CONFIG_UDP_FILE|$CONFIG_SOCKS5_FILE" | grep -v "grep" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &
kill_all v2ray-plugin obfs-local
ps -w | grep -E "$CONFIG_PATH" | grep -v "grep" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1 &
rm -rf $TMP_DNSMASQ_PATH $CONFIG_PATH
stop_dnsmasq

View File

@ -2,6 +2,7 @@
CONFIG=passwall
CONFIG_PATH=/var/etc/$CONFIG
RUN_BIN_PATH=$CONFIG_PATH/bin
config_n_get() {
local ret=$(uci -q get $CONFIG.$1.$2 2>/dev/null)
@ -40,14 +41,14 @@ for i in $(seq 1 $TCP_NODE_NUM); do
#kcptun
use_kcp=$(config_n_get $tmp_node use_kcp 0)
if [ $use_kcp -gt 0 ]; then
icount=$(ps -w | grep kcptun-client | grep $CONFIG_PATH/kcptun_${i} | grep -v grep | wc -l)
icount=$(ps -w | grep -v grep | grep $RUN_BIN_PATH | grep kcptun-client | grep kcptun_${i} | wc -l)
if [ $icount = 0 ]; then
/etc/init.d/passwall restart
exit 0
fi
fi
[ -f "/var/etc/passwall/port/TCP_$i" ] && listen_port=$(echo -n `cat /var/etc/passwall/port/TCP_$i`)
icount=$(ps -w | grep -v grep | grep -i -E "${CONFIG}/TCP_${i}|brook tproxy -l 0.0.0.0:${listen_port}|ipt2socks -T -l ${listen_port}" | wc -l)
icount=$(ps -w | grep -v grep | grep $RUN_BIN_PATH | grep -i -E "TCP_${i}|brook tproxy -l 0.0.0.0:${listen_port}|ipt2socks -T -l ${listen_port}" | wc -l)
if [ $icount = 0 ]; then
/etc/init.d/passwall restart
exit 0
@ -62,7 +63,7 @@ for i in $(seq 1 $UDP_NODE_NUM); do
if [ "$tmp_node" != "nil" ]; then
[ "$tmp_node" == "default" ] && tmp_node=$TCP_NODE1
[ -f "/var/etc/passwall/port/UDP_$i" ] && listen_port=$(echo -n `cat /var/etc/passwall/port/UDP_$i`)
icount=$(ps -w | grep -v grep | grep -i -E "${CONFIG}/UDP_${i}|brook tproxy -l 0.0.0.0:${listen_port}|ipt2socks -U -l ${listen_port}" | wc -l)
icount=$(ps -w | grep -v grep | grep $RUN_BIN_PATH | grep -i -E "UDP_${i}|brook tproxy -l 0.0.0.0:${listen_port}|ipt2socks -U -l ${listen_port}" | wc -l)
if [ $icount = 0 ]; then
/etc/init.d/passwall restart
exit 0
@ -75,7 +76,7 @@ for i in $(seq 1 $SOCKS5_NODE_NUM); do
eval tmp_node=\$SOCKS5_NODE$i
if [ "$tmp_node" != "nil" ]; then
[ -f "/var/etc/passwall/port/SOCKS5_$i" ] && listen_port=$(echo -n `cat /var/etc/passwall/port/SOCKS5_$i`)
icount=$(ps -w | grep -v grep | grep -i -E "${CONFIG}/SOCKS5_${i}|brook client -l 0.0.0.0:${listen_port}" | wc -l)
icount=$(ps -w | grep -v grep | grep $RUN_BIN_PATH | grep -i -E "SOCKS5_${i}|brook client -l 0.0.0.0:${listen_port}" | wc -l)
if [ $icount = 0 ]; then
/etc/init.d/passwall restart
exit 0
@ -94,7 +95,7 @@ fi
#haproxy
if [ $use_haproxy -gt 0 ]; then
icount=$(ps -w | grep haproxy | grep $CONFIG_PATH/haproxy.cfg | grep -v grep | wc -l)
icount=$(ps -w | grep -v grep | grep $RUN_BIN_PATH | grep haproxy | wc -l)
if [ $icount = 0 ]; then
/etc/init.d/passwall restart
exit 0

View File

@ -0,0 +1,463 @@
#!/usr/bin/lua
------------------------------------------------
-- This file from luci-app-ssr-plus transplant to luci-app-passwall
-- This file is part of the luci-app-ssr-plus subscribe.lua
-- @author William Chan <root@williamchan.me>
------------------------------------------------
require 'nixio'
require 'luci.util'
require 'luci.jsonc'
require 'luci.sys'
local params = arg[1]
-- these global functions are accessed all the time by the event handler
-- so caching them is worth the effort
local luci = luci
local tinsert = table.insert
local ssub, slen, schar, sbyte, sformat, sgsub = string.sub, string.len, string.char, string.byte, string.format, string.gsub
local jsonParse, jsonStringify = luci.jsonc.parse, luci.jsonc.stringify
local b64decode = nixio.bin.b64decode
local cache = {}
local nodeResult = setmetatable({}, { __index = cache }) -- update result
local name = 'passwall'
local uciType = 'nodes'
local ucic = luci.model.uci.cursor()
local api = require "luci.model.cbi.passwall.api.api"
local log = function(...)
print(os.date("%Y-%m-%d %H:%M:%S: ") .. table.concat({ ... }, " "))
end
-- 分割字符串
local function split(full, sep)
full = full:gsub("%z", "") -- 这里不是很清楚 有时候结尾带个\0
local off, result = 1, {}
while true do
local nEnd = full:find(sep, off)
if not nEnd then
local res = ssub(full, off, slen(full))
if #res > 0 then -- 过滤掉 \0
tinsert(result, res)
end
break
else
tinsert(result, ssub(full, off, nEnd - 1))
off = nEnd + slen(sep)
end
end
return result
end
-- urlencode
local function get_urlencode(c)
return sformat("%%%02X", sbyte(c))
end
local function urlEncode(szText)
local str = szText:gsub("([^0-9a-zA-Z ])", get_urlencode)
str = str:gsub(" ", "+")
return str
end
local function get_urldecode(h)
return schar(tonumber(h, 16))
end
local function UrlDecode(szText)
return szText:gsub("+", " "):gsub("%%(%x%x)", get_urldecode)
end
-- trim
local function trim(text)
if not text or text == "" then
return ""
end
return (sgsub(text, "^%s*(.-)%s*$", "%1"))
end
-- md5
local function md5(content)
local stdout = luci.sys.exec('echo \"' .. urlEncode(content) .. '\" | md5sum | cut -d \" \" -f1')
-- assert(nixio.errno() == 0)
return trim(stdout)
end
-- base64
local function base64Decode(text)
local raw = text
if not text then return '' end
text = text:gsub("%z", "")
text = text:gsub("_", "/")
text = text:gsub("-", "+")
local mod4 = #text % 4
text = text .. string.sub('====', mod4 + 1)
local result = b64decode(text)
if result then
return result:gsub("%z", "")
else
return raw
end
end
-- 处理数据
local function processData(szType, content, add_mode)
local result = {
timeout = 60,
add_mode = add_mode,
is_sub = (add_mode and add_mode == "导入") and 0 or 1
}
result.hashkey = type(content) == 'string' and md5(content) or md5(jsonStringify(content))
if szType == 'ssr' then
local dat = split(content, "/\\?")
local hostInfo = split(dat[1], ':')
result.type = "SSR"
result.address = hostInfo[1]
result.port = hostInfo[2]
result.protocol = hostInfo[3]
result.ssr_encrypt_method = hostInfo[4]
result.obfs = hostInfo[5]
result.password = base64Decode(hostInfo[6])
local params = {}
for _, v in pairs(split(dat[2], '&')) do
local t = split(v, '=')
params[t[1]] = t[2]
end
result.obfs_param = base64Decode(params.bfsparam)
result.protocol_param = base64Decode(params.protoparam)
local group = base64Decode(params.group)
if group then
result.group = group
end
result.remarks = base64Decode(params.remarks)
elseif szType == 'vmess' then
local info = jsonParse(content)
result.type = 'V2ray'
result.address = info.add
result.port = info.port
result.v2ray_transport = info.net
result.v2ray_VMess_alterId = info.aid
result.v2ray_VMess_id = info.id
result.remarks = info.ps
result.v2ray_mux = 1
result.v2ray_mux_concurrency = 8
if info.net == 'ws' then
result.v2ray_ws_host = info.host
result.v2ray_ws_path = info.path
end
if info.net == 'h2' then
result.v2ray_h2_host = info.host
result.v2ray_h2_path = info.path
end
if info.net == 'tcp' then
result.v2ray_tcp_guise = info.type
result.v2ray_tcp_guise_http_host = info.host
result.v2ray_tcp_guise_http_path = info.path
end
if info.net == 'kcp' then
result.v2ray_mkcp_guise = info.type
result.v2ray_mkcp_mtu = 1350
result.v2ray_mkcp_tti = 50
result.v2ray_mkcp_uplinkCapacity = 5
result.v2ray_mkcp_downlinkCapacity = 20
result.v2ray_mkcp_readBufferSize = 2
result.v2ray_mkcp_writeBufferSize = 2
end
if info.net == 'quic' then
result.v2ray_quic_guise = info.type
result.v2ray_quic_key = info.key
result.v2ray_quic_security = info.securty
end
if not info.security then
result.v2ray_security = "auto"
end
if info.tls == "tls" or info.tls == "1" then
result.v2ray_stream_security = "tls"
result.tls_serverName = info.host
else
result.v2ray_stream_security = "none"
end
elseif szType == "ss" then
local idx_sp = 0
local alias = ""
if content:find("#") then
idx_sp = content:find("#")
alias = content:sub(idx_sp + 1, -1)
end
local info = content:sub(1, idx_sp - 1)
local hostInfo = split(base64Decode(info), "@")
local host = split(hostInfo[2], ":")
local userinfo = base64Decode(hostInfo[1])
local method = userinfo:sub(1, userinfo:find(":") - 1)
local password = userinfo:sub(userinfo:find(":") + 1, #userinfo)
result.remarks = UrlDecode(alias)
result.type = "SS"
result.address = host[1]
if host[2]:find("/\\?") then
local query = split(host[2], "/\\?")
result.port = query[1]
local params = {}
for _, v in pairs(split(query[2], '&')) do
local t = split(v, '=')
params[t[1]] = t[2]
end
if params.lugin then
local plugin_info = UrlDecode(params.lugin)
local idx_pn = plugin_info:find(";")
if idx_pn then
result.ss_plugin = plugin_info:sub(1, idx_pn - 1)
result.ss_plugin_opts = plugin_info:sub(idx_pn + 1, #plugin_info)
else
result.ss_plugin = plugin_info
end
end
else
result.port = host[2]
end
result.ss_encrypt_method = method
result.password = password
elseif szType == "ssd" then
result.type = "SS"
result.address = content.server
result.port = content.port
result.password = content.password
result.ss_encrypt_method = content.encryption
result.ss_plugin = content.plugin
result.ss_plugin_opts = content.plugin_options
result.group = content.airport
result.remarks = content.remarks
end
if not result.remarks then
result.remarks = result.address .. ':' .. result.port
end
return result
end
-- wget
local function wget(url)
local stdout = luci.sys.exec('/usr/bin/wget --user-agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36" --no-check-certificate -t 3 -T 10 -O- "' .. url .. '"')
return trim(stdout)
end
local function truncate_nodes()
local is_stop = 0
local tcp_node_num = ucic:get_first(name, "global_other", "tcp_node_num", 1)
local udp_node_num = ucic:get_first(name, "global_other", "udp_node_num", 1)
local socks5_node_num = ucic:get_first(name, "global_other", "socks5_node_num", 1)
for i = 1, tcp_node_num, 1 do
local node = ucic:get_first(name, "global", "tcp_node"..i, nil)
if node and node ~= "nil" then
local is_sub_node = api.uci_get_type_id(node, "is_sub", "0")
if is_sub_node == "1" then
is_stop = 1
ucic:set(name, ucic:get_first(name, 'global'), "tcp_node"..i, "nil")
end
end
end
for i = 1, udp_node_num, 1 do
local node = ucic:get_first(name, "global", "udp_node"..i, nil)
if node and node ~= "nil" then
local is_sub_node = api.uci_get_type_id(node, "is_sub", "0")
if is_sub_node == "1" then
is_stop = 1
ucic:set(name, ucic:get_first(name, 'global'), "udp_node"..i, "nil")
end
end
end
for i = 1, socks5_node_num, 1 do
local node = ucic:get_first(name, "global", "socks5_node"..i, nil)
if node and node ~= "nil" then
local is_sub_node = api.uci_get_type_id(node, "is_sub", "0")
if is_sub_node == "1" then
is_stop = 1
ucic:set(name, ucic:get_first(name, 'global'), "socks5_node"..i, "nil")
end
end
end
ucic:foreach(name, uciType, function(old)
if old.is_sub and old.is_sub == "1" then
ucic:delete(name, old['.name'])
end
end)
ucic:commit(name)
if is_stop == 1 then
luci.sys.call("/etc/init.d/" .. name .. " restart > /dev/null 2>&1 &") -- 不加&的话日志会出现的更早
end
log('在线订阅节点已全部删除')
end
local function update_node(manual)
assert(next(nodeResult), "node result is empty")
local add, del = 0, 0
ucic:foreach(name, uciType, function(old)
if old.grouphashkey or old.hashkey then -- 没有 hash 的不参与删除
if manual == 0 and (old.is_sub and old.is_sub == "1") then
if not nodeResult[old.grouphashkey] or not nodeResult[old.grouphashkey][old.hashkey] then
ucic:delete(name, old['.name'])
del = del + 1
else
local dat = nodeResult[old.grouphashkey][old.hashkey]
ucic:tset(name, old['.name'], dat)
-- 标记一下
setmetatable(nodeResult[old.grouphashkey][old.hashkey], { __index = { _ignore = true } })
end
elseif manual == 1 and (old.add_mode and old.add_mode == "导入") then
if not nodeResult[old.grouphashkey] or not nodeResult[old.grouphashkey][old.hashkey] then
ucic:delete(name, old['.name'])
del = del + 1
else
local dat = nodeResult[old.grouphashkey][old.hashkey]
ucic:tset(name, old['.name'], dat)
-- 标记一下
setmetatable(nodeResult[old.grouphashkey][old.hashkey], { __index = { _ignore = true } })
end
end
else
--log('忽略手动添加的节点: ' .. old.remarks)
end
end)
for k, v in ipairs(nodeResult) do
for kk, vv in ipairs(v) do
if not vv._ignore then
local section = ucic:add(name, uciType)
ucic:tset(name, section, vv)
add = add + 1
end
end
end
ucic:commit(name)
-- 如果节点已经不见了把帮换一个
local globalServer = ucic:get_first(name, 'global', 'tcp_node1', '')
local firstServer = ucic:get_first(name, uciType)
if not ucic:get(name, globalServer) then
if firstServer then
ucic:set(name, ucic:get_first(name, 'global'), 'tcp_node1', firstServer)
ucic:commit(name)
log('当前主服务器已更新,正在自动更换。')
end
luci.sys.call("/etc/init.d/" .. name .. " restart > /dev/null 2>&1 &") -- 不加&的话日志会出现的更早
end
log('新增节点数量: ' ..add, '删除节点数量: ' .. del)
end
local function parse_link(raw, md5_str, manual)
if raw and #raw > 0 then
local add_mode
local nodes, szType
local groupHash = md5_str or md5(raw)
cache[groupHash] = {}
tinsert(nodeResult, {})
local index = #nodeResult
-- SSD 似乎是这种格式 ssd:// 开头的
if raw:find('ssd://') then
szType = 'ssd'
local nEnd = select(2, raw:find('ssd://'))
nodes = base64Decode(raw:sub(nEnd + 1, #raw))
nodes = jsonParse(nodes)
local extra = {
airport = nodes.airport,
port = nodes.port,
encryption = nodes.encryption,
password = nodes.password
}
local servers = {}
-- SS里面包着 干脆直接这样
for _, server in ipairs(nodes.servers) do
tinsert(servers, setmetatable(server, { __index = extra }))
end
nodes = servers
else
-- ssd 外的格式
if manual then
nodes = split(raw:gsub(" ", "\n"), "\n")
add_mode = '导入'
else
nodes = split(base64Decode(raw):gsub(" ", "\n"), "\n")
end
end
for _, v in ipairs(nodes) do
if v then
local result
if szType == 'ssd' then
result = processData(szType, v, add_mode)
elseif not szType then
local node = trim(v)
local dat = split(node, "://")
if dat and dat[1] and dat[2] then
if dat[1] == 'ss' then
result = processData(dat[1], dat[2], add_mode)
else
result = processData(dat[1], base64Decode(dat[2]), add_mode)
end
end
else
log('跳过未知类型: ' .. szType)
end
-- log(result)
if result then
if result.remarks:find("过期时间") or
result.remarks:find("剩余流量") or
result.remarks:find("QQ群") or
result.remarks:find("官网") or
not result.address
then
log('丢弃无效节点: ' .. result.type ..' 节点, ' .. result.remarks)
else
--log('成功解析: ' .. result.type ..' 节点, ' .. result.remarks)
result.grouphashkey = groupHash
tinsert(nodeResult[index], result)
cache[groupHash][result.hashkey] = nodeResult[index][#nodeResult[index]]
end
end
end
end
log('成功解析节点数量: ' ..#nodes)
end
end
local execute = function()
-- exec
do
ucic:foreach(name, "subscribe_list", function(obj)
local enabled = obj.enabled or nil
if enabled and enabled == "1" then
local remark = obj.remark
local url = obj.url
local md5_str = md5(url)
local raw = wget(url)
parse_link(raw, md5_str)
end
end)
end
-- diff
do
update_node(0)
end
end
if arg[1] then
if arg[1] == "start" then
count = luci.sys.exec("echo -n $(uci show " .. name .." | grep @subscribe_list | grep -c \"enabled='1'\")")
if count and tonumber(count) > 0 then
log('开始订阅...')
xpcall(execute, function(e)
log(e)
log(debug.traceback())
log('发生错误, 正在恢复服务')
end)
log('订阅完毕...')
end
elseif arg[1] == "add" then
local f = assert(io.open("/tmp/links.conf",'r'))
local content = f:read('*all')
f:close()
local nodes = split(content:gsub(" ", "\n"), "\n")
for _, raw in ipairs(nodes) do
local md5_str = md5(raw)
parse_link(raw, md5_str, 1)
end
update_node(1)
elseif arg[1] == "truncate" then
truncate_nodes()
end
end

View File

@ -1,597 +0,0 @@
#!/bin/bash
. $IPKG_INSTROOT/lib/functions.sh
. /usr/share/libubox/jshn.sh
CONFIG=passwall
LOCK_FILE=/var/lock/${CONFIG}_subscription.lock
Date=$(date "+%Y-%m-%d %H:%M:%S")
LOG_FILE=/var/log/$CONFIG.log
config_t_get() {
local index=0
[ -n "$3" ] && index=$3
local ret=$(uci -q get $CONFIG.@$1[$index].$2 2>/dev/null)
#echo ${ret:=$3}
echo $ret
}
urldecode() { : "${*//+/ }"; echo -e "${_//%/\\x}"; }
decode_url_link() {
link=$1
num=$2
len=$((${#link}-$num))
mod4=$(($len%4))
if [ "$mod4" -gt 0 ]; then
var="===="
newlink=${link}${var:$mod4}
echo -n "$newlink" | sed 's/-/+/g; s/_/\//g' | base64 -d -i 2> /dev/null
else
echo -n "$link" | sed 's/-/+/g; s/_/\//g' | base64 -d -i 2> /dev/null
fi
}
start_subscribe() {
local enabled
local url
config_get enabled $1 enabled
config_get url $1 url
[ "$enabled" == "1" ] && {
[ -n "$url" -a "$url" != "" ] && {
local addnum_ss=0
local updatenum_ss=0
local delnum_ss=0
local addnum_ssr=0
local updatenum_ssr=0
local delnum_ssr=0
local addnum_v2ray=0
local updatenum_v2ray=0
local delnum_v2ray=0
local addnum_trojan=0
local updatenum_trojan=0
local delnum_trojan=0
config_get subscrib_remark $1 remark
let index+=1
echo "$Date: 正在订阅:$url" >> $LOG_FILE
result=$(/usr/bin/curl --connect-timeout 5 --retry 1 -sL $url)
[ "$?" != 0 ] || [ -z "$result" ] && {
result=$(/usr/bin/wget --no-check-certificate --timeout=5 -t 1 -O- $url)
[ "$?" != 0 ] || [ -z "$result" ] && echo "$Date: 订阅失败:$url,请检测订阅链接是否正常或使用代理尝试!" >> $LOG_FILE && continue
}
file="/var/${CONFIG}_sub/$index"
echo "$result" > $file
get_local_nodes
if [ $(expr "$result" : "ssd://") == 0 ];then
[ -z "$(du -sh $file 2> /dev/null)" ] && echo "$Date: 订阅失败:$url,解密失败!" >> $LOG_FILE && continue
decode_link=$(cat "$file" | base64 -d 2> /dev/null)
maxnum=$(echo -n "$decode_link" | grep "MAX=" | awk -F"=" '{print $2}')
if [ -n "$maxnum" ]; then
decode_link=$(echo -n "$decode_link" | sed '/MAX=/d' | shuf -n${maxnum})
else
decode_link=$(echo -n "$decode_link")
fi
[ -z "$decode_link" ] && continue
for link in $decode_link
do
if expr "$link" : "ss://";then
link_type="ss"
new_link=$(echo -n "$link" | sed 's/ss:\/\///g')
elif expr "$link" : "ssr://";then
link_type="ssr"
new_link=$(echo -n "$link" | sed 's/ssr:\/\///g')
elif expr "$link" : "vmess://";then
link_type="v2ray"
new_link=$(echo -n "$link" | sed 's/vmess:\/\///g')
elif expr "$link" : "trojan://";then
link_type="trojan"
new_link=$(echo -n "$link" | sed 's/trojan:\/\///g')
fi
[ -z "$link_type" ] && continue
get_remote_config "$link_type" "$new_link"
done
else
link=$result
link_type="ssd"
new_link=$(echo -n "$link" | sed 's/ssd:\/\///g')
[ -z "$link_type" ] && continue
get_remote_config "$link_type" "$new_link"
fi
[ "$addnum_ss" -gt 0 ] || [ "$updatenum_ss" -gt 0 ] || [ "$delnum_ss" -gt 0 ] && echo "$Date: $subscrib_remark SS节点新增 $addnum_ss 个,修改 $updatenum_ss 个,删除 $delnum_ss 个。" >> $LOG_FILE
[ "$addnum_ssr" -gt 0 ] || [ "$updatenum_ssr" -gt 0 ] || [ "$delnum_ssr" -gt 0 ] && echo "$Date: $subscrib_remark SSR节点新增 $addnum_ssr 个,修改 $updatenum_ssr 个,删除 $delnum_ssr 个。" >> $LOG_FILE
[ "$addnum_v2ray" -gt 0 ] || [ "$updatenum_v2ray" -gt 0 ] || [ "$delnum_v2ray" -gt 0 ] && echo "$Date: $subscrib_remark V2ray节点新增 $addnum_v2ray 个,修改 $updatenum_v2ray 个,删除 $delnum_v2ray 个。" >> $LOG_FILE
[ "$addnum_trojan" -gt 0 ] || [ "$updatenum_trojan" -gt 0 ] || [ "$delnum_trojan" -gt 0 ] && echo "$Date: $subscrib_remark Trojan节点新增 $addnum_trojan 个,修改 $updatenum_trojan 个,删除 $delnum_trojan 个。" >> $LOG_FILE
}
}
}
ss_decode() {
temp_link=$1
if [[ "$(echo $temp_link | grep "@")" != "" ]]; then
link1=$(decode_url_link $(echo -n "$temp_link" | awk -F '@' '{print $1}') 1)
link2=$(echo -n "$temp_link" | awk -F '@' '{print $2}')
echo -n "${link1}@${link2}"
elif [[ "$(echo $temp_link | grep "#")" != "" ]]; then
link1=$(decode_url_link $(echo -n "$temp_link" | awk -F '#' '{print $1}') 1)
link2=$(echo -n "$temp_link" | awk -F '#' '{print $2}')
echo -n "${link1}#${link2}"
else
link1=$(decode_url_link $(echo -n "$temp_link" ) 1)
echo -n "$link1"
fi
}
get_node_index(){
[ -f "/etc/config/$CONFIG" ] && {
nodes_index=$(uci show $CONFIG | grep -c "=nodes")
}
}
get_local_nodes(){
[ -f "/etc/config/$CONFIG" ] && [ "`uci show $CONFIG | grep -c 'is_sub'`" -gt 0 ] && {
get_node_index
for i in `seq $nodes_index -1 1`
do
[ "$(uci show $CONFIG.@nodes[$(($i-1))]|grep -c "is_sub")" -eq 1 ] && {
if [ ! -f "/usr/share/${CONFIG}/sub/all_localnodes" ]; then
echo $(config_t_get nodes address $(($i-1))) > /usr/share/${CONFIG}/sub/all_localnodes
else
echo $(config_t_get nodes address $(($i-1))) >> /usr/share/${CONFIG}/sub/all_localnodes
fi
}
done
}
}
get_remote_config(){
add_mode="$subscrib_remark"
[ -n "$3" ] && add_mode="导入"
new_node_type=$(echo $1 | tr '[a-z]' '[A-Z]')
if [ "$1" == "ss" ]; then
decode_link=$(ss_decode $2)
ss_encrypt_method=$(echo "$decode_link" | awk -F ':' '{print $1}')
password=$(echo "$decode_link" | awk -F ':' '{print $2}' | awk -F '@' '{print $1}')
node_address=$(echo "$decode_link" | awk -F ':' '{print $2}' | awk -F '@' '{print $2}')
plugin_tmp=$(echo "$decode_link" | awk -F '\\/\\?' '{print $2}' | awk -F '#' '{print $1}')
if [ "$plugin_tmp" != "" ]; then
plugin_tmp=$(urldecode $plugin_tmp)
plugin=$(echo "$plugin_tmp" | awk -F 'plugin=' '{print $2}' | awk -F ';' '{print $1}')
plugin_options=$(echo "$plugin_tmp" | awk -F "$plugin;" '{print $2}' | awk -F '&' '{print $1}')
node_port=$(echo "$decode_link" | awk -F '@' '{print $2}' | awk -F '\\/\\?' '{print $1}' | awk -F ':' '{print $2}')
else
node_port=$(echo "$decode_link" | awk -F '@' '{print $2}' | awk -F '#' '{print $1}' | awk -F ':' '{print $2}')
fi
[ -n "$plugin" -a "$plugin" == "simple-obfs" ] && plugin=obfs-local
remarks=$(urldecode $(echo "$decode_link" | awk -F '#' '{print $2}'))
elif [ "$1" == "ssr" ]; then
decode_link=$(decode_url_link $2 1)
node_address=$(echo "$decode_link" | awk -F ':' '{print $1}')
node_port=$(echo "$decode_link" | awk -F ':' '{print $2}')
protocol=$(echo "$decode_link" | awk -F ':' '{print $3}')
ssr_encrypt_method=$(echo "$decode_link" | awk -F ':' '{print $4}')
obfs=$(echo "$decode_link" | awk -F ':' '{print $5}')
password=$(decode_url_link $(echo "$decode_link" | awk -F ':' '{print $6}' | awk -F '/' '{print $1}') 0)
obfsparm_temp=$(echo "$decode_link" |grep -Eo "obfsparam.+" |sed 's/obfsparam=//g'|awk -F'&' '{print $1}')
[ -n "$obfsparm_temp" ] && obfsparam=$(decode_url_link $obfsparm_temp 0) || obfsparam=''
protoparam_temp=$(echo "$decode_link" |grep -Eo "protoparam.+" |sed 's/protoparam=//g'|awk -F'&' '{print $1}')
[ -n "$protoparam_temp" ] && protoparam=$(decode_url_link $protoparam_temp 0) || protoparam=''
remarks_temp=$(echo "$decode_link" |grep -Eo "remarks.+" |sed 's/remarks=//g'|awk -F'&' '{print $1}')
[ -n "$remarks_temp" ] && remarks="$(decode_url_link $remarks_temp 0)"
group_temp=$(echo "$decode_link" |grep -Eo "group.+" |sed 's/group=//g'|awk -F'&' '{print $1}')
[ -n "$group_temp" ] && group="$(decode_url_link $group_temp 0)"
elif [ "$1" == "v2ray" ]; then
decode_link=$(decode_url_link $2 1)
json_load "$decode_link"
json_get_var json_v v
json_get_var json_ps ps
json_get_var json_node_address add
json_get_var json_node_port port
json_get_var json_id id
json_get_var json_aid aid
json_get_var json_security security
json_get_var json_net net
json_get_var json_type type
json_get_var json_transport net
json_get_var json_tls tls
json_get_var json_host host
json_get_var json_path path
if [ "$json_tls" == "tls" -o "$json_tls" == "1" ]; then
json_tls="tls"
else
json_tls="none"
fi
remarks="${json_ps}"
node_address=$json_node_address
node_port=$json_node_port
elif [ "$1" == "trojan" ]; then
link="$2"
node_password=$(echo "$link" | sed 's/trojan:\/\///g' | awk -F '@' '{print $1}')
node_address=$(echo "$link" | sed 's/trojan:\/\///g' | awk -F '@' '{print $2}' | awk -F ':' '{print $1}')
node_port=$(echo "$link" | sed 's/trojan:\/\///g' | awk -F '@' '{print $2}' | awk -F ':' '{print $2}')
remarks="${node_address}:${node_port}"
elif [ "$1" == "ssd" ]; then
link_type="ss"
new_node_type=$(echo $link_type | tr '[a-z]' '[A-Z]')
decode_link=$(decode_url_link $2 1)
json_load "$decode_link"
json_get_var json_airport airport
json_get_var json_port port
json_get_var json_encryption encryption
json_get_var json_password password
json_get_var json_traffic_used traffic_used
json_get_var json_traffic_total traffic_total
json_get_var json_expiry expiry
json_get_var json_url url
json_get_var json_plugin plugin
json_get_var json_plugin_options plugin_options
ss_encrypt_method=$json_encryption
password=$json_password
plugin=$json_plugin
plugin_options=$json_plugin_options
[ -n "$plugin" -a "$plugin" == "simple-obfs" ] && plugin=obfs-local
if json_get_type Type servers && [ "$Type" == array ]
then
json_select servers
idx=1
while json_get_type Type "$idx" && [ "$Type" == object ]
do
json_select $idx
json_get_var json_server server
json_get_var json_server_id id
json_get_var json_server_ratio ratio
json_get_var json_server_remarks remarks
remarks="${json_server_remarks}"
node_address=$json_server
node_port=$json_port
idx=$(expr $idx + 1)
json_select ..
node_address=$(echo -n $node_address | awk '{print gensub(/[^!-~]/,"","g",$0)}')
node_address=$(echo -n $node_address | grep -F ".")
[ -z "$node_address" -o "$node_address" == "" ] && return
[ -z "$remarks" -o "$remarks" == "" ] && remarks="${node_address}:${node_port}"
tmp=$(echo $remarks | grep -E "过期时间|剩余流量|QQ群|官网")
[ -n "$tmp" ] && {
echo "$Date: 丢弃无用节点:$tmp" >> $LOG_FILE
return
}
# 把全部节点节点写入文件 /usr/share/${CONFIG}/sub/all_onlinenodes
if [ ! -f "/usr/share/${CONFIG}/sub/all_onlinenodes" ]; then
echo $node_address > /usr/share/${CONFIG}/sub/all_onlinenodes
else
echo $node_address >> /usr/share/${CONFIG}/sub/all_onlinenodes
fi
update_config
done
return
fi
fi
node_address=$(echo -n $node_address | awk '{print gensub(/[^!-~]/,"","g",$0)}')
node_address=$(echo -n $node_address | grep -F ".")
[ -z "$node_address" -o "$node_address" == "" ] && return
[ -z "$remarks" -o "$remarks" == "" ] && remarks="${node_address}:${node_port}"
tmp=$(echo $remarks | grep -E "过期时间|剩余流量|QQ群|官网")
[ -n "$tmp" ] && {
echo "$Date: 丢弃无用节点:$tmp" >> $LOG_FILE
return
}
# 把全部节点节点写入文件 /usr/share/${CONFIG}/sub/all_onlinenodes
if [ ! -f "/usr/share/${CONFIG}/sub/all_onlinenodes" ]; then
echo $node_address > /usr/share/${CONFIG}/sub/all_onlinenodes
else
echo $node_address >> /usr/share/${CONFIG}/sub/all_onlinenodes
fi
update_config
}
add_nodes(){
if [ "$1" == "add" ]; then
get_node_index
uci add $CONFIG nodes
elif [ "$1" == "update" ]; then
nodes_index=$update_index
fi
uci_set="uci set $CONFIG.@nodes[$nodes_index]."
[ "$add_mode" != "导入" ] && ${uci_set}is_sub="is_sub"
if [ "$2" == "ss" ]; then
${uci_set}add_mode="$add_mode"
${uci_set}remarks="$remarks"
${uci_set}type="SS"
${uci_set}address="$node_address"
${uci_set}use_ipv6=0
${uci_set}port="$node_port"
${uci_set}password="$password"
${uci_set}ss_encrypt_method="$ss_encrypt_method"
${uci_set}timeout=300
${uci_set}tcp_fast_open=false
[ -n "$plugin" ] && ${uci_set}ss_plugin="$plugin"
[ -n "$plugin_options" ] && ${uci_set}ss_plugin_opts="$plugin_options"
if [ "$1" == "add" ]; then
let addnum_ss+=1
elif [ "$1" == "update" ]; then
let updatenum_ss+=1
fi
elif [ "$2" == "ssr" ]; then
${uci_set}add_mode="$add_mode"
${uci_set}remarks="$remarks"
${uci_set}type="SSR"
${uci_set}address="$node_address"
${uci_set}use_ipv6=0
${uci_set}port="$node_port"
${uci_set}password="$password"
${uci_set}ssr_encrypt_method="$ssr_encrypt_method"
${uci_set}protocol="$protocol"
${uci_set}protocol_param="$protoparam"
${uci_set}obfs="$obfs"
${uci_set}obfs_param="$obfsparam"
${uci_set}timeout=300
${uci_set}tcp_fast_open=false
${uci_set}group="$group"
if [ "$1" == "add" ]; then
let addnum_ssr+=1
elif [ "$1" == "update" ]; then
let updatenum_ssr+=1
fi
elif [ "$2" == "v2ray" ]; then
${uci_set}add_mode="$add_mode"
${uci_set}remarks="$remarks"
${uci_set}type="V2ray"
${uci_set}v2ray_protocol="vmess"
${uci_set}address="$node_address"
${uci_set}use_ipv6=0
${uci_set}port="$json_node_port"
${uci_set}v2ray_security="auto"
${uci_set}v2ray_VMess_id="$json_id"
${uci_set}v2ray_VMess_alterId="$json_aid"
${uci_set}v2ray_VMess_level="$json_v"
${uci_set}v2ray_transport="$json_net"
${uci_set}v2ray_stream_security="$json_tls"
${uci_set}v2ray_tcp_guise="$json_type"
${uci_set}v2ray_ws_host="$json_host"
${uci_set}v2ray_ws_path="$json_path"
${uci_set}v2ray_h2_host="$json_host"
${uci_set}v2ray_h2_path="$json_path"
${uci_set}tls_allowInsecure=1
if [ "$1" == "add" ]; then
let addnum_v2ray+=1
elif [ "$1" == "update" ]; then
let updatenum_v2ray+=1
fi
elif [ "$2" == "trojan" ]; then
${uci_set}add_mode="$add_mode"
${uci_set}remarks="$remarks"
${uci_set}type="Trojan"
${uci_set}address="$node_address"
${uci_set}port="$node_port"
${uci_set}password="$node_password"
if [ "$1" == "add" ]; then
let addnum_trojan+=1
elif [ "$1" == "update" ]; then
let updatenum_trojan+=1
fi
fi
uci commit $CONFIG
}
update_config(){
[ -z "$remarks" -o "$remarks" == "" ] && return
indexs=$(uci show $CONFIG | grep "@nodes" | grep "remarks=" | grep -F "$remarks" | cut -d '[' -f2|cut -d ']' -f1)
if [ -z "$indexs" ]; then
add_nodes add "$link_type"
else
action="add"
for index in $indexs
do
local is_sub=$(uci -q get $CONFIG.@nodes[$index].is_sub)
[ -z "$is_sub" -o "$is_sub" == "" ] && return
local old_node_type=$(uci -q get $CONFIG.@nodes[$index].type | tr '[a-z]' '[A-Z]')
if [ -n "$old_node_type" -a "$old_node_type" == "$new_node_type" ]; then
action="update"
update_index=$index
break
fi
done
if [ "$action" == "add" ]; then
add_nodes add "$link_type"
elif [ "$action" == "update" ]; then
add_nodes update "$link_type"
fi
fi
}
del_config(){
# 删除订阅节点已经不存在的节点
for localaddress in $(cat /usr/share/${CONFIG}/sub/all_localnodes)
do
[ "`cat /usr/share/${CONFIG}/sub/all_onlinenodes |grep -c "$localaddress"`" -eq 0 ] && {
for localindex in $(uci show $CONFIG | grep -w "$localaddress" | grep -w "address=" |cut -d '[' -f2|cut -d ']' -f1)
do
del_type=$(uci -q get $CONFIG.@nodes[$localindex].type)
uci delete $CONFIG.@nodes[$localindex]
uci commit $CONFIG
if [ "$del_type" == "SS" ]; then
let delnum_ss+=1 #删除该节点
elif [ "$del_type" == "SSR" ]; then
let delnum_ssr+=1 #删除该节点
elif [ "$del_type" == "V2ray" ]; then
let delnum_v2ray+=1 #删除该节点
elif [ "$del_type" == "Trojan" ]; then
let delnum_trojan=1 #删除该节点
fi
done
}
done
}
del_all_config(){
get_node_index
[ "`uci show $CONFIG | grep -c 'is_sub'`" -eq 0 ] && exit 0
TCP_NODE_NUM=$(uci -q get $CONFIG.@global_other[0].tcp_node_num)
[ -z "$TCP_NODE_NUM" ] && TCP_NODE_NUM=1
for i in $(seq 1 $TCP_NODE_NUM); do
eval TCP_NODE$i=$(config_t_get global tcp_node$i)
done
UDP_NODE_NUM=$(uci -q get $CONFIG.@global_other[0].udp_node_num)
[ -z "$UDP_NODE_NUM" ] && UDP_NODE_NUM=1
for i in $(seq 1 $UDP_NODE_NUM); do
eval UDP_NODE$i=$(config_t_get global udp_node$i)
done
SOCKS5_NODE_NUM=$(uci -q get $CONFIG.@global_other[0].socks5_node_num)
[ -z "$SOCKS5_NODE_NUM" ] && SOCKS5_NODE_NUM=1
for i in $(seq 1 $SOCKS5_NODE_NUM); do
eval SOCKS5_NODE$i=$(config_t_get global socks5_node$i)
done
[ "$UDP_NODE1" == "default" ] && UDP_NODE1=$TCP_NODE1
is_stop=0
for i in $(seq 1 $TCP_NODE_NUM); do
eval node=\$TCP_NODE$i
[ -n "$node" -a "$node" != "nil" ] && {
is_sub_node=`uci -q get $CONFIG.$node.is_sub`
[ -n "$is_sub_node" ] && {
is_stop=1
uci set $CONFIG.@global[0].tcp_node$i="nil" && uci commit $CONFIG
}
}
done
for i in $(seq 1 $UDP_NODE_NUM); do
eval node=\$UDP_NODE$i
[ "$node" != "nil" ] && {
is_sub_node=`uci -q get $CONFIG.$node.is_sub`
[ -n "$is_sub_node" ] && {
is_stop=1
uci set $CONFIG.@global[0].udp_node$i="nil" && uci commit $CONFIG
}
}
done
for i in $(seq 1 $SOCKS5_NODE_NUM); do
eval node=\$SOCKS5_NODE$i
[ "$node" != "nil" ] && {
is_sub_node=`uci -q get $CONFIG.$node.is_sub`
[ -n "$is_sub_node" ] && {
is_stop=1
uci set $CONFIG.@global[0].socks5_node$i="nil" && uci commit $CONFIG
}
}
done
for i in `seq $nodes_index -1 1`
do
[ "$(uci show $CONFIG.@nodes[$(($i-1))] | grep -c 'is_sub')" -eq 1 ] && uci delete $CONFIG.@nodes[$(($i-1))] && uci commit $CONFIG
done
[ "$is_stop" == 1 ] && /etc/init.d/$CONFIG restart
}
add() {
base64=$(command -v base64)
[ -z "$base64" ] && echo "$Date: 找不到Base64程序请安装后重试" >> $LOG_FILE && rm -f "$LOCK_FILE" && exit 0
LINKS=$(cat /tmp/links.conf 2>/dev/null)
[ -n "$LINKS" ] && {
[ -f "$LOCK_FILE" ] && return 3
touch "$LOCK_FILE"
mkdir -p /usr/share/${CONFIG}/sub && rm -f /usr/share/${CONFIG}/sub/*
for link in $LINKS
do
if expr "$link" : "ss://";then
link_type="ss"
new_link=$(echo -n "$link" | sed 's/ss:\/\///g')
elif expr "$link" : "ssr://";then
link_type="ssr"
new_link=$(echo -n "$link" | sed 's/ssr:\/\///g')
elif expr "$link" : "vmess://";then
link_type="v2ray"
new_link=$(echo -n "$link" | sed 's/vmess:\/\///g')
elif expr "$link" : "trojan://";then
link_type="trojan"
new_link=$(echo -n "$link" | sed 's/trojan:\/\///g')
fi
[ -z "$link_type" ] && continue
get_remote_config "$link_type" "$new_link" 1
done
[ -f "/usr/share/${CONFIG}/sub/all_onlinenodes" ] && rm -f /usr/share/${CONFIG}/sub/all_onlinenodes
}
rm -f /tmp/links.conf
rm -f "$LOCK_FILE"
exit 0
}
start() {
# 防止并发开启服务
[ -f "$LOCK_FILE" ] && return 3
touch "$LOCK_FILE"
base64=$(command -v base64)
[ -z "$base64" ] && echo "$Date: 找不到Base64程序请安装后重试" >> $LOG_FILE && rm -f "$LOCK_FILE" && exit 0
has_subscribe=$(uci show $CONFIG | grep @subscribe_list | grep enabled=\'1\')
[ -z "$has_subscribe" -o "$has_subscribe" = "" ] && echo "$Date: 没有订阅地址或没启用!" >> $LOG_FILE && rm -f "$LOCK_FILE" && exit 0
echo "$Date: 开始订阅..." >> $LOG_FILE
mkdir -p /var/${CONFIG}_sub && rm -f /var/${CONFIG}_sub/*
mkdir -p /usr/share/${CONFIG}/sub && rm -f /usr/share/${CONFIG}/sub/*
index=0
config_load $CONFIG
config_foreach start_subscribe "subscribe_list"
[ -f "/usr/share/${CONFIG}/sub/all_localnodes" ] && del_config
echo "$Date: 订阅完毕..." >> $LOG_FILE
rm -f "$LOCK_FILE"
exit 0
}
stop() {
[ "`uci show $CONFIG | grep -c 'is_sub'`" -gt 0 ] && {
del_all_config
echo "$Date: 在线订阅节点已全部删除" >> $LOG_FILE
}
rm -rf /var/${CONFIG}_sub
rm -rf /usr/share/${CONFIG}/sub
rm -f "$LOCK_FILE"
exit 0
}
case $1 in
stop)
stop
;;
add)
add
;;
*)
start
;;
esac