-
Notifications
You must be signed in to change notification settings - Fork 890
/
Copy pathkeep.sh
230 lines (200 loc) · 9.61 KB
/
keep.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
#!/bin/bash
# 此版本无哪吒,只保活节点,将此文件放到vps,填写以下服务器配置后bash keep.sh运行即可
# 如果需要在青龙面板运行,注释或删除此文件里的35至74行,保留中间的第56行
# Telegram消息提醒配置(可选,不需要留空即可)
TG_CHAT_ID="12345678" # 替换为你的TG chat_id
TG_BOT_TOKEN="" # 替换为你的TG机器人token
# 以下配置不需要可以留空或保持默认
export UUID=${UUID:-'bc97f674-c578-4940-9234-0a1da46041b0'} # UUID
export CFIP=${CFIP:-'www.visa.com.tw'} # 优选域名或优选ip
export CFPORT=${CFIPPORT:-'443'} # 优选域名或优选ip对应端口
export SUB_TOKEN=${SUB_TOKEN:-'sub'} # 订阅token
# serv00或ct8服务器及端口配置,请按照以下格式填写,每个变量之间用英文输入法状态下冒号分隔
declare -A servers=( # 账号:密码:tcp端口:udp1端口:udp2端口:argo域名:Argo隧道json或token
["s0.serv00.com"]='abcd:abd12345678:1234:2345:3455:s0.2go.com:{"AccountTag":"8b9724080e55e70370fb74287922f31b","TunnelSecret":"C+OA5/LjJz9UHZ0vOkCC5PVRkvXiPhrWNcnxJBrfTPc=","TunnelID":"28125b91-34309-44d2-94be-b5e718944dad"}'
["s1.serv00.com"]='abcd:dbc12345678:1234:2345:3455:s1.2go.com:{"AccountTag":"8b9724080e55e70370fb74287922f31b","TunnelSecret":"C+OA5/LjJz9UHZ0vOkCC5PVRkvXiPhrWNcnxJBrfTPc=","TunnelID":"28125b91-34309-44d2-94be-b5e718944dad"}'
["s2.serv00.com"]='abcd:avd12345678:1234:2345:3455:s2.2go.com:{"AccountTag":"8b9724080e55e70370fb74287922f31b","TunnelSecret":"C+OA5/LjJz9UHZ0vOkCC5PVRkvXiPhrWNcnxJBrfTPc=","TunnelID":"28125b91-34309-44d2-94be-b5e718944dad"}'
["s3.serv00.com"]='abcd:dss12345678:1234:2345:3455:s3.2go.com:{"AccountTag":"8b9724080e55e70370fb74287922f31b","TunnelSecret":"C+OA5/LjJz9UHZ0vOkCC5PfRkvXiPhrWNcnxJBrfTPc=","TunnelID":"28125b91-34309-44d2-94be-b5e718944dad"}'
["s4.serv00.com"]='abcd:sds12345678:1234:2345:3455:s4.2go.com:{"AccountTag":"8b9724080e55e70370fb74287922f31b","TunnelSecret":"C+OA5/LjJz9UHZ0vOkCC5PVRkvXiPhrWNcnxJBrfTPc=","TunnelID":"28125b91-34309-44d2-94be-b5e718944dad"}'
["s5.serv00.com"]='abcd:dsd12345678:1234:2345:3455:s5.2go.com:{"AccountTag":"8b9724080e55e70370fb74287922f31b","TunnelSecret":"C+OA5/LjJz9UHZ0vOkCC5PVRkvXiPhrWNcnxJBrfTPc=","TunnelID":"28125b91-34309-44d2-94be-b5e718944dad"}'
["s6.serv00.com"]='abcd:dsd12345678:1234:2345:3455:s6.2go.com:{"AccountTag":"8b9724080e55e70370fb74287922f31b","TunnelSecret":"C+OA5/LjJz9UHZ0vOkCC5PVRkvXiPhrWNcnxJBrfTPc=","TunnelID":"28125b91-34309-44d2-94be-b5e718944dad"}'
["s7.serv00.com"]='abcd:dsd12345678:1234:2345:3455:s7.2go.com:{"AccountTag":"8b9724080e55e70370fb74287922f31b","TunnelSecret":"C+OA5/LjJz9UHZ0vOkCC5PVRkvXiPhrWNcnxJBrfTPc=","TunnelID":"28125b91-34309-44d2-94be-b5e718944dad"}'
["s8.serv00.com"]='abcd:dss12345678:1234:2345:3455:s8.2go.com:{"AccountTag":"8b9724080e55e70370fb74287922f31b","TunnelSecret":"C+OA5/LjJz9UHZ0vOkCC5PVRkvXiPhrWNcnxJBrfTPc=","TunnelID":"28125b91-34309-44d2-94be-b5e718944dad"}'
# 添加更多服务器......
)
# 定义颜色
red() { echo -e "\e[1;91m$1\033[0m"; }
green() { echo -e "\e[1;32m$1\033[0m"; }
yellow() { echo -e "\e[1;33m$1\033[0m"; }
purple() { echo -e "\e[1;35m$1\033[0m"; }
export TERM=xterm
export DEBIAN_FRONTEND=noninteractive
install_packages() {
if [ -f /etc/debian_version ]; then
package_manager="apt-get install -y"
elif [ -f /etc/redhat-release ]; then
package_manager="yum install -y"
elif [ -f /etc/fedora-release ]; then
package_manager="dnf install -y"
elif [ -f /etc/alpine-release ]; then
package_manager="apk add"
else
red "不支持的系统架构!"
exit 1
fi
$package_manager sshpass curl netcat-openbsd jq cron >/dev/null 2>&1 &
}
install_packages
clear
# 结束上一次运行的残留进程(排除当前进程)
bash -c 'ps aux | grep -E "/bin/bash /root/keep.sh|sshpass|ssh|curl" | grep -v "pts/" | awk "\$2 != \"'$$'\" {print \$2}" | xargs kill -9 > /dev/null 2>&1' >/dev/null 2>&1 &
# 添加定时任务
add_cron_job() {
if [ -f /etc/alpine-release ]; then
if ! command -v crond >/dev/null 2>&1; then
apk add --no-cache cronie bash >/dev/null 2>&1 &
rc-update add crond && rc-service crond start
fi
fi
# 检查定时任务是否已经存在
if ! crontab -l 2>/dev/null | grep -q "$SCRIPT_PATH"; then
(crontab -l 2>/dev/null; echo "*/2 * * * * /bin/bash $SCRIPT_PATH >> /root/keep_00.log 2>&1") | crontab -
green "已添加计划任务,每两分钟执行一次"
else
purple "计划任务已存在,跳过添加计划任务"
fi
}
add_cron_job
# 检查 TCP 端口是否通畅
check_tcp_port() {
local host=$1
local port=$2
nc -z -w 3 "$host" "$port" &> /dev/null
return $?
}
# 检查 Argo 隧道是否在线
check_argo_tunnel() {
local argo_domain=$1
if [ -z "$argo_domain" ]; then
return 1
else
http_code=$(curl -o /dev/null -s -w "%{http_code}\n" "https://$argo_domain")
if [ "$http_code" -eq 404 ]; then
return 0
else
return 1
fi
fi
}
# 发送提醒消息到TG
send_telegram_message() {
local message="$1"
if [ -n "$TG_BOT_TOKEN" ] && [ -n "$TG_CHAT_ID" ]; then
curl -s -X POST "https://api.telegram.org/bot$TG_BOT_TOKEN/sendMessage" \
-d "chat_id=$TG_CHAT_ID" \
-d "text=$message" \
-d "parse_mode=HTML" > /dev/null
fi
}
# 执行远程命令
run_remote_command() {
local host=$1
local ssh_user=$2
local ssh_pass=$3
local tcp_port=$4
local udp1_port=$5
local udp2_port=$6
local argo_domain=${7}
local argo_auth=${8}
remote_command="SUB_TOKEN=$SUB_TOKEN UUID=$UUID ARGO_DOMAIN=$argo_domain ARGO_AUTH='$argo_auth' CFIP=$CFIP CFPORT=$CFPORT bash <(curl -Ls https://raw.githubusercontent.com/eooce/sing-box/main/sb_00.sh)"
sshpass -p "$ssh_pass" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=60 "$ssh_user@$host" "$remote_command"
}
# 如果3次检测失败,发送消息到TG,连接 SSH 并执行远程命令
connect_ssh() {
if [ $tcp_attempt -ge 3 ] || [ $argo_attempt -ge 3 ]; then
local alert_message="⚠️ Serv00异常警报
📅 时间: $time
👤 账户: $ssh_user
🖥️ 服务器: $host"
if [ $tcp_attempt -ge 3 ]; then
alert_message="$alert_message
❌ 检测到TCP端口 $tcp_port 不通"
fi
if [ $argo_attempt -ge 3 ]; then
alert_message="$alert_message
❌ 检测到Argo隧道 $argo_domain 离线"
fi
# 发送告警消息
send_telegram_message "$alert_message"
yellow "$time 多次检测失败,尝试通过SSH连接并远程执行命令 服务器: $host 账户: $ssh_user"
ssh_output=$(sshpass -p "$ssh_pass" ssh -o StrictHostKeyChecking=no -o ConnectTimeout=60 "$ssh_user@$host" -q exit 2>&1)
# 检查账户是否被封
if echo "$ssh_output" | grep -q "HAS BEEN BLOCKED"; then
red "$time 账户已被封禁 服务器: $host 账户: $ssh_user"
# 发送账户封禁提醒
send_telegram_message "🚫 账户已被封锁
👤 账户: $ssh_user
🖥️ 服务器: $host
⚠️ 请尽快移除keep文件中封禁的账户"
return 0
fi
# 检查 SSH 连接是否成功
if [ $? -eq 0 ]; then
green "$time SSH远程连接成功 服务器: $host 账户 : $ssh_user"
output=$(run_remote_command "$host" "$ssh_user" "$ssh_pass" "$tcp_port" "$udp1_port" "$udp2_port" "$argo_domain" "$argo_auth")
yellow "远程命令执行结果:\n"
echo "$output"
# 发送服务恢复消息
send_telegram_message "✅ Serv00服务已恢复
👤 账户: $ssh_user
🖥️ 服务器: $host
📡 节点订阅:
V2rayN: https://$ssh_user.serv00.net/${SUB_TOKEN}_v2.log
Clash: https://$ssh_user.serv00.net/get_sub.php?file=${SUB_TOKEN}_clash.yaml
Sing-box: https://$ssh_user.serv00.net/get_sub.php?file=${SUB_TOKEN}_singbox.yaml"
return 0
else
red "$time 连接失败,请检查你的账户密码 服务器: $host 账户: $ssh_user"
# 发送失败通知
send_telegram_message "❌ SSH连接失败
👤 账户: $ssh_user
🖥️ 服务器: $host
⚠️ 请检查你的账户密码"
return 0
fi
fi
}
# 循环遍历服务器列表检测
for host in "${!servers[@]}"; do
IFS=':' read -r ssh_user ssh_pass tcp_port udp1_port udp2_port argo_domain argo_auth <<< "${servers[$host]}"
tcp_attempt=0
argo_attempt=0
max_attempts=3
time=$(TZ="Asia/Hong_Kong" date +"%Y-%m-%d %H:%M")
# 检查 TCP 端口
while [ $tcp_attempt -lt $max_attempts ]; do
if check_tcp_port "$host" "$tcp_port"; then
green "$time TCP端口${tcp_port}通畅 服务器: $host 账户: $ssh_user"
tcp_attempt=0
break
else
red "$time TCP端口${tcp_port}不通 服务器: $host 账户: $ssh_user"
sleep 5
tcp_attempt=$((tcp_attempt+1))
connect_ssh
fi
done
# # 检查 Argo 隧道
while [ $argo_attempt -lt $max_attempts ]; do
if check_argo_tunnel "$argo_domain"; then
green "$time Argo 隧道在线 Argo域名: $argo_domain 账户: $ssh_user\n"
argo_attempt=0
break
else
red "$time Argo 隧道离线 Argo域名: $argo_domain 账户: $ssh_user"
sleep 5
argo_attempt=$((argo_attempt+1))
connect_ssh
fi
done
done