mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-09-13 20:04:45 +08:00
🗽 Sync 2026-06-03 14:05:40
This commit is contained in:
@@ -10,58 +10,6 @@
|
||||
LOCK_FILE="/var/lock/ssr-monitor.lock"
|
||||
[ -f "$LOCK_FILE" ] && exit 2
|
||||
touch "$LOCK_FILE"
|
||||
|
||||
ps_list() {
|
||||
if busybox ps -w >/dev/null 2>&1; then
|
||||
busybox ps -w
|
||||
else
|
||||
busybox ps
|
||||
fi
|
||||
}
|
||||
|
||||
match_proc_count() {
|
||||
local pattern="$1"
|
||||
ps_list | grep -E "$pattern" | grep -v grep | wc -l
|
||||
}
|
||||
|
||||
redir_tcp_running() {
|
||||
local ssr_count
|
||||
local ipt_count
|
||||
ssr_count=$(match_proc_count 'ssr-retcp')
|
||||
ipt_count=$(ps_list | grep 'ipt2socks' | grep -v grep | grep -E ' -T( |$)| --tcp-only( |$)' | wc -l)
|
||||
echo $((ssr_count + ipt_count))
|
||||
}
|
||||
|
||||
redir_udp_running() {
|
||||
local ssr_count
|
||||
local ipt_count
|
||||
ssr_count=$(match_proc_count 'ssr-reudp')
|
||||
ipt_count=$(ps_list | grep 'ipt2socks' | grep -v grep | grep -E ' -U( |$)| --udp-only( |$)' | wc -l)
|
||||
echo $((ssr_count + ipt_count))
|
||||
}
|
||||
|
||||
kill_matched_procs() {
|
||||
local pattern="$1"
|
||||
ps_list | grep -E "$pattern" | grep -v grep | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1
|
||||
}
|
||||
|
||||
get_expected_threads() {
|
||||
local threads
|
||||
threads=$(uci_get_by_type global threads 0)
|
||||
if [ "$threads" = "0" ] || [ -z "$threads" ]; then
|
||||
threads=$(grep -c '^processor' /proc/cpuinfo 2>/dev/null)
|
||||
fi
|
||||
|
||||
case "$threads" in
|
||||
''|*[!0-9]*)
|
||||
threads=1
|
||||
;;
|
||||
esac
|
||||
|
||||
[ "$threads" -lt 1 ] && threads=1
|
||||
echo "$threads"
|
||||
}
|
||||
|
||||
server_process_count=$1
|
||||
redir_tcp_process=$2
|
||||
redir_udp_process=$3
|
||||
@@ -73,8 +21,6 @@ if [ -z "$pdnsd_process" ]; then
|
||||
fi
|
||||
i=0
|
||||
GLOBAL_SERVER=$(uci_get_by_type global global_server)
|
||||
GLOBAL_TYPE=$(uci_get_by_name $GLOBAL_SERVER type)
|
||||
EXPECTED_THREADS=$(get_expected_threads)
|
||||
server=$(uci_get_by_name $GLOBAL_SERVER server)
|
||||
kcp_port=$(uci_get_by_name $GLOBAL_SERVER kcp_port)
|
||||
server_port=$(uci_get_by_name $GLOBAL_SERVER server_port)
|
||||
@@ -86,12 +32,8 @@ while [ "1" == "1" ]; do #死循环
|
||||
sleep 000030s
|
||||
#redir tcp
|
||||
if [ "$redir_tcp_process" -gt 0 ]; then
|
||||
icount=$(redir_tcp_running)
|
||||
local tcp_expected="$redir_tcp_process"
|
||||
if [ "$GLOBAL_TYPE" = "socks5" ]; then
|
||||
tcp_expected="$EXPECTED_THREADS"
|
||||
fi
|
||||
if [ "$icount" -lt "$tcp_expected" ]; then
|
||||
icount=$(busybox ps -w | grep ssr-retcp | grep -v grep | wc -l)
|
||||
if [ "$icount" == 0 ]; then
|
||||
logger -t "$NAME" "ssrplus redir tcp error.restart!"
|
||||
echolog "ssrplus redir tcp error.restart!"
|
||||
/etc/init.d/shadowsocksr restart
|
||||
@@ -100,12 +42,8 @@ while [ "1" == "1" ]; do #死循环
|
||||
fi
|
||||
#redir udp
|
||||
if [ "$redir_udp_process" -gt 0 ]; then
|
||||
icount=$(redir_udp_running)
|
||||
local udp_expected="$redir_udp_process"
|
||||
if [ "$GLOBAL_TYPE" = "socks5" ]; then
|
||||
udp_expected="$EXPECTED_THREADS"
|
||||
fi
|
||||
if [ "$icount" -lt "$udp_expected" ]; then
|
||||
icount=$(busybox ps -w | grep ssr-reudp | grep -v grep | wc -l)
|
||||
if [ "$icount" == 0 ]; then
|
||||
logger -t "$NAME" "ssrplus redir udp error.restart!"
|
||||
echolog "ssrplus redir udp error.restart!"
|
||||
/etc/init.d/shadowsocksr restart
|
||||
@@ -114,18 +52,18 @@ while [ "1" == "1" ]; do #死循环
|
||||
fi
|
||||
#server
|
||||
if [ "$server_process_count" -gt 0 ]; then
|
||||
icount=$(match_proc_count 'ssr-server|ss-server-|xray-server-')
|
||||
icount=$(busybox ps -w | grep ssr-server | grep -v grep | wc -l)
|
||||
if [ "$icount" -lt "$server_process_count" ]; then #如果进程挂掉就重启它
|
||||
logger -t "$NAME" "ssrplus server error.restart!"
|
||||
echolog "ssrplus server error.restart!"
|
||||
kill_matched_procs 'ssr-server|ss-server-'
|
||||
kill -9 $(busybox ps -w | grep ssr-server | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
/etc/init.d/shadowsocksr restart
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
#kcptun
|
||||
if [ "$kcp_process" -gt 0 ]; then
|
||||
icount=$(ps_list | grep kcptun-client | grep -v grep | wc -l)
|
||||
icount=$(busybox ps -w | grep kcptun-client | grep -v grep | wc -l)
|
||||
if [ "$icount" -lt "$kcp_process" ]; then #如果进程挂掉就重启它
|
||||
logger -t "$NAME" "ssrplus kcptun error.restart!"
|
||||
echolog "ssrplus kcptun error.restart!"
|
||||
@@ -135,43 +73,132 @@ while [ "1" == "1" ]; do #死循环
|
||||
fi
|
||||
#localsocks
|
||||
if [ "$local_process" -gt 0 ]; then
|
||||
icount=$(match_proc_count 'ssr-local|ss-local|tuic-local')
|
||||
icount=$(busybox ps -w | grep ssr-local | grep -v grep | wc -l)
|
||||
if [ "$icount" -lt "$local_process" ]; then #如果进程挂掉就重启它
|
||||
logger -t "$NAME" "global socks server error.restart!"
|
||||
echolog "global socks server error.restart!"
|
||||
kill_matched_procs 'ssr-local|ss-local|tuic-local'
|
||||
kill -9 $(busybox ps -w | grep ssr-local | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
/etc/init.d/shadowsocksr restart
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
#dns2tcp
|
||||
if [ "$pdnsd_process" -eq 1 ]; then
|
||||
icount=$(ps_list | grep $TMP_BIN_PATH/dns2tcp | grep -v grep | wc -l)
|
||||
icount=$(busybox ps -w | grep $TMP_BIN_PATH/dns2tcp | grep -v grep | wc -l)
|
||||
if [ "$icount" -lt 1 ]; then #如果进程挂掉就重启它
|
||||
logger -t "$NAME" "dns2tcp tunnel error.restart!"
|
||||
echolog "dns2tcp tunnel error.restart!"
|
||||
dnsserver=$(uci_get_by_type global tunnel_forward 8.8.4.4:53)
|
||||
kill -9 $(ps_list | grep $TMP_BIN_PATH/dns2tcp | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
start_dns2tcp "$dnsserver"
|
||||
kill -9 $(busybox ps -w | grep $TMP_BIN_PATH/dns2tcp | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
ln_start_bin $(first_type dns2tcp) dns2tcp -L "127.0.0.1#$dns_port" -R "${dnsserver/:/#}"
|
||||
fi
|
||||
#dns2socks
|
||||
elif [ "$pdnsd_process" -eq 2 ]; then
|
||||
icount=$(busybox ps -w | grep -e ssrplus-dns -e "dns2socks 127.0.0.1 $tmp_dns_port" | grep -v grep | wc -l)
|
||||
if [ "$icount" -lt 1 ]; then #如果进程挂掉就重启它
|
||||
logger -t "$NAME" "dns2socks $dnsserver tunnel error.restart!"
|
||||
echolog "dns2socks $dnsserver tunnel error.restart!"
|
||||
dnsserver=$(uci_get_by_type global tunnel_forward 8.8.4.4:53)
|
||||
kill -9 $(busybox ps -w | grep ssrplus-dns | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
kill -9 $(busybox ps -w | grep "dns2socks 127.0.0.1 $tmp_dns_port" | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
ln_start_bin $(first_type microsocks) microsocks -i 127.0.0.1 -p $tmp_dns_port ssrplus-dns
|
||||
ln_start_bin $(first_type dns2socks) dns2socks 127.0.0.1:$tmp_dns_port $dnsserver 127.0.0.1:$dns_port -q
|
||||
fi
|
||||
#dns2socks-rust
|
||||
elif [ "$pdnsd_process" -eq 3 ]; then
|
||||
icount=$(busybox ps -w | grep -e ssrplus-dns -e "dns2socks-rust -s socks5://127.0.0.1 $tmp_dns_port" | grep -v grep | wc -l)
|
||||
if [ "$icount" -lt 1 ]; then #如果进程挂掉就重启它
|
||||
logger -t "$NAME" "dns2socks-rust $dnsserver tunnel error.restart!"
|
||||
echolog "dns2socks-rust $dnsserver tunnel error.restart!"
|
||||
dnsserver=$(uci_get_by_type global tunnel_forward 8.8.4.4:53)
|
||||
kill -9 $(busybox ps -w | grep ssrplus-dns | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
kill -9 $(busybox ps -w | grep "dns2socks-rust -s socks5://127.0.0.1 $tmp_dns_port" | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
ln_start_bin $(first_type microsocks) microsocks -i 127.0.0.1 -p $tmp_dns_port ssrplus-dns
|
||||
ln_start_bin $(first_type dns2socks) dns2socks-rust -s socks5://127.0.0.1:$tmp_dns_port -d $dnsserver -l 127.0.0.1:$dns_port -f -c
|
||||
fi
|
||||
#mosdns
|
||||
elif [ "$pdnsd_process" -eq 4 ]; then
|
||||
icount=$(ps_list | grep $TMP_BIN_PATH/mosdns | grep -v grep | wc -l)
|
||||
icount=$(busybox ps -w | grep $TMP_BIN_PATH/mosdns | grep -v grep | wc -l)
|
||||
if [ "$icount" -lt 1 ]; then #如果进程挂掉就重启它
|
||||
logger -t "$NAME" "mosdns tunnel error.restart!"
|
||||
echolog "mosdns tunnel error.restart!"
|
||||
dnsserver=$(uci_get_by_type global tunnel_forward 8.8.4.4:53)
|
||||
kill -9 $(ps_list | grep $TMP_BIN_PATH/mosdns | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
kill -9 $(busybox ps -w | grep $TMP_BIN_PATH/mosdns | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
ln_start_bin $(first_type mosdns) mosdns start -c /etc/mosdns/config.yaml
|
||||
#dnsproxy
|
||||
elif [ "$pdnsd_process" -eq 5 ]; then
|
||||
icount=$(busybox ps -w | grep -e ssrplus-dns -e "dnsproxy -l 127.0.0.1 -p $tmp_dns_port" | grep -v grep | wc -l)
|
||||
if [ "$icount" -lt 1 ]; then #如果进程挂掉就重启它
|
||||
logger -t "$NAME" "dnsproxy $dnsserver tunnel error.restart!"
|
||||
echolog "dnsproxy $dnsserver tunnel error.restart!"
|
||||
local dnsproxy_dnsserver="$(uci_get_by_type global parse_method)"
|
||||
if [ -n "$dnsproxy_dnsserver" ] && [ "$dnsproxy_dnsserver" != "parse_file" ]; then
|
||||
dnsserver="$(uci_get_by_type global dnsproxy_tunnel_forward 8.8.4.4:53)"
|
||||
fi
|
||||
kill -9 $(busybox ps -w | grep "dnsproxy -l 127.0.0.1 -p $tmp_dns_port" | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
dnsproxy_ipv6="$(uci_get_by_type global dnsproxy_ipv6)"
|
||||
disabled_ipv6="--ipv6-disabled"
|
||||
fi
|
||||
if [ "$dnsproxy_dnsserver" != "parse_file" ]; then
|
||||
ln_start_bin $(first_type dnsproxy) dnsproxy -l 127.0.0.1 -p $tmp_dns_port -p $dns_port -u $dnsserver $disabled_ipv6 --cache --cache-min-ttl=3600
|
||||
else
|
||||
dnsproxy_dnsserver_file="$TMP_PATH/dnsproxy_dns.list"
|
||||
cleaned_file="$TMP_PATH/cleaned_dns.list"
|
||||
temp_file="$TMP_PATH/temp_dns.list"
|
||||
> "$cleaned_file"
|
||||
# 清理输入文件并去重
|
||||
while IFS= read -r line || [ -n "$line" ]; do
|
||||
line=$(echo "$line" | sed -E 's/^[ \t\r]+//; s/[ \t\r]+$//')
|
||||
[ -z "$line" ] && continue
|
||||
echo "$line" | grep -qE '^#' && continue
|
||||
echo "$line" >> "$cleaned_file"
|
||||
done < "/etc/ssrplus/dnsproxy_dns.list"
|
||||
# 获取清理后文件的MD5
|
||||
cleaned_md5=$(md5sum "$cleaned_file" | awk '{print $1}')
|
||||
if [ ! -f "$dnsproxy_dnsserver_file" ]; then
|
||||
cp "$cleaned_file" "$dnsproxy_dnsserver_file"
|
||||
else
|
||||
target_md5=$(md5sum "$dnsproxy_dnsserver_file" | awk '{print $1}')
|
||||
if [ "$cleaned_md5" != "$target_md5" ]; then
|
||||
> "$temp_file"
|
||||
# 保留目标文件中也存在于清理文件的记录(去重)
|
||||
while IFS= read -r line; do
|
||||
line=$(echo "$line" | sed -E 's/^[ \t\r]+//; s/[ \t\r]+$//')
|
||||
if grep -qixF "$line" "$cleaned_file" && ! grep -qixF "$line" "$temp_file"; then
|
||||
echo "$line" >> "$temp_file"
|
||||
fi
|
||||
done < "$dnsproxy_dnsserver_file"
|
||||
# 添加清理文件中有但目标文件没有的记录(去重)
|
||||
while IFS= read -r line; do
|
||||
line=$(echo "$line" | sed -E 's/^[ \t\r]+//; s/[ \t\r]+$//')
|
||||
if ! grep -qixF "$line" "$temp_file"; then
|
||||
echo "$line" >> "$temp_file"
|
||||
fi
|
||||
done < "$cleaned_file"
|
||||
temp_md5=$(md5sum "$temp_file" | awk '{print $1}')
|
||||
if [ "$temp_md5" != "$target_md5" ]; then
|
||||
mv "$temp_file" "$dnsproxy_dnsserver_file"
|
||||
else
|
||||
rm -f "$temp_file"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
rm -f "$cleaned_file"
|
||||
|
||||
if [ -n "$dnsproxy_dnsserver_file" ] && [ -s "$dnsproxy_dnsserver_file" ]; then
|
||||
local upstreams_logic_mode="$(uci_get_by_type global upstreams_logic_mode)"
|
||||
ln_start_bin $(first_type dnsproxy) dnsproxy -l 127.0.0.1 -p $tmp_dns_port -p $dns_port -u $dnsproxy_dnsserver_file $disabled_ipv6 --cache --cache-min-ttl=3600 --upstream-mode=$upstreams_logic_mode
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
#chinadns-ng(proxy)
|
||||
elif [ "$pdnsd_process" -eq 6 ]; then
|
||||
icount=$(ps_list | grep -e ssrplus-dns -e "chinadns-ng -b 127.0.0.1 -l $tmp_dns_port" | grep -v grep | wc -l)
|
||||
icount=$(busybox ps -w | grep -e ssrplus-dns -e "chinadns-ng -b 127.0.0.1 -l $tmp_dns_port" | grep -v grep | wc -l)
|
||||
if [ "$icount" -lt 1 ]; then #如果进程挂掉就重启它
|
||||
logger -t "$NAME" "chinadns-ng $dnsserver tunnel error.restart!"
|
||||
echolog "chinadns-ng $dnsserver tunnel error.restart!"
|
||||
dnsserver=$(uci_get_by_type global chinadns_ng_tunnel_forward 8.8.4.4:53)
|
||||
kill -9 $(ps_list | grep "chinadns-ng -b 127.0.0.1 -l $tmp_dns_port" | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
kill -9 $(busybox ps -w | grep "chinadns-ng -b 127.0.0.1 -l $tmp_dns_port" | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
local chinadns_ng_proto="$(uci_get_by_type global chinadns_ng_proto)"
|
||||
local chinadns_ng_dns=""
|
||||
IFS=','
|
||||
@@ -197,18 +224,10 @@ while [ "1" == "1" ]; do #死循环
|
||||
dnsserver="$chinadns_ng_dns"
|
||||
ln_start_bin $(first_type chinadns-ng) chinadns-ng -b 127.0.0.1 -l $tmp_dns_port -l $dns_port -p 3 -d gfw $dnsserver -N --filter-qtype 64,65 -f -r --cache 4096 --cache-stale 86400 --cache-refresh 20
|
||||
fi
|
||||
#built-in dns
|
||||
elif [ "$pdnsd_process" -eq 7 ]; then
|
||||
if ! is_builtin_dns_active; then
|
||||
logger -t "$NAME" "builtin dns error.restart!"
|
||||
echolog "builtin dns error.restart!"
|
||||
/etc/init.d/shadowsocksr restart
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
#chinadns-ng(china)
|
||||
if [ "$(uci -q get "dhcp.@dnsmasq[0]._unused_ssrp_changed")" = "1" ]; then
|
||||
icount=$(ps_list | grep $TMP_BIN_PATH/chinadns-ng | grep -v grep | wc -l)
|
||||
icount=$(busybox ps -w | grep $TMP_BIN_PATH/chinadns-ng | grep -v grep | wc -l)
|
||||
if [ "$icount" -lt 1 ]; then #如果进程挂掉就重启它
|
||||
logger -t "$NAME" "chinadns-ng tunnel error.restart!"
|
||||
echolog "chinadns-ng tunnel error.restart!"
|
||||
@@ -218,7 +237,7 @@ while [ "1" == "1" ]; do #死循环
|
||||
"wan") chinadns="$wandns" ;;
|
||||
""|"wan_114") chinadns="$wandns,114.114.114.114" ;;
|
||||
esac
|
||||
kill -9 $(ps_list | grep $TMP_BIN_PATH/chinadns-ng | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
kill -9 $(busybox ps -w | grep $TMP_BIN_PATH/chinadns-ng | grep -v grep | awk '{print $1}') >/dev/null 2>&1
|
||||
ln_start_bin $(first_type chinadns-ng) chinadns-ng -l $china_dns_port -4 china -p 3 -c ${chinadns/:/#} -t 127.0.0.1#$dns_port -N -f -r
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -85,14 +85,13 @@ usage() {
|
||||
-e <extra_options> extra options for iptables
|
||||
-o apply the rules to the OUTPUT chain
|
||||
-O apply the global rules to the OUTPUT chain
|
||||
-u enable udprelay mode, TPROXY is required
|
||||
-U enable udprelay mode, using different IP
|
||||
and ports for TCP and UDP
|
||||
-y disable all auxiliary UDP rules when UDP
|
||||
transparent proxy is unavailable
|
||||
-f flush the rules
|
||||
-u enable udprelay mode, TPROXY is required
|
||||
-U enable udprelay mode, using different IP
|
||||
and ports for TCP and UDP
|
||||
-f flush the rules
|
||||
-g gfwlist mode
|
||||
-r router mode
|
||||
-c oversea mode
|
||||
-z all mode
|
||||
|
||||
# New persistence management options (use different letters to avoid conflicts)
|
||||
@@ -275,7 +274,7 @@ flush_nftables() {
|
||||
|
||||
# Optional: force delete all ss_spec related sets (even if table was accidentally deleted)
|
||||
for setname in ss_spec_lan_ac ss_spec_wan_ac ssr_gen_router \
|
||||
china fplan bplan gmlan whitelist blacklist gfwlist music; do
|
||||
china fplan bplan gmlan oversea whitelist blacklist netflix gfwlist music; do
|
||||
$NFT delete set inet ss_spec $setname 2>/dev/null
|
||||
$NFT delete set ip ss_spec_mangle $setname 2>/dev/null
|
||||
done
|
||||
@@ -311,7 +310,7 @@ flush_iptables_legacy() {
|
||||
ip route del local 0.0.0.0/0 dev lo table 999 2>/dev/null
|
||||
fi
|
||||
for setname in ss_spec_lan_ac ss_spec_wan_ac ssr_gen_router \
|
||||
china fplan bplan gmlan whitelist blacklist gfwlist music; do
|
||||
china fplan bplan gmlan oversea whitelist blacklist netflix gfwlist music; do
|
||||
ipset -X $setname 2>/dev/null
|
||||
done
|
||||
[ -n "$FWI" ] && echo '#!/bin/sh' >$FWI
|
||||
@@ -334,7 +333,7 @@ ipset_nft() {
|
||||
fi
|
||||
|
||||
# Create necessary collections
|
||||
for setname in china gmlan fplan bplan whitelist blacklist music; do
|
||||
for setname in china gmlan fplan bplan whitelist blacklist netflix music; do
|
||||
if ! $NFT list set inet ss_spec $setname >/dev/null 2>&1; then
|
||||
$NFT add set inet ss_spec $setname '{ type ipv4_addr; flags interval; auto-merge; }' 2>/dev/null
|
||||
else
|
||||
@@ -393,6 +392,13 @@ ipset_nft() {
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac meta l4proto tcp ip daddr @music return
|
||||
fi
|
||||
|
||||
# Shunt/Netflix rules
|
||||
if [ -f "$SHUNT_LIST" ]; then
|
||||
for ip in $(cat "$SHUNT_LIST" 2>/dev/null); do
|
||||
[ -n "$ip" ] && $NFT add element inet ss_spec netflix "{ $ip }" 2>/dev/null
|
||||
done
|
||||
fi
|
||||
|
||||
# Set up mode-specific rules
|
||||
case "$RUNMODE" in
|
||||
router)
|
||||
@@ -421,6 +427,14 @@ ipset_nft() {
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac ip daddr @gfwlist jump ss_spec_wan_fw
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac ip saddr @gmlan ip daddr != @china jump ss_spec_wan_fw
|
||||
;;
|
||||
oversea)
|
||||
if ! $NFT list set inet ss_spec oversea >/dev/null 2>&1; then
|
||||
$NFT add set inet ss_spec oversea '{ type ipv4_addr; flags interval; auto-merge; }' 2>/dev/null
|
||||
fi
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac ip daddr @oversea jump ss_spec_wan_fw
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac ip saddr @gmlan jump ss_spec_wan_fw
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac ip daddr @china jump ss_spec_wan_fw
|
||||
;;
|
||||
all)
|
||||
if $NFT list chain inet ss_spec ss_spec_wan_fw >/dev/null 2>&1; then
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac jump ss_spec_wan_fw
|
||||
@@ -436,10 +450,9 @@ ipset_iptables() {
|
||||
|
||||
$IPT -N SS_SPEC_WAN_AC 2>/dev/null
|
||||
$IPT -F SS_SPEC_WAN_AC
|
||||
$IPT -I SS_SPEC_WAN_AC -m mark --mark 255 -j RETURN
|
||||
|
||||
$IPT -I SS_SPEC_WAN_AC -p tcp --dport 53 -d 127.0.0.0/8 -j RETURN
|
||||
[ -n "$server" ] && $IPT -I SS_SPEC_WAN_AC -p tcp ! --dport 53 -d "$server" -j RETURN
|
||||
$IPT -I SS_SPEC_WAN_AC -p tcp ! --dport 53 -d "$server" -j RETURN
|
||||
|
||||
ipset -N gmlan hash:net 2>/dev/null
|
||||
for ip in $LAN_GM_IP; do ipset -! add gmlan "$ip"; done
|
||||
@@ -461,6 +474,12 @@ ipset_iptables() {
|
||||
$IPT -A SS_SPEC_WAN_AC -m set --match-set gfwlist dst -j SS_SPEC_WAN_FW
|
||||
$IPT -A SS_SPEC_WAN_AC -m set --match-set gmlan src -m set ! --match-set china dst -j SS_SPEC_WAN_FW
|
||||
;;
|
||||
oversea)
|
||||
ipset -N oversea hash:net 2>/dev/null
|
||||
$IPT -I SS_SPEC_WAN_AC -m set --match-set oversea dst -j SS_SPEC_WAN_FW
|
||||
$IPT -A SS_SPEC_WAN_AC -m set --match-set gmlan src -j SS_SPEC_WAN_FW
|
||||
$IPT -A SS_SPEC_WAN_AC -m set --match-set china dst -j SS_SPEC_WAN_FW
|
||||
;;
|
||||
all)
|
||||
$IPT -A SS_SPEC_WAN_AC -j SS_SPEC_WAN_FW
|
||||
;;
|
||||
@@ -491,6 +510,25 @@ ipset_iptables() {
|
||||
|
||||
for ip in $WAN_BP_IP; do ipset -! add whitelist "$ip"; done
|
||||
for ip in $WAN_FW_IP; do ipset -! add blacklist "$ip"; done
|
||||
|
||||
if [ "$SHUNT_PORT" != "0" ]; then
|
||||
ipset -N netflix hash:net 2>/dev/null
|
||||
for ip in $(cat "${SHUNT_LIST:=/dev/null}" 2>/dev/null); do ipset -! add netflix "$ip"; done
|
||||
case "$SHUNT_PORT" in
|
||||
0) ;;
|
||||
1)
|
||||
$IPT -I SS_SPEC_WAN_AC -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports "$local_port"
|
||||
;;
|
||||
*)
|
||||
$IPT -I SS_SPEC_WAN_AC -p tcp -m set --match-set netflix dst -j REDIRECT --to-ports "$SHUNT_PORT"
|
||||
if [ "$SHUNT_PROXY" = "1" ]; then
|
||||
$IPT -I SS_SPEC_WAN_AC -p tcp -d "$SHUNT_IP" -j REDIRECT --to-ports "$local_port"
|
||||
else
|
||||
ipset -! add whitelist "$SHUNT_IP"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
return $?
|
||||
}
|
||||
|
||||
@@ -524,6 +562,22 @@ fw_rule_nft() {
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$SHUNT_PORT" != "0" ] && [ -f "$SHUNT_LIST" ]; then
|
||||
case "$SHUNT_PORT" in
|
||||
1)
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac $TCP_EXT_ARGS ip daddr @netflix counter redirect to :$local_port
|
||||
;;
|
||||
*)
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac $TCP_EXT_ARGS ip daddr @netflix counter redirect to :$SHUNT_PORT
|
||||
if [ "$SHUNT_PROXY" = "1" ]; then
|
||||
$NFT add rule inet ss_spec ss_spec_wan_ac $TCP_EXT_ARGS ip daddr $SHUNT_IP counter redirect to :$local_port
|
||||
else
|
||||
[ -n "$SHUNT_IP" ] && $NFT add element inet ss_spec whitelist "{ $SHUNT_IP }" 2>/dev/null
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
return $?
|
||||
}
|
||||
|
||||
@@ -616,7 +670,7 @@ ac_rule_nft() {
|
||||
fi
|
||||
|
||||
# Block UDP port 443 when TPROXY not Enable
|
||||
if [ -z "$TPROXY" ] && [ "$DISABLE_UDP_RULES" != "1" ]; then
|
||||
if [ -z "$TPROXY" ]; then
|
||||
# Add UDP 443 block rule
|
||||
if [ -z "$Interface" ]; then
|
||||
if [ -n "$MATCH_SET" ]; then
|
||||
@@ -663,11 +717,10 @@ ac_rule_nft() {
|
||||
case "$OUTPUT" in
|
||||
1)
|
||||
# Create ss_spec_output tcp chain
|
||||
if ! $NFT list chain inet ss_spec ss_spec_output >/dev/null 2>&1; then
|
||||
$NFT add chain inet ss_spec ss_spec_output '{ type nat hook output priority 0; policy accept; }'
|
||||
fi
|
||||
$NFT flush chain inet ss_spec ss_spec_output 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_output meta mark 255 return 2>/dev/null
|
||||
if ! $NFT list chain inet ss_spec ss_spec_output >/dev/null 2>&1; then
|
||||
$NFT add chain inet ss_spec ss_spec_output '{ type nat hook output priority 0; policy accept; }'
|
||||
fi
|
||||
$NFT flush chain inet ss_spec ss_spec_output 2>/dev/null
|
||||
|
||||
# Exclude special local addresses
|
||||
if $NFT list chain inet ss_spec ss_spec_output >/dev/null 2>&1; then
|
||||
@@ -688,11 +741,10 @@ ac_rule_nft() {
|
||||
;;
|
||||
2)
|
||||
# Create ss_spec_output tcp chain
|
||||
if ! $NFT list chain inet ss_spec ss_spec_output >/dev/null 2>&1; then
|
||||
$NFT add chain inet ss_spec ss_spec_output '{ type nat hook output priority 0; policy accept; }'
|
||||
fi
|
||||
$NFT flush chain inet ss_spec ss_spec_output 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_output meta mark 255 return 2>/dev/null
|
||||
if ! $NFT list chain inet ss_spec ss_spec_output >/dev/null 2>&1; then
|
||||
$NFT add chain inet ss_spec ss_spec_output '{ type nat hook output priority 0; policy accept; }'
|
||||
fi
|
||||
$NFT flush chain inet ss_spec ss_spec_output 2>/dev/null
|
||||
|
||||
# Exclude special local addresses
|
||||
if $NFT list chain inet ss_spec ss_spec_output >/dev/null 2>&1; then
|
||||
@@ -706,12 +758,11 @@ ac_rule_nft() {
|
||||
for ip in $(gen_spec_iplist); do
|
||||
[ -n "$ip" ] && $NFT add element inet ss_spec ssr_gen_router "{ $ip }" 2>/dev/null
|
||||
done
|
||||
if ! $NFT list chain inet ss_spec ss_spec_router >/dev/null 2>&1; then
|
||||
$NFT add chain inet ss_spec ss_spec_router 2>/dev/null
|
||||
fi
|
||||
$NFT flush chain inet ss_spec ss_spec_router 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_router meta mark 255 return 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_router ip daddr @ssr_gen_router return 2>/dev/null
|
||||
if ! $NFT list chain inet ss_spec ss_spec_router >/dev/null 2>&1; then
|
||||
$NFT add chain inet ss_spec ss_spec_router 2>/dev/null
|
||||
fi
|
||||
$NFT flush chain inet ss_spec ss_spec_router 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_router ip daddr @ssr_gen_router return 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_router jump ss_spec_wan_fw 2>/dev/null
|
||||
$NFT add rule inet ss_spec ss_spec_output $TCP_EXT_ARGS jump ss_spec_router comment "\"$TAG\"" 2>/dev/null
|
||||
;;
|
||||
@@ -741,7 +792,7 @@ ac_rule_iptables() {
|
||||
EOF
|
||||
|
||||
# Block UDP port 443 when TPROXY not Enable
|
||||
if [ -z "$TPROXY" ] && [ "$DISABLE_UDP_RULES" != "1" ]; then
|
||||
if [ -z "$TPROXY" ]; then
|
||||
# Add UDP 443 block rule
|
||||
if [ -z "$Interface" ]; then
|
||||
# Global rules
|
||||
@@ -794,11 +845,10 @@ ac_rule_iptables() {
|
||||
create ssr_gen_router hash:net
|
||||
$(gen_spec_iplist | sed -e "s/^/add ssr_gen_router /")
|
||||
EOF
|
||||
$IPT -N SS_SPEC_ROUTER 2>/dev/null
|
||||
$IPT -F SS_SPEC_ROUTER 2>/dev/null
|
||||
$IPT -A SS_SPEC_ROUTER -m mark --mark 255 -j RETURN && \
|
||||
$IPT -A SS_SPEC_ROUTER -m set --match-set ssr_gen_router dst -j RETURN && \
|
||||
$IPT -A SS_SPEC_ROUTER -j SS_SPEC_WAN_FW
|
||||
$IPT -N SS_SPEC_ROUTER 2>/dev/null
|
||||
$IPT -F SS_SPEC_ROUTER 2>/dev/null
|
||||
$IPT -A SS_SPEC_ROUTER -m set --match-set ssr_gen_router dst -j RETURN && \
|
||||
$IPT -A SS_SPEC_ROUTER -j SS_SPEC_WAN_FW
|
||||
$IPT -I OUTPUT 1 -p tcp -m comment --comment "$TAG" -j SS_SPEC_ROUTER
|
||||
;;
|
||||
esac
|
||||
@@ -956,6 +1006,14 @@ tp_rule_nft() {
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp $EXT_ARGS ip daddr @gfwlist counter tproxy ip to :"$LOCAL_PORT" meta mark set ${FWMARK} 2>/dev/null
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp ip saddr @gmlan ip daddr != @china counter tproxy ip to :"$LOCAL_PORT" meta mark set ${FWMARK} 2>/dev/null
|
||||
;;
|
||||
oversea)
|
||||
if ! $NFT list set ip ss_spec_mangle oversea >/dev/null 2>&1; then
|
||||
$NFT add set ip ss_spec_mangle oversea '{ type ipv4_addr; flags interval; auto-merge; }' 2>/dev/null
|
||||
fi
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp $EXT_ARGS ip saddr @oversea counter tproxy ip to :"$LOCAL_PORT" meta mark set ${FWMARK} 2>/dev/null
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp $EXT_ARGS ip daddr @china counter tproxy ip to :"$LOCAL_PORT" meta mark set ${FWMARK} 2>/dev/null
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp ip saddr @gmlan counter tproxy ip to :"$LOCAL_PORT" meta mark set ${FWMARK} 2>/dev/null
|
||||
;;
|
||||
all)
|
||||
$NFT add rule ip ss_spec_mangle ss_spec_tproxy meta l4proto udp $EXT_ARGS counter tproxy ip to :"$LOCAL_PORT" meta mark set ${FWMARK} 2>/dev/null
|
||||
;;
|
||||
@@ -1032,8 +1090,8 @@ tp_rule_iptables() {
|
||||
do
|
||||
$ipt -A SS_SPEC_TPROXY -p udp -d "$net" -j RETURN
|
||||
done
|
||||
[ -n "$SERVER" ] && $ipt -A SS_SPEC_TPROXY -p udp ! --dport 53 -d "$SERVER" -j RETURN
|
||||
[ -n "$SERVER" ] && [ "$server" != "$SERVER" ] && ipset -! add whitelist "$SERVER"
|
||||
$ipt -A SS_SPEC_TPROXY -p udp ! --dport 53 -d "$SERVER" -j RETURN
|
||||
[ "$server" != "$SERVER" ] && ipset -! add whitelist "$SERVER"
|
||||
if [ -f "${xhttp_ip:=/etc/ssrplus/xhttp_address.txt}" ]; then
|
||||
while IFS= read -r ip; do
|
||||
[ -n "$ip" ] && ipset add whitelist "$ip" -exist
|
||||
@@ -1061,6 +1119,11 @@ tp_rule_iptables() {
|
||||
$ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set gfwlist dst -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark ${FWMARK}
|
||||
$ipt -A SS_SPEC_TPROXY -p udp -m set --match-set gmlan src -m set ! --match-set china dst -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark ${FWMARK}
|
||||
;;
|
||||
oversea)
|
||||
$ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set oversea src -m dst -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark ${FWMARK}
|
||||
$ipt -A SS_SPEC_TPROXY -p udp -m set --match-set gmlan src -m set -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark ${FWMARK}
|
||||
$ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -m set --match-set china dst -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark ${FWMARK}
|
||||
;;
|
||||
all)
|
||||
$ipt -A SS_SPEC_TPROXY -p udp $PROXY_PORTS -j TPROXY --on-port "$LOCAL_PORT" --tproxy-mark ${FWMARK}
|
||||
;;
|
||||
@@ -1432,7 +1495,7 @@ restore_from_persistence() {
|
||||
fi
|
||||
}
|
||||
|
||||
while getopts ":m:s:l:S:L:i:e:a:B:b:w:p:G:D:F:N:M:I:oOuUyfgrzAKPCRXh" arg; do
|
||||
while getopts ":m:s:l:S:L:i:e:a:B:b:w:p:G:D:F:N:M:I:oOuUfgrczAKPCRXh" arg; do
|
||||
case "$arg" in
|
||||
m)
|
||||
Interface=$OPTARG
|
||||
@@ -1500,15 +1563,15 @@ while getopts ":m:s:l:S:L:i:e:a:B:b:w:p:G:D:F:N:M:I:oOuUyfgrzAKPCRXh" arg; do
|
||||
U)
|
||||
TPROXY=2
|
||||
;;
|
||||
y)
|
||||
DISABLE_UDP_RULES=1
|
||||
;;
|
||||
g)
|
||||
RUNMODE=gfw
|
||||
;;
|
||||
r)
|
||||
RUNMODE=router
|
||||
;;
|
||||
c)
|
||||
RUNMODE=oversea
|
||||
;;
|
||||
z)
|
||||
RUNMODE=all
|
||||
;;
|
||||
@@ -1640,7 +1703,7 @@ runmode_change() {
|
||||
}
|
||||
|
||||
# Main process
|
||||
if [ -n "$local_port" ]; then
|
||||
if [ -n "$server" ] && [ -n "$local_port" ]; then
|
||||
if ! echo "$local_port" | grep -qE '^[0-9]+$'; then
|
||||
loger 3 "Invalid local port: $local_port"
|
||||
exit 1
|
||||
@@ -1652,6 +1715,7 @@ if [ -n "$local_port" ]; then
|
||||
LOCAL_PORT=$local_port
|
||||
;;
|
||||
2)
|
||||
: ${SERVER:?"You must assign an ip for the udp relay server."}
|
||||
: ${LOCAL_PORT:?"You must assign a port for the udp relay server."}
|
||||
;;
|
||||
esac
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/sh
|
||||
#!/bin/sh /etc/rc.common
|
||||
#
|
||||
# Copyright (C) 2017 openwrt-ssr
|
||||
# Copyright (C) 2017 yushi studio <ywb94@qq.com>
|
||||
@@ -7,276 +7,149 @@
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
ORIG_ARG1="${1:-}"
|
||||
ORIG_ARG2="${2:-}"
|
||||
ORIG_ARG3="${3:-}"
|
||||
[ -f /lib/functions.sh ] && . /lib/functions.sh
|
||||
. $IPKG_INSTROOT/etc/init.d/shadowsocksr
|
||||
LOCK_FILE="/var/lock/ssr-switch.lock"
|
||||
PROBE_SID=""
|
||||
[ -f "$LOCK_FILE" ] && exit 2
|
||||
touch "$LOCK_FILE"
|
||||
LOG_FILE=/var/log/ssrplus.log
|
||||
|
||||
cycle_time=60
|
||||
switch_time=3
|
||||
probe_socks_port=10800
|
||||
direct_fail_count=0
|
||||
direct_fail_limit=3
|
||||
probe_url="$(uci_get_by_type server_subscribe url_test_url)"
|
||||
[ -n "$probe_url" ] || probe_url="https://www.google.com/generate_204"
|
||||
PROBE_INSTANCE_KEY="ssr-switch-probe-local"
|
||||
normal_flag=0
|
||||
server_locate=0
|
||||
server_count=0
|
||||
ENABLE_SERVER=nil
|
||||
[ -n "$1" ] && cycle_time=$1
|
||||
[ -n "$2" ] && switch_time=$2
|
||||
DEFAULT_SERVER=$(uci_get_by_type global global_server)
|
||||
CURRENT_SERVER=$DEFAULT_SERVER
|
||||
|
||||
DEFAULT_SERVER="$(uci_get_by_type global global_server)"
|
||||
CURRENT_SERVER="$DEFAULT_SERVER"
|
||||
ENABLE_SERVER="nil"
|
||||
|
||||
cleanup_probe_socks() {
|
||||
ps_list | grep -v "grep" | grep -E "tcp-http-ssr-switch-local\\.json|ss-${PROBE_INSTANCE_KEY}/config\\.yaml|tuic-${PROBE_INSTANCE_KEY}/config\\.yaml" | awk '{print $1}' | xargs kill >/dev/null 2>&1
|
||||
sleep 1
|
||||
ps_list | grep -v "grep" | grep -E "tcp-http-ssr-switch-local\\.json|ss-${PROBE_INSTANCE_KEY}/config\\.yaml|tuic-${PROBE_INSTANCE_KEY}/config\\.yaml" | awk '{print $1}' | xargs kill -9 >/dev/null 2>&1
|
||||
rm -f "$TMP_PATH/tcp-http-ssr-switch-local.json" 2>/dev/null
|
||||
rm -rf "$TMP_PATH/ss-${PROBE_INSTANCE_KEY}" "$TMP_PATH/tuic-${PROBE_INSTANCE_KEY}" 2>/dev/null
|
||||
rm -f /tmp/ssr-switch-probe.log 2>/dev/null
|
||||
}
|
||||
|
||||
start_probe_socks() {
|
||||
local sid="$1"
|
||||
local server_type
|
||||
|
||||
server_type="$(uci_get_by_name "$sid" type)"
|
||||
[ "$server_type" = "clash" ] && return 1
|
||||
[ "$server_type" = "tuic" ] && return 1
|
||||
[ "$server_type" = "socks5" ] && return 1
|
||||
|
||||
cleanup_probe_socks
|
||||
LOCAL_SERVER="$sid"
|
||||
local_config_file="$TMP_PATH/tcp-http-ssr-switch-local.json"
|
||||
_local="2"
|
||||
local_enable=0
|
||||
tmp_local_port=
|
||||
mode="tcp,udp"
|
||||
|
||||
if [ "$server_type" = "v2ray" ]; then
|
||||
export SSR_SWITCH_PROBE=1
|
||||
gen_config_file "$LOCAL_SERVER" "$server_type" 4 0 "$probe_socks_port" >/tmp/ssr-switch-probe.log 2>&1 || return 1
|
||||
unset SSR_SWITCH_PROBE
|
||||
local xray_bin
|
||||
xray_bin="$(first_type xray)"
|
||||
[ -x "$xray_bin" ] || return 1
|
||||
"$xray_bin" run -c "$local_config_file" >>/tmp/ssr-switch-probe.log 2>&1 &
|
||||
else
|
||||
export SSR_SWITCH_PROBE=1
|
||||
export SSR_SWITCH_PROBE_INSTANCE_KEY="$PROBE_INSTANCE_KEY"
|
||||
start_local_with_port "$probe_socks_port" >/tmp/ssr-switch-probe.log 2>&1 || return 1
|
||||
unset SSR_SWITCH_PROBE_INSTANCE_KEY
|
||||
unset SSR_SWITCH_PROBE
|
||||
fi
|
||||
|
||||
sleep 2
|
||||
return 0
|
||||
}
|
||||
|
||||
probe_http_ok() {
|
||||
case "$1" in
|
||||
[1-5][0-9][0-9])
|
||||
return 0
|
||||
;;
|
||||
esac
|
||||
return 1
|
||||
}
|
||||
|
||||
check_direct_probe() {
|
||||
local code
|
||||
|
||||
code="$(curl -k -sS -L -o /dev/null \
|
||||
--connect-timeout "$switch_time" \
|
||||
--max-time "$switch_time" \
|
||||
-w '%{http_code}' \
|
||||
"$probe_url" 2>/dev/null || true)"
|
||||
probe_http_ok "$code"
|
||||
}
|
||||
|
||||
check_proxy_via_socks() {
|
||||
local try_count
|
||||
local code
|
||||
local proxy_host
|
||||
|
||||
try_count="$(uci_get_by_type global switch_try_count 3)"
|
||||
for i in $(seq 1 "$try_count"); do
|
||||
for proxy_host in "127.0.0.1:$probe_socks_port" "[::1]:$probe_socks_port"; do
|
||||
code="$(curl -k -sS -L -o /dev/null \
|
||||
--connect-timeout "$switch_time" \
|
||||
--max-time "$switch_time" \
|
||||
--socks5-hostname "$proxy_host" \
|
||||
-w '%{http_code}' \
|
||||
"$probe_url" 2>/dev/null || true)"
|
||||
probe_http_ok "$code" && return 0
|
||||
done
|
||||
#判断代理是否正常
|
||||
check_proxy() {
|
||||
local result=0
|
||||
local try_count=$(uci_get_by_type global switch_try_count 3)
|
||||
for i in $(seq 1 $try_count); do
|
||||
/usr/bin/ssr-check www.google.com 80 $switch_time 1
|
||||
if [ "$?" == "0" ]; then
|
||||
# echolog "Check Google Proxy Success, count=$i"
|
||||
result=0
|
||||
break
|
||||
else
|
||||
# echolog "Check Google Proxy Fail, count=$i"
|
||||
/usr/bin/ssr-check www.baidu.com 80 $switch_time 1
|
||||
if [ "$?" == "0" ]; then
|
||||
result=1
|
||||
else
|
||||
result=2
|
||||
fi
|
||||
fi
|
||||
sleep 1
|
||||
done
|
||||
return 1
|
||||
return $result
|
||||
}
|
||||
|
||||
test_proxy() {
|
||||
local sid="$1"
|
||||
[ "$(uci_get_by_name "$sid" type)" = "clash" ] && return 1
|
||||
[ "$(uci_get_by_name "$sid" type)" = "tuic" ] && return 1
|
||||
start_probe_socks "$sid" || {
|
||||
cleanup_probe_socks
|
||||
local servername=$(uci_get_by_name $1 server)
|
||||
local serverport=$(uci_get_by_name $1 server_port)
|
||||
ipset add whitelist $servername 2>/dev/null
|
||||
tcping -q -c 3 -i 1 -t 2 -p $serverport $servername
|
||||
if [ "$?" -gt "0" ]; then
|
||||
ipset del whitelist $servername 2>/dev/null
|
||||
return 1
|
||||
}
|
||||
check_proxy_via_socks
|
||||
fi
|
||||
/usr/bin/ssr-check $servername $serverport $switch_time
|
||||
local ret=$?
|
||||
cleanup_probe_socks
|
||||
return $ret
|
||||
ipset del whitelist $servername 2>/dev/null
|
||||
if [ "$ret" == "0" ]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
search_proxy() {
|
||||
local sid="$1"
|
||||
[ "$(uci_get_by_name "$sid" switch_enable 0)" = "1" ] || return 1
|
||||
[ "$(uci_get_by_name "$sid" type)" = "clash" ] && return 1
|
||||
[ "$(uci_get_by_name "$sid" type)" = "tuic" ] && return 1
|
||||
[ "$sid" = "$CURRENT_SERVER" ] && return 1
|
||||
[ "$ENABLE_SERVER" != "nil" ] && return 0
|
||||
|
||||
if test_proxy "$sid"; then
|
||||
ENABLE_SERVER="$sid"
|
||||
let server_count=server_count+1
|
||||
[ "$normal_flag" == "1" -a "$server_count" -le "$server_locate" ] && return 0
|
||||
[ "$(uci_get_by_name $1 switch_enable 0)" != "1" ] && return 1
|
||||
[ $ENABLE_SERVER != nil ] && return 0
|
||||
[ "$1" == "$CURRENT_SERVER" ] && return 0
|
||||
local servername=$(uci_get_by_name $1 server)
|
||||
local serverport=$(uci_get_by_name $1 server_port)
|
||||
ipset add whitelist $servername 2>/dev/null
|
||||
/usr/bin/ssr-check $servername $serverport $switch_time
|
||||
local ret=$?
|
||||
ipset del whitelist $servername 2>/dev/null
|
||||
if [ "$ret" == "0" ]; then
|
||||
server_locate=$server_count
|
||||
ENABLE_SERVER=$1
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
#选择可用的代理
|
||||
select_proxy() {
|
||||
config_load "$NAME"
|
||||
ENABLE_SERVER="nil"
|
||||
config_load $NAME
|
||||
ENABLE_SERVER=nil
|
||||
mkdir -p /var/run /var/etc
|
||||
server_count=0
|
||||
config_foreach search_proxy servers
|
||||
}
|
||||
|
||||
set_main_server() {
|
||||
local sid="$1"
|
||||
[ -n "$sid" ] || return 1
|
||||
uci set shadowsocksr.@global[0].global_server="$sid"
|
||||
uci commit shadowsocksr
|
||||
return 0
|
||||
}
|
||||
|
||||
#切换代理
|
||||
switch_proxy() {
|
||||
set_main_server "$1" || return 1
|
||||
/etc/init.d/shadowsocksr restart "$1"
|
||||
/etc/init.d/shadowsocksr restart $1
|
||||
return 0
|
||||
}
|
||||
|
||||
start() {
|
||||
while [ "1" = "1" ]; do
|
||||
sleep "0000$cycle_time"
|
||||
run_once
|
||||
#不支持kcptun启用时的切换
|
||||
[ $(uci_get_by_name $DEFAULT_SERVER kcp_enable) = "1" ] && return 1
|
||||
while [ "1" == "1" ]; do #死循环
|
||||
sleep 0000$cycle_time
|
||||
LOGTIME=$(date "+%Y-%m-%d %H:%M:%S")
|
||||
#判断当前代理是否为缺省服务器
|
||||
if [ "$CURRENT_SERVER" != "$DEFAULT_SERVER" ]; then
|
||||
#echo "not default proxy"
|
||||
echolog "Current server is not default Main server, try to switch back."
|
||||
#检查缺省服务器是否正常
|
||||
if test_proxy $DEFAULT_SERVER; then
|
||||
#echo "switch to default proxy"
|
||||
echolog "Main server is avilable."
|
||||
#缺省服务器正常,切换回来
|
||||
CURRENT_SERVER=$DEFAULT_SERVER
|
||||
switch_proxy $CURRENT_SERVER
|
||||
echolog "switch to default "$(uci_get_by_name $CURRENT_SERVER alias)" proxy!"
|
||||
else
|
||||
echolog "Main server is NOT avilable.Continue using current server."
|
||||
fi
|
||||
fi
|
||||
#判断当前代理是否正常
|
||||
#echolog "Start checking if the current server is available."
|
||||
check_proxy
|
||||
current_ret=$?
|
||||
if [ "$current_ret" == "1" ]; then
|
||||
#当前代理错误,判断有无可用的服务器
|
||||
#echo "current error"
|
||||
echolog "Current server error, try to switch another server."
|
||||
select_proxy
|
||||
if [ "$ENABLE_SERVER" != nil ]; then
|
||||
#有其他服务器可用,进行切换
|
||||
#echo $(uci_get_by_name $new_proxy server)
|
||||
echolog "Another server is avilable, now switching server."
|
||||
CURRENT_SERVER=$ENABLE_SERVER
|
||||
switch_proxy $CURRENT_SERVER
|
||||
normal_flag=1
|
||||
echolog "Switch to "$(uci_get_by_name $CURRENT_SERVER alias)" proxy!"
|
||||
else
|
||||
switch_proxy $CURRENT_SERVER
|
||||
normal_flag=1
|
||||
echolog "Try restart current server."
|
||||
fi
|
||||
else
|
||||
normal_flag=0
|
||||
# echolog "ShadowsocksR No Problem."
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
run_once() {
|
||||
DEFAULT_SERVER="$(uci_get_by_type global global_server)"
|
||||
[ "$DEFAULT_SERVER" = "nil" ] && {
|
||||
direct_fail_count=0
|
||||
return 0
|
||||
}
|
||||
[ "$(uci_get_by_name "$DEFAULT_SERVER" type)" = "clash" ] && {
|
||||
direct_fail_count=0
|
||||
cleanup_probe_socks
|
||||
return 0
|
||||
}
|
||||
[ "$(uci_get_by_name "$DEFAULT_SERVER" type)" = "tuic" ] && {
|
||||
direct_fail_count=0
|
||||
cleanup_probe_socks
|
||||
return 0
|
||||
}
|
||||
[ "$(uci_get_by_name "$DEFAULT_SERVER" kcp_enable 0)" = "1" ] && {
|
||||
direct_fail_count=0
|
||||
cleanup_probe_socks
|
||||
return 1
|
||||
}
|
||||
|
||||
CURRENT_SERVER="$DEFAULT_SERVER"
|
||||
|
||||
if check_direct_probe; then
|
||||
direct_fail_count=0
|
||||
return 0
|
||||
fi
|
||||
|
||||
direct_fail_count=$((direct_fail_count + 1))
|
||||
[ "$direct_fail_count" -lt "$direct_fail_limit" ] && return 0
|
||||
direct_fail_count=0
|
||||
|
||||
if test_proxy "$CURRENT_SERVER"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
echolog "Current server error, try to switch another server."
|
||||
select_proxy
|
||||
if [ "$ENABLE_SERVER" != "nil" ]; then
|
||||
CURRENT_SERVER="$ENABLE_SERVER"
|
||||
switch_proxy "$CURRENT_SERVER"
|
||||
echolog "Switch to $(uci_get_by_name "$CURRENT_SERVER" alias) proxy!"
|
||||
else
|
||||
switch_proxy "$CURRENT_SERVER"
|
||||
echolog "Try restart current server."
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
probe_once() {
|
||||
local sid="$1"
|
||||
[ -n "$sid" ] || {
|
||||
echo "missing_sid"
|
||||
return 1
|
||||
}
|
||||
cleanup_probe_socks
|
||||
if ! start_probe_socks "$sid"; then
|
||||
echo "probe_start:fail"
|
||||
return 1
|
||||
fi
|
||||
echo "probe_start:ok"
|
||||
echo "probe:curl_ipv4"
|
||||
curl -k -sS -L -o /dev/null \
|
||||
--connect-timeout "$switch_time" \
|
||||
--max-time "$switch_time" \
|
||||
--socks5-hostname "127.0.0.1:$probe_socks_port" \
|
||||
-w 'code=%{http_code}\n' \
|
||||
"$probe_url" 2>/dev/null || true
|
||||
echo "probe:curl_ipv6"
|
||||
curl -g -k -sS -L -o /dev/null \
|
||||
--connect-timeout "$switch_time" \
|
||||
--max-time "$switch_time" \
|
||||
--socks5-hostname "[::1]:$probe_socks_port" \
|
||||
-w 'code=%{http_code}\n' \
|
||||
"$probe_url" 2>/dev/null || true
|
||||
cleanup_probe_socks
|
||||
return 0
|
||||
}
|
||||
|
||||
main() {
|
||||
case "${ORIG_ARG1:-}" in
|
||||
probe)
|
||||
PROBE_SID="${ORIG_ARG2:-}"
|
||||
probe_once "$PROBE_SID"
|
||||
;;
|
||||
once)
|
||||
run_once
|
||||
;;
|
||||
start)
|
||||
[ -n "$ORIG_ARG2" ] && cycle_time="$ORIG_ARG2"
|
||||
[ -n "$ORIG_ARG3" ] && switch_time="$ORIG_ARG3"
|
||||
[ -f "$LOCK_FILE" ] && exit 2
|
||||
touch "$LOCK_FILE"
|
||||
start
|
||||
;;
|
||||
*)
|
||||
[ -n "$ORIG_ARG1" ] && cycle_time="$ORIG_ARG1"
|
||||
[ -n "$ORIG_ARG2" ] && switch_time="$ORIG_ARG2"
|
||||
[ -f "$LOCK_FILE" ] && exit 2
|
||||
touch "$LOCK_FILE"
|
||||
start
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
if [ "${0##*/}" = "ssr-switch" ]; then
|
||||
main "$@"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user