#!/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=$(whoami) HOSTNAME=$(hostname) export UUID=${UUID:-'fc44fe6a-f083-4591-9c03-f8d61dc3907f'} export NEZHA_SERVER=${NEZHA_SERVER:-''} export NEZHA_PORT=${NEZHA_PORT:-'5555'} export NEZHA_KEY=${NEZHA_KEY:-''} export ARGO_DOMAIN=${ARGO_DOMAIN:-''} export ARGO_AUTH=${ARGO_AUTH:-''} export CFIP=${CFIP:-'www.visa.com.tw'} export CFPORT=${CFPORT:-'443'} export VLESS_PORT=${VLESS_PORT:-'10000'} export ARGO_PORT=${ARGO_PORT:-'20000'} [[ "$HOSTNAME" == "s1.ct8.pl" ]] && WORKDIR="domains/${USERNAME}.ct8.pl/logs" || WORKDIR="domains/${USERNAME}.serv00.net/logs" && rm -rf $WORKDIR [ -d "$WORKDIR" ] || (mkdir -p "$WORKDIR" && chmod 777 "$WORKDIR") ps aux | grep $(whoami) | grep -v "sshd\|bash\|grep" | awk '{print $2}' | xargs -r kill -9 2>/dev/null argo_configure() { clear purple "正在安装中,请稍等..." if [[ -z $ARGO_AUTH || -z $ARGO_DOMAIN ]]; then green "ARGO_DOMAIN or ARGO_AUTH is empty,use quick tunnel" return fi 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 else green "ARGO_AUTH mismatch TunnelSecret,use token connect to tunnel" fi } argo_configure wait 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" "https://github.com/eooce/test/releases/download/ARM/swith npm") elif [ "$ARCH" == "amd64" ] || [ "$ARCH" == "x86_64" ] || [ "$ARCH" == "x86" ]; then FILE_INFO=("https://github.com/eooce/test/releases/download/freebsd/xary web" "https://github.com/eooce/test/releases/download/freebsd/server bot" "https://github.com/eooce/test/releases/download/freebsd/swith 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" } 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 generate_config() { output=$(./"${FILE_MAP[web]}" x25519) private_key=$(echo "$output" | grep "Private key" | cut -d ' ' -f 3) public_key=$(echo "$output" | grep "Public key" | cut -d ' ' -f 3) cat > config.json << EOF { "log":{ "access":"/dev/null", "error":"/dev/null", "loglevel":"none" }, "inbounds":[ { "tag":"vless-reality", "protocol":"vless", "port":${VLESS_PORT}, "settings":{ "clients":[ { "id":"${UUID}", "flow":"xtls-rprx-vision" } ], "decryption":"none" }, "streamSettings":{ "network":"tcp", "security":"reality", "realitySettings":{ "show":true, "dest":"www.ups.com:443", "xver":0, "serverNames":[ "www.ups.com" ], "privateKey":"${private_key}", "publicKey":"${public_key}", "maxTimeDiff":0, "shortIds":[ "" ] } }, "sniffing":{ "enabled":true, "destOverride":[ "http", "tls" ] } }, { "tag":"vmess-splithttp", "port": ${ARGO_PORT}, "protocol": "vmess", "settings": { "clients": [ { "id": "${UUID}", "alterId": 0, "security": "auto" } ] }, "streamSettings": { "network": "splithttp", "security": "none", "httpSettings": { "host": "", "path": "" } } } ], "dns":{ "servers":[ "https+local://8.8.8.8/dns-query" ] }, "outbounds":[ { "protocol":"freedom" }, { "tag":"WARP", "protocol":"wireguard", "settings":{ "secretKey":"YFYOAdbw1bKTHlNNi+aEjBM3BO7unuFC5rOkMRAz9XY=", "address":[ "172.16.0.2/32", "2606:4700:110:8a36:df92:102a:9602:fa18/128" ], "peers":[ { "publicKey":"bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=", "allowedIPs":[ "0.0.0.0/0", "::/0" ], "endpoint":"162.159.193.10:2408" } ], "reserved":[78, 135, 76], "mtu":1280 } } ], "routing":{ "domainStrategy":"AsIs", "rules":[ { "type":"field", "domain":[ "domain:openai.com", "domain:chatgpt.com", "domain:auth.openai.com", "domain:chat.openai.com" ], "outboundTag":"WARP" } ] } } EOF } generate_config wait if [ -e "$(basename ${FILE_MAP[npm]})" ]; then tlsPorts=("443" "8443" "2096" "2087" "2083" "2053") if [[ "${tlsPorts[*]}" =~ "${NEZHA_PORT}" ]]; then NEZHA_TLS="--tls" else NEZHA_TLS="" fi if [ -n "$NEZHA_SERVER" ] && [ -n "$NEZHA_PORT" ] && [ -n "$NEZHA_KEY" ]; then export TMPDIR=$(pwd) nohup ./"$(basename ${FILE_MAP[npm]})" -s ${NEZHA_SERVER}:${NEZHA_PORT} -p ${NEZHA_KEY} ${NEZHA_TLS} >/dev/null 2>&1 & sleep 2 pgrep -x "$(basename ${FILE_MAP[npm]})" > /dev/null && green "$(basename ${FILE_MAP[npm]}) is running" || { red "$(basename ${FILE_MAP[npm]}) is not running, restarting..."; pkill -x "$(basename ${FILE_MAP[npm]})" && nohup ./"$(basename ${FILE_MAP[npm]})" -s "${NEZHA_SERVER}:${NEZHA_PORT}" -p "${NEZHA_KEY}" ${NEZHA_TLS} >/dev/null 2>&1 & sleep 2; purple "$(basename ${FILE_MAP[npm]}) restarted"; } else purple "NEZHA variable is empty, skipping running" fi fi if [ -e "$(basename ${FILE_MAP[web]})" ]; then nohup ./"$(basename ${FILE_MAP[web]})" -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 ./"$(basename ${FILE_MAP[web]})" -c config.json >/dev/null 2>&1 & sleep 2; purple "$(basename ${FILE_MAP[web]}) restarted"; } fi if [ -e "$(basename ${FILE_MAP[bot]})" ]; then 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 "${WORKDIR}/boot.log" --loglevel info --url http://localhost:$ARGO_PORT" fi nohup ./"$(basename ${FILE_MAP[bot]})" $args >/dev/null 2>&1 & sleep 2 pgrep -x "$(basename ${FILE_MAP[bot]})" > /dev/null && green "$(basename ${FILE_MAP[bot]}) is running" || { red "$(basename ${FILE_MAP[bot]}) is not running, restarting..."; pkill -x "$(basename ${FILE_MAP[bot]})" && nohup ./"$(basename ${FILE_MAP[bot]})" "${args}" >/dev/null 2>&1 & sleep 2; purple "$(basename ${FILE_MAP[bot]}) restarted"; } fi sleep 2 rm -f "$(basename ${FILE_MAP[npm]})" "$(basename ${FILE_MAP[web]})" "$(basename ${FILE_MAP[bot]})" get_argodomain() { if [[ -n $ARGO_AUTH ]]; then echo "$ARGO_DOMAIN" else local retry=0 local max_retries=6 local argodomain="" while [[ $retry -lt $max_retries ]]; do ((retry++)) argodomain=$(sed -n 's|.*https://\([^/]*trycloudflare\.com\).*|\1|p' "${WORKDIR}/boot.log") if [[ -n $argodomain ]]; then break fi sleep 1 done echo "$argodomain" fi } get_ip() { 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" } generate_links() { Available_IP=$(get_ip) argodomain=$(get_argodomain) echo -e "\e[1;32mArgoDomain:\e[1;35m${argodomain}\e[0m\n" ISP=$(curl -s --max-time 1.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)" cat > ${WORKDIR}/list.txt <