#!/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 export UUID=${UUID:-''} export ARGO_DOMAIN=${ARGO_DOMAIN:-''} export ARGO_AUTH=${ARGO_AUTH:-''} export vless_port=${vless_port:-''} export vmess_port=${vmess_port:-''} export hy2_port=${hy2_port:-''} export IP=${IP:-''} export reym=${reym:-''} export reset=${reset:-''} if [[ "$reset" =~ ^[Yy]$ ]]; then crontab -l | grep -v "serv00keep" >rmcron crontab rmcron >/dev/null 2>&1 rm rmcron ps aux | grep $(whoami) | grep -v "sshd\|bash\|grep" | awk '{print $2}' | xargs -r kill -9 > /dev/null 2>&1 find ~ -type f -exec chmod 644 {} \; 2>/dev/null find ~ -type d -exec chmod 755 {} \; 2>/dev/null find ~ -type f -exec rm -f {} \; 2>/dev/null find ~ -type d -empty -exec rmdir {} \; 2>/dev/null find ~ -exec rm -rf {} \; 2>/dev/null echo "重置系统完成" fi sleep 2 USERNAME=$(whoami) HOSTNAME=$(hostname) [[ "$HOSTNAME" == "s1.ct8.pl" ]] && export WORKDIR="domains/${USERNAME}.ct8.pl/logs" || export WORKDIR="domains/${USERNAME}.serv00.net/logs" [ -d "$WORKDIR" ] || (mkdir -p "$WORKDIR" && chmod 777 "$WORKDIR") read_ip(){ nb=$(echo "$HOSTNAME" | cut -d '.' -f 1 | tr -d 's') ym=("$HOSTNAME" "cache$nb.serv00.com" "web$nb.serv00.com") rm -rf ip.txt for ym in "${ym[@]}"; do # 引用frankiejun API response=$(curl -s "https://ss.botai.us.kg/api/getip?host=$ym") if [[ -z "$response" ]]; then for ip in "${ym[@]}"; do dig @8.8.8.8 +time=2 +short $ip >> ip.txt sleep 1 done break else echo "$response" | while IFS='|' read -r ip status; do if [[ $status == "Accessible" ]]; then echo "$ip: 可用" >> ip.txt else echo "$ip: 被墙 (Argo与CDN回源节点、proxyip依旧有效)" >> ip.txt fi done fi done if [[ -z "$IP" ]]; then IP=$(grep -m 1 "可用" ip.txt | awk -F ':' '{print $1}') if [ -z "$IP" ]; then IP=$(okip) if [ -z "$IP" ]; then IP=$(head -n 1 ip.txt | awk -F ':' '{print $1}') fi fi fi } okip(){ IP_LIST=($(devil vhost list | awk '/^[0-9]+/ {print $1}')) API_URL="https://status.eooce.com/api" IP="" THIRD_IP=${IP_LIST[2]} RESPONSE=$(curl -s --max-time 2 "${API_URL}/${THIRD_IP}") if [[ $(echo "$RESPONSE" | jq -r '.status') == "Available" ]]; then IP=$THIRD_IP else FIRST_IP=${IP_LIST[0]} RESPONSE=$(curl -s --max-time 2 "${API_URL}/${FIRST_IP}") if [[ $(echo "$RESPONSE" | jq -r '.status') == "Available" ]]; then IP=$FIRST_IP else IP=${IP_LIST[1]} fi fi echo "$IP" } # Generating argo Config argo_configure() { if [[ $ARGO_AUTH =~ TunnelSecret ]]; then echo $ARGO_AUTH > tunnel.json cat > tunnel.yml << EOF tunnel: $(cut -d\" -f12 <<< "$ARGO_AUTH") credentials-file: tunnel.json protocol: http2 ingress: - hostname: $ARGO_DOMAIN service: http://localhost:$vmess_port originRequest: noTLSVerify: true - service: http_status:404 EOF fi } # Download Dependency Files download_and_run_singbox() { if [ ! -s sb.txt ] && [ ! -s ag.txt ]; then 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/arm64/bot13 bot") elif [ "$ARCH" == "amd64" ] || [ "$ARCH" == "x86_64" ] || [ "$ARCH" == "x86" ]; then FILE_INFO=("https://github.com/yonggekkk/Cloudflare_vless_trojan/releases/download/serv00/sb web" "https://github.com/yonggekkk/Cloudflare_vless_trojan/releases/download/serv00/server bot") 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" } download_with_fallback() { local URL=$1 local NEW_FILENAME=$2 curl -L -sS --max-time 2 -o "$NEW_FILENAME" "$URL" & CURL_PID=$! CURL_START_SIZE=$(stat -c%s "$NEW_FILENAME" 2>/dev/null || echo 0) sleep 1 CURL_CURRENT_SIZE=$(stat -c%s "$NEW_FILENAME" 2>/dev/null || echo 0) if [ "$CURL_CURRENT_SIZE" -le "$CURL_START_SIZE" ]; then kill $CURL_PID 2>/dev/null wait $CURL_PID 2>/dev/null wget -q -O "$NEW_FILENAME" "$URL" echo -e "\e[1;32mDownloading $NEW_FILENAME by wget\e[0m" else wait $CURL_PID echo -e "\e[1;32mDownloading $NEW_FILENAME by curl\e[0m" fi } 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 echo -e "\e[1;32m$NEW_FILENAME already exists, Skipping download\e[0m" else download_with_fallback "$URL" "$NEW_FILENAME" fi chmod +x "$NEW_FILENAME" FILE_MAP[$(echo "$entry" | cut -d ' ' -f 2)]="$NEW_FILENAME" done wait fi if [ ! -e private_key.txt ]; then output=$(./"$(basename ${FILE_MAP[web]})" generate reality-keypair) private_key=$(echo "${output}" | awk '/PrivateKey:/ {print $2}') public_key=$(echo "${output}" | awk '/PublicKey:/ {print $2}') echo "${private_key}" > private_key.txt echo "${public_key}" > public_key.txt fi private_key=$( config.json << EOF { "log": { "disabled": true, "level": "info", "timestamp": true }, "inbounds": [ { "tag": "hysteria-in", "type": "hysteria2", "listen": "$IP", "listen_port": $hy2_port, "users": [ { "password": "$UUID" } ], "masquerade": "https://www.bing.com", "ignore_client_bandwidth":false, "tls": { "enabled": true, "alpn": [ "h3" ], "certificate_path": "cert.pem", "key_path": "private.key" } }, { "tag": "vless-reality-vesion", "type": "vless", "listen": "::", "listen_port": $vless_port, "users": [ { "uuid": "$UUID", "flow": "xtls-rprx-vision" } ], "tls": { "enabled": true, "server_name": "$reym", "reality": { "enabled": true, "handshake": { "server": "$reym", "server_port": 443 }, "private_key": "$private_key", "short_id": [ "" ] } } }, { "tag": "vmess-ws-in", "type": "vmess", "listen": "::", "listen_port": $vmess_port, "users": [ { "uuid": "$UUID" } ], "transport": { "type": "ws", "path": "$UUID-vm", "early_data_header_name": "Sec-WebSocket-Protocol" } } ], "outbounds": [ { "type": "wireguard", "tag": "wg", "server": "162.159.192.200", "server_port": 4500, "local_address": [ "172.16.0.2/32", "2606:4700:110:8f77:1ca9:f086:846c:5f9e/128" ], "private_key": "wIxszdR2nMdA7a2Ul3XQcniSfSZqdqjPb6w6opvf5AU=", "peer_public_key": "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=", "reserved": [ 126, 246, 173 ] }, { "type": "direct", "tag": "direct" }, { "type": "block", "tag": "block" } ], "route": { "rules": [ { "domain": [ $ytb "oh.my.god" ], "outbound": "wg" } ], "final": "direct" } } EOF if ! ps aux | grep '[c]onfig' > /dev/null; then ps aux | grep '[c]onfig' | awk '{print $2}' | xargs -r kill -9 > /dev/null 2>&1 if [ -e "$(basename "${FILE_MAP[web]}")" ]; then echo "$(basename "${FILE_MAP[web]}")" > sb.txt sbb=$(cat sb.txt) nohup ./"$sbb" run -c config.json >/dev/null 2>&1 & sleep 5 if pgrep -x "$sbb" > /dev/null; then green "$sbb 主进程已启动" else red "$sbb 主进程未启动, 重启中..." pkill -x "$sbb" nohup ./"$sbb" run -c config.json >/dev/null 2>&1 & sleep 2 purple "$sbb 主进程已重启" fi else sbb=$(cat sb.txt) nohup ./"$sbb" run -c config.json >/dev/null 2>&1 & sleep 5 if pgrep -x "$sbb" > /dev/null; then green "$sbb 主进程已启动" else red "$sbb 主进程未启动, 重启中..." pkill -x "$sbb" nohup ./"$sbb" run -c config.json >/dev/null 2>&1 & sleep 2 purple "$sbb 主进程已重启" fi fi else green "主进程已启动" fi cfgo() { rm -rf boot.log if [ -e "$(basename "${FILE_MAP[bot]}")" ]; then echo "$(basename "${FILE_MAP[bot]}")" > ag.txt agg=$(cat ag.txt) if [[ $ARGO_AUTH =~ ^[A-Z0-9a-z=]{120,250}$ ]]; then args="tunnel --edge-ip-version auto --no-autoupdate --protocol http2 run --token ${ARGO_AUTH}" elif [[ $ARGO_AUTH =~ TunnelSecret ]]; then args="tunnel --edge-ip-version auto --config tunnel.yml run" else args="tunnel --edge-ip-version auto --no-autoupdate --protocol http2 --logfile boot.log --loglevel info --url http://localhost:$vmess_port" fi nohup ./"$agg" $args >/dev/null 2>&1 & sleep 10 if pgrep -x "$agg" > /dev/null; then green "$agg Arog进程已启动" else red "$agg Argo进程未启动, 重启中..." pkill -x "$agg" nohup ./"$agg" "${args}" >/dev/null 2>&1 & sleep 5 purple "$agg Argo进程已重启" fi else agg=$(cat ag.txt) if [[ $ARGO_AUTH =~ ^[A-Z0-9a-z=]{120,250}$ ]]; then args="tunnel --edge-ip-version auto --no-autoupdate --protocol http2 run --token ${ARGO_AUTH}" elif [[ $ARGO_AUTH =~ TunnelSecret ]]; then args="tunnel --edge-ip-version auto --config tunnel.yml run" else args="tunnel --edge-ip-version auto --no-autoupdate --protocol http2 --logfile boot.log --loglevel info --url http://localhost:$vmess_port" fi nohup ./"$agg" $args >/dev/null 2>&1 & sleep 10 if pgrep -x "$agg" > /dev/null; then green "$agg Arog进程已启动" else red "$agg Argo进程未启动, 重启中..." pkill -x "$agg" nohup ./"$agg" "${args}" >/dev/null 2>&1 & sleep 5 purple "$agg Argo进程已重启" fi fi } if [ -z "$ARGO_DOMAIN" ] && ! ps aux | grep "[l]ocalhost:$vmess_port" > /dev/null; then ps aux | grep '[l]ocalhost' | awk '{print $2}' | xargs -r kill -9 > /dev/null 2>&1 cfgo elif [ -n "$ARGO_DOMAIN" ] && ! ps aux | grep "[t]oken $ARGO_AUTH" > /dev/null; then ps aux | grep '[t]oken' | awk '{print $2}' | xargs -r kill -9 > /dev/null 2>&1 cfgo else green "Arog进程已启动" fi sleep 2 if ! pgrep -x "$(cat sb.txt)" > /dev/null; then red "主进程未启动,根据以下情况一一排查" yellow "1、网页端权限是否开启" yellow "2、端口是否设置错误(2个TCP、1个UDP)" yellow "3、尝试更换网页端3个端口并重装" yellow "4、当前Serv00服务器炸了?等会再试" red "5、以上都试了,哥直接躺平,交给进程保活,过会再来看" fi } get_argodomain() { if [[ -n $ARGO_AUTH ]]; then echo "$ARGO_DOMAIN" > gdym.log echo "$ARGO_DOMAIN" else local retry=0 local max_retries=6 local argodomain="" while [[ $retry -lt $max_retries ]]; do ((retry++)) argodomain=$(grep -oE 'https://[[:alnum:]+\.-]+\.trycloudflare\.com' boot.log 2>/dev/null | sed 's@https://@@') if [[ -n $argodomain ]]; then break fi sleep 2 done if [ -z ${argodomain} ]; then argodomain="Argo临时域名暂时获取失败,Argo节点暂不可用" fi echo "$argodomain" fi } get_links(){ argodomain=$(get_argodomain) echo -e "\e[1;32mArgo域名:\e[1;35m${argodomain}\e[0m\n" ISP=$(curl -sL --max-time 5 https://speed.cloudflare.com/meta | awk -F\" '{print $26}' | sed -e 's/ /_/g' || echo "0") get_name() { if [ "$HOSTNAME" = "s1.ct8.pl" ]; then SERVER="CT8"; else SERVER=$(echo "$HOSTNAME" | cut -d '.' -f 1); fi; echo "$SERVER"; } NAME="$ISP-$(get_name)" rm -rf jh.txt vl_link="vless://$UUID@$IP:$vless_port?encryption=none&flow=xtls-rprx-vision&security=reality&sni=$reym&fp=chrome&pbk=$public_key&type=tcp&headerType=none#$NAME-reality" echo "$vl_link" >> jh.txt vmws_link="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$NAME-vmess-ws\", \"add\": \"$IP\", \"port\": \"$vmess_port\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"auto\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"\", \"path\": \"/$UUID-vm?ed=2048\", \"tls\": \"\", \"sni\": \"\", \"alpn\": \"\", \"fp\": \"\"}" | base64 -w0)" echo "$vmws_link" >> jh.txt vmatls_link="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$NAME-vmess-ws-tls-argo\", \"add\": \"icook.hk\", \"port\": \"8443\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"auto\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"$argodomain\", \"path\": \"/$UUID-vm?ed=2048\", \"tls\": \"tls\", \"sni\": \"$argodomain\", \"alpn\": \"\", \"fp\": \"\"}" | base64 -w0)" echo "$vmatls_link" >> jh.txt vma_link="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$NAME-vmess-ws-argo\", \"add\": \"icook.hk\", \"port\": \"8880\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"auto\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"$argodomain\", \"path\": \"/$UUID-vm?ed=2048\", \"tls\": \"\"}" | base64 -w0)" echo "$vma_link" >> jh.txt hy2_link="hysteria2://$UUID@$IP:$hy2_port?sni=www.bing.com&alpn=h3&insecure=1#$NAME-hy2" echo "$hy2_link" >> jh.txt url=$(cat jh.txt 2>/dev/null) baseurl=$(echo -e "$url" | base64 -w 0) cat > sing_box.json < clash_meta.yaml </dev/null) clmsub=$(cat clash_meta.yaml 2>/dev/null) echo sleep 2 cat > list.txt <