前几天通过ProxySite 免费网络代理注册了个serv00
安装了Sing-box, 发现进程总是被kill掉
下面两个保活脚本是在linuxdo上找到的, 忘了哪个帖子了
脚本是青龙面板运行的, 我的青龙面板装在机顶盒刷的armbian里面, 无法访问浏览器, 所以就不放serv00的ip解禁脚本了
1. web面板登录脚本 (青龙面板)
首先是web面板的登录py脚本, 记得安装依赖模块, 我设置的cron是0 0 9 ? * 1
serv00_web_login.log日志文件需要先touch
脚本文件名: serv00_web_login.py
# -*- coding: utf-8 -*-
import os
import sys
import requests
import mechanize
from html.parser import HTMLParser
import logging
from datetime import datetime
class MyHTMLParser(HTMLParser):
def __init__(self, username):
super().__init__()
self.username = username
self.success = False
def handle_data(self, data):
if f'Zalogowany jako: {self.username}' in data:
self.success = True
# Use os.path.expanduser to expand the path
log_file_path = os.path.expanduser('../files/serv00_web_login.log')
# Configure logging
logging.basicConfig(
filename=log_file_path,
level=logging.INFO,
format='%(asctime)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
# List of accounts with their respective details
accounts = [
{'name': 'serv00', 'username': '你的账户', 'password': '你的密码', 'url': '你的web面板登录地址比如https://panel8.serv00.com/login/'}
]
# 创建一个浏览器对象
br = mechanize.Browser()
br.set_handle_robots(False) # 忽略 robots.txt
# 设置 User-Agent 头部
br.addheaders = [('User-Agent', 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36')]
# Flag to track overall success
all_successful = True
logging.info("开始尝试登录...")
# Iterate over each account
for account in accounts:
logging.info(f"{account['name']}尝试登录")
try:
# Open the login page
response = br.open(account['url'])
# Select the login form
br.select_form(nr=1)
# Fill in the form
br['username'] = account['username']
br['password'] = account['password']
# Submit the form
response = br.submit()
# Use the custom HTML parser to verify login success
parser = MyHTMLParser(account['username'])
parser.feed(response.read().decode())
if parser.success:
logging.info(f"{account['name']}登录成功")
else:
logging.error(f"{account['name']}登录失败")
all_successful = False # Set the flag to False if any login fails
except Exception as e:
logging.error(f"{account['name']}登录失败报错: {e}")
all_successful = False # Set the flag to False if an exception occurs
# Exit with 0 if all logins were successful, otherwise exit with 1
if all_successful:
logging.info("Serv00网页登录成功")
requests.get("这里可以放bark通知url")
sys.exit(0)
else:
logging.error("Serv00网页登录失败")
requests.get("这里可以放bark通知url")
sys.exit(1)
2. ssh登录脚本 (青龙面板)
ssh登录脚本中会执行一个Sing-box的安装脚本(第3个脚本), 记得修改当前脚本中的路径
这里我设置的cron是0 0 */1 * * ?
脚本文件名: serv00_ssh_login.py
#!/bin/bash
# 运行此脚本青龙面板要安装Linux下的sshpass和jq依赖
echo "开始执行任务..."
# 设置 SSH 超时(单位:秒)
SSH_TIMEOUT=15
Serv00_username_1="你的账户"
Serv00_password_1="你的密码"
Serv00_host_1="你的主机地址"
# Bark 通知相关配置
BARK_URL="你的bark通知url"
BARK_GROUP="Alive"
BARK_TITLE="Serv00"
BARK_ICON="https://kechang.uk/pic/kechang_icon_round.png"
# 定义账号、密码和主机信息数组,每个元素包含 "账号:密码:主机",主机就是s*.serv00.com,一行一组(不需要,号)
CREDENTIALS=(
"$Serv00_username_1:$Serv00_password_1:$Serv00_host_1"
)
# 函数: 发送 Bark 推送通知
send_bark_notification() {
local title="$1"
local message="$2"
local encoded_title=$(echo -n "$title" | jq -sRr @uri)
local encoded_message=$(echo -e "$message" | jq -sRr @uri)
local notification_url="$BARK_URL/$encoded_title/$encoded_message?group=$BARK_GROUP&icon=$(echo -n "$BARK_ICON" | jq -sRr @uri)"
curl -s -X GET "$notification_url" > /dev/null
}
# 定义一个数组来存储输出和错误信息
declare -A OUTPUTS
# 用于标记是否有命令失败
has_error=false
# 用于存储成功的命令
successful_commands=()
# 用于存储失败的命令
failed_commands=()
# 循环遍历每行并执行命令
for cred in "${CREDENTIALS[@]}"; do
IFS=':' read -r user pass host <<< "$cred"
if [ -z "$user" ]; then
continue
fi
# 在远程服务器上执行指定的命令
OUTPUTS["$user"]=$(sshpass -p "$pass" ssh -q -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=$SSH_TIMEOUT -t $user@$host "bash /home/你的用户名/start.sh" 2>&1)
if [ $? -ne 0 ];then
echo "执行命令失败: $user: ${OUTPUTS["$user"]}"
has_error=true
failed_commands+=("$user")
else
successful_commands+=("$user")
fi
done
# 构建消息内容
MESSAGE=""
# 添加成功的命令到消息
if [ ${#successful_commands[@]} -gt 0 ]; then
MESSAGE+="保号成功:\\n"
for user in "${successful_commands[@]}"; do
MESSAGE+="$user\\n"
done
fi
# 添加失败的命令到消息
if [ ${#failed_commands[@]} -gt 0 ]; then
MESSAGE+="以下出错了😭:\\n"
for user in "${failed_commands[@]}"; do
MESSAGE+="$user\\n"
done
fi
# 输出最终结果
if [ "$has_error" = true ]; then
echo "请检查输入是否正确,或是否在 https://www.serv00.com/ip_unban/ 解锁了IP"
else
echo "任务执行完成"
fi
MESSAGE+="All done."
echo $MESSAGE
# send_bark_notification "$BARK_TITLE" "$MESSAGE"
# 这里我设置的cron是 0 0/30 * * * ? 执行太频繁了, 所以把bark通知注释掉了
3. sing-box安装脚本 (Serv00)
下面这个sh脚本是修改了Sing-box的一键四协议安装脚本, 去掉了哪吒探针和ARGO, 执行即安装, 放在/home/你的用户名/
目录下
需要在web面板开放一个55501的tcp端口, 55502的udp端口, 55503的udp端口(可以自定义, 下面脚本中对应修改就行)
脚本文件名: start.sh
#!/bin/bash
re="\033[0m"
red="\033[1;91m"
green="\e[1;32m"
yellow="\e[1;33m"
purple="\e[1;35m"
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"; }
reading() { read -p "$(red "$1")" "$2"; }
export LC_ALL=C
USERNAME="你的用户名"
HOSTNAME=$(hostname)
export UUID=${UUID:-'bc97f674-c578-4940-9234-0a1da46041b9'}
[[ "$HOSTNAME" == "s1.ct8.pl" ]] && WORKDIR="domains/${USERNAME}.ct8.pl/logs" || WORKDIR="domains/${USERNAME}.serv00.net/logs"
[ -d "$WORKDIR" ] || (mkdir -p "$WORKDIR" && chmod 777 "$WORKDIR")
install_singbox() {
cd $WORKDIR
generate_config
download_singbox
get_links
}
# Generating Configuration Files
generate_config() {
openssl ecparam -genkey -name prime256v1 -out "private.key"
openssl req -new -x509 -days 3650 -key "private.key" -out "cert.pem" -subj "/CN=$USERNAME.serv00.net"
cat >config.json <<EOF
{
"log": {
"disabled": true,
"level": "info",
"timestamp": true
},
"dns": {
"servers": [
{
"tag": "google",
"address": "tls://8.8.8.8",
"strategy": "ipv4_only",
"detour": "direct"
}
],
"rules": [
{
"rule_set": [
"geosite-openai"
],
"server": "wireguard"
},
{
"rule_set": [
"geosite-netflix"
],
"server": "wireguard"
},
{
"rule_set": [
"geosite-category-ads-all"
],
"server": "block"
}
],
"final": "google",
"strategy": "",
"disable_cache": false,
"disable_expire": false
},
"inbounds": [
{
"tag": "vmess-ws-in",
"type": "vmess",
"listen": "::",
"listen_port": 55501,
"users": [
{
"uuid": "$UUID"
}
],
"transport": {
"type": "ws",
"path": "/vmess",
"early_data_header_name": "Sec-WebSocket-Protocol"
}
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct"
},
{
"type": "block",
"tag": "block"
},
{
"type": "dns",
"tag": "dns-out"
},
{
"type": "wireguard",
"tag": "wireguard-out",
"server": "162.159.195.100",
"server_port": 4500,
"local_address": [
"172.16.0.2/32",
"2606:4700:110:83c7:b31f:5858:b3a8:c6b1/128"
],
"private_key": "mPZo+V9qlrMGCZ7+E6z2NI6NOV34PD++TpAR09PtCWI=",
"peer_public_key": "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=",
"reserved": [
26,
21,
228
]
}
],
"route": {
"rules": [
{
"protocol": "dns",
"outbound": "dns-out"
},
{
"ip_is_private": true,
"outbound": "direct"
},
{
"rule_set": [
"geosite-openai"
],
"outbound": "wireguard-out"
},
{
"rule_set": [
"geosite-netflix"
],
"outbound": "wireguard-out"
},
{
"rule_set": [
"geosite-category-ads-all"
],
"outbound": "block"
}
],
"rule_set": [
{
"tag": "geosite-netflix",
"type": "remote",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-netflix.srs",
"download_detour": "direct"
},
{
"tag": "geosite-openai",
"type": "remote",
"format": "binary",
"url": "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/openai.srs",
"download_detour": "direct"
},
{
"tag": "geosite-category-ads-all",
"type": "remote",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-category-ads-all.srs",
"download_detour": "direct"
}
],
"final": "direct"
},
"experimental": {
"cache_file": {
"path": "cache.db",
"cache_id": "mycacheid",
"store_fakeip": true
}
}
}
EOF
}
# Download Dependency Files
download_singbox() {
ARCH=$(uname -m) && DOWNLOAD_DIR="." && mkdir -p "$DOWNLOAD_DIR" && FILE_INFO=()
if [ "$ARCH" == "arm" ] || [ "$ARCH" == "arm64" ] || [ "$ARCH" == "aarch64" ]; then
FILE_INFO=("https://github.com/eooce/test/releases/download/arm64/sb web" "https://github.com/eooce/test/releases/download/ARM/swith npm")
elif [ "$ARCH" == "amd64" ] || [ "$ARCH" == "x86_64" ] || [ "$ARCH" == "x86" ]; then
FILE_INFO=("https://eooce.2go.us.kg/web web" "https://eooce.2go.us.kg/npm npm")
else
echo "Unsupported architecture: $ARCH"
exit 1
fi
declare -A FILE_MAP
generate_random_name() {
local chars=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
local name=""
for i in {1..6}; do
name="$name${chars:RANDOM%${#chars}:1}"
done
echo "$name"
}
for entry in "${FILE_INFO[@]}"; do
URL=$(echo "$entry" | cut -d ' ' -f 1)
RANDOM_NAME=$(generate_random_name)
NEW_FILENAME="$DOWNLOAD_DIR/$RANDOM_NAME"
if [ -e "$NEW_FILENAME" ]; then
green "$NEW_FILENAME already exists, Skipping download"
else
curl -L -sS -o "$NEW_FILENAME" "$URL"
green "Downloading $NEW_FILENAME"
fi
chmod +x "$NEW_FILENAME"
FILE_MAP[$(echo "$entry" | cut -d ' ' -f 2)]="$NEW_FILENAME"
done
wait
if [ -e "${FILE_MAP[web]}" ]; then
nohup ./"${FILE_MAP[web]}" run -c config.json >/dev/null 2>&1 &
sleep 2
pgrep -x "$(basename ${FILE_MAP[web]})" > /dev/null && green "$(basename ${FILE_MAP[web]}) is running" || { red "$(basename ${FILE_MAP[web]}) is not running, restarting..."; pkill -x "$(basename ${FILE_MAP[web]})" && nohup ./"${FILE_MAP[web]}" run -c config.json >/dev/null 2>&1 & sleep 2; purple "$(basename ${FILE_MAP[web]}) restarted"; }
fi
sleep 5
rm -f "$(basename ${FILE_MAP[npm]})" "$(basename ${FILE_MAP[web]})"
}
get_ip() {
ip=$(curl -s --max-time 2 ipv4.ip.sb)
if [ -z "$ip" ]; then
if [[ "$HOSTNAME" =~ s[0-9]\.serv00\.com ]]; then
ip=${HOSTNAME/s/web}
else
ip="$HOSTNAME"
fi
fi
echo $ip
}
get_links() {
sleep 1
# get ip
IP=$(get_ip)
# get ipinfo
ISP=$(curl -s https://speed.cloudflare.com/meta | awk -F\" '{print $26"-"$18}' | sed -e 's/ /_/g')
sleep 1
# yellow "注意:v2ray或其他软件的跳过证书验证需设置为true,否则hy2或tuic节点可能不通\n"
cat >list.txt <<EOF
vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$ISP\", \"add\": \"$IP\", \"port\": \"55501\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"none\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"\", \"path\": \"/vmess?ed=2048\", \"tls\": \"\", \"sni\": \"\", \"alpn\": \"\", \"fp\": \"\"}" | base64 -w0)
EOF
cat list.txt
purple "\n$WORKDIR/list.txt saved successfully"
purple "Running done!"
sleep 2
rm -rf boot.log config.json sb.log core tunnel.yml tunnel.json fake_useragent_0.2.0.json
}
# Restart web, and bot processes
kill_serv() {
# 获取进程的PID
PID=$(ps aux | grep "run -c config.json" | grep -v "grep" | awk '{print \$2}')
# 检查是否获取到PID
if [ -z "$PID" ]; then
echo "No web process found."
else
# 杀掉进程
echo "$PID" | xargs kill -9
echo "Killed processes: $PID."
fi
}
#主菜单
menu() {
kill_serv
sleep 5
green "install sing-box..."
install_singbox
}
menu
祝大家玩的愉快!