├── .github └── workflows │ └── main.yml ├── README.md ├── SFW电脑网页版(V1.11.7).7z ├── SSH.yml ├── app.js ├── index.html ├── kp.sh ├── sb.sh ├── sbwpph_amd64 ├── sbwpph_arm64 ├── sb官方客户端配置说明.txt ├── serv00.sh ├── serv00.yml ├── serv00keep.sh ├── sversion ├── version └── workers_keep.js /.github/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Parallel URL Fetch 2 | 3 | on: 4 | schedule: 5 | - cron: '*/10 * * * *' # 每10分钟执行一次(公开库每月2000分钟运行时长,每天64分钟) 6 | workflow_dispatch: 7 | 8 | jobs: 9 | fetch-urls: 10 | runs-on: ubuntu-latest 11 | 12 | steps: 13 | - name: Checkout repository 14 | uses: actions/checkout@v2 15 | 16 | - name: Fetch URLs in parallel 17 | # secrets设置,变量名称:http 18 | # 变量值要求:每个保活/up网页或每个重启/re网页之间用空格或者,或者,间隔开,网页前带http:// 19 | # 变量值填写示例:http://保活或重启网页1 http://保活或重启网页2 http://保活或重启网页3 ……… 20 | run: | 21 | IFS=$',, ' read -r -a http <<< "${{ secrets.http }}" 22 | echo "*****************************************************" 23 | echo "甬哥Github项目 :github.com/yonggekkk" 24 | echo "甬哥Blogger博客 :ygkkk.blogspot.com" 25 | echo "甬哥YouTube频道 :www.youtube.com/@ygkkk" 26 | echo "🎉Github定时运行serv00保活网页🎉" 27 | echo "请先确认已成功安装甬哥的serv00的SSH脚本或者Github/VPS/软路由脚本" 28 | echo "脚本地址:https://github.com/yonggekkk/sing-box-yg" 29 | echo "*****************************************************" 30 | for url in "${http[@]}"; do 31 | response=$(curl -sk "$url" || true) 32 | if [[ "$response" == *"网页保活启动"* ]]; then 33 | echo "🎉恭喜!$url ✅运行正常,成功拉起一次保活" 34 | elif [[ "$response" == *"主程序重启成功"* ]]; then 35 | echo "🎉恭喜!$url ✅运行正常,成功重启一次主程序" 36 | else 37 | echo "💥杯具!$url ❌运行失败,⚠️网页变量是否填写正确?或者Serv00炸了" 38 | fi 39 | done 40 | wait 41 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### 一、Sing-box-yg精装桶一键四协议共存脚本(VPS专用) 2 | ### 二、Serv00/Hostuno-sb-yg多平台一键三协议共存脚本(Serv00/Hostuno专用) 3 | 4 | ### 注:本项目分享订阅节点都为本地化生成,不使用节点转换、订阅器等第三方外链引用,无需担心节点订阅被外链作者查看 5 | 6 | ### 交流平台:[甬哥博客地址](https://ygkkk.blogspot.com)、[甬哥YouTube频道](https://www.youtube.com/@ygkkk)、[甬哥TG电报群组](https://t.me/+jZHc6-A-1QQ5ZGVl)、[甬哥TG电报频道](https://t.me/+DkC9ZZUgEFQzMTZl) 7 | -------------------------------------------------------------- 8 | 9 | ### 一、Sing-box-yg精装桶小白专享一键四协议共存脚本(VPS专用) 10 | 11 | * 支持人气最高的四大协议:Vless-reality-vision、Vmess-ws(tls)/Argo、Hysteria-2、Tuic-v5 12 | 13 | * 支持纯IPV6、纯IPV4、双栈VPS,支持amd与arm架构,支持alpine系统,推荐使用最新的Ubuntu系统 14 | 15 | * 小白简单模式:无需域名证书,回车三次就安装完成,复制、扫描你要的节点配置 16 | 17 | #### 相关说明及注意点请查看[甬哥博客说明与Sing-box视频教程](https://ygkkk.blogspot.com/2023/10/sing-box-yg.html) 18 | 19 | #### 视频教程: 20 | 21 | [Sing-box精装桶小白一键脚本(一):配置文件通吃SFA/SFI/SFW三平台客户端,Argo隧道、双证书切换、域名分流](https://youtu.be/QwTapeVPeB0) 22 | 23 | [Sing-box精装桶小白一键脚本(二):纯IPV6 VPS搭建,CDN优选IP设置汇总,全平台多种客户端一个脚本全套带走](https://youtu.be/kmTgj1DundU) 24 | 25 | [Sing-box精装桶小白一键脚本(三):自建gitlab私有订阅链接一键同步推送全平台,WARP分流ChatGPT,SFW电脑客户端支持订阅链接](https://youtu.be/by7C2HU6-fU) 26 | 27 | [Sing-box精装桶小白一键脚本(四):vmess协议CDN优选IP多形态设置(详见说明图)](https://youtu.be/Qfm8DbLeb6w) 28 | 29 | [Sing-box精装桶小白一键脚本(五):集成oblivion warp免费vpn功能,本地WARP+赛风VPN切换分流(30个国家IP)](https://youtu.be/5Y6NPsYPws0) 30 | 31 | ### VPS专用一键脚本如下:快捷方式:```sb``` 32 | 33 | ``` 34 | bash <(wget -qO- https://raw.githubusercontent.com/yonggekkk/sing-box-yg/main/sb.sh) 35 | ``` 36 | 或者 37 | ``` 38 | bash <(curl -Ls https://raw.githubusercontent.com/yonggekkk/sing-box-yg/main/sb.sh) 39 | ``` 40 | 41 | 更新中的ArgoSB脚本,专为Google IDX VPS设计:https://github.com/yonggekkk/ArgoSB 42 | 43 | ### Sing-box-yg脚本界面预览图(注:相关参数随意填写,仅供围观) 44 | 45 | ![1d5425c093618313888fe41a55f493f](https://github.com/user-attachments/assets/2b4b04a6-2de4-499a-afa1-ed78bccc50a8) 46 | 47 | ----------------------------------------------------- 48 | 49 | ### 二、Serv00/Hostuno一键三协议共存脚本(Serv00/Hostuno专用): 50 | 51 | * 目前免费Serv00使用代理脚本有被封账号的风险,收费版Hostuno不受影响,可正常使用 52 | 53 | * 切勿与其他Serv00脚本混用!!! 54 | 55 | * 修改自Serv00老王sing-box安装脚本,支持一键三协议:vless-reality、vmess-ws(argo)、hysteria2 56 | 57 | * 主要增加reality协议默认支持 CF vless/trojan 节点的proxyip以及非标端口的优选反代IP功能 58 | 59 | * 聚合通用节点分享,支持到22个节点:三协议各自三个IP,argo全覆盖13个端口节点,已添加不死优选IP 60 | 61 | #### 相关说明及注意点请查看[甬哥博客说明与Serv00视频教程](https://ygkkk.blogspot.com/2025/01/serv00.html) 62 | 63 | #### 视频教程: 64 | 65 | [Serv00免费代理脚本最终教程(一):独家支持三个IP自定义安装,支持Proxyip+反代IP、支持Argo临时/固定隧道+CDN回源;支持五个节点的Sing-box与Clash订阅配置输出](https://youtu.be/2VF9D6z2z7w) 66 | 67 | [Serv00免费代理脚本最终教程(二):Serv00不必再登录SSH了,部署保活融为一体,独家支持Github、VPS、软路由多平台多账户通用部署,四大方案总有一款适合你](https://youtu.be/rYeX1iU_iZ0) 68 | 69 | [Serv00免费代理脚本最终教程(三):多功能网页生成【保活+重启+重置端口+查看订阅节点】、随意重置端口功能;Github+Workers自动执行保活功能任你选!](https://youtu.be/9uCfFNnjNc0) 70 | 71 | [Serv00免费代理脚本最终教程(四):重大更新!支持Argo临时/固定隧道相互切换,实时更新节点信息;完美适配Serv00收费版Hostuno.com](https://youtu.be/XN6_vpz1NhE) 72 | 73 | [Serv00免费代理脚本最终教程(五):Github、VPS、软路由多平台脚本大更新!支持多功能网页,Cron内射保活+网页外射保活,任你选](https://youtu.be/tKaBdbU4G4s) 74 | 75 | ### Serv00/Hostuno-sb-yg一键脚本 76 | 77 | * Argo高度自定义:可以重置临时隧道; 可以继续使用上回的固定隧道; 也可以更换固定隧道的域名或token 78 | 79 | ``` 80 | bash <(curl -Ls https://raw.githubusercontent.com/yonggekkk/sing-box-yg/main/serv00.sh) 81 | ``` 82 | 83 | #### Serv00/Hostuno-sb-yg脚本界面预览图,仅限方案一的SSH端安装脚本(注:仅供围观) 84 | ![a6b776a094566ab14e88fdcd70ba9e9](https://github.com/user-attachments/assets/90a918ed-aec7-4a1f-8159-97f3acfd0092) 85 | 86 | 87 | ----------------------------------------------------- 88 | ### 感谢支持!微信打赏甬哥侃侃侃ygkkk 89 | ![41440820a366deeb8109db5610313a1](https://github.com/user-attachments/assets/5cd2d891-ae54-4397-8211-ac4c6d1099c9) 90 | 91 | --------------------------------------- 92 | ### 感谢你右上角的star🌟 93 | [![Stargazers over time](https://starchart.cc/yonggekkk/sing-box-yg.svg)](https://starchart.cc/yonggekkk/sing-box-yg) 94 | 95 | --------------------------------------- 96 | #### 声明:所有代码来源于Github社区与ChatGPT的整合,[老王eooce](https://github.com/eooce/Sing-box/blob/test/sb_00.sh)、[frankiejun](https://github.com/frankiejun/serv00-play/blob/main/start.sh) 97 | -------------------------------------------------------------------------------- /SFW电脑网页版(V1.11.7).7z: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yonggekkk/sing-box-yg/03a0ecc9c7e97b5e86e1a35b800d06889503ac17/SFW电脑网页版(V1.11.7).7z -------------------------------------------------------------------------------- /SSH.yml: -------------------------------------------------------------------------------- 1 | name: Keep Servers serv00 2 | on: 3 | schedule: 4 | - cron: '0 15 */8 * *' 5 | workflow_dispatch: 6 | 7 | jobs: 8 | keep_servers_alive: 9 | runs-on: ubuntu-latest 10 | env: 11 | ACCOUNTS: > 12 | [ 13 | {"SSH_USER":"123456789", "SSH_PASS":"123456", "HOST":"sxxx.serv00.com"} 14 | ] 15 | steps: 16 | - name: Checkout Repository 17 | uses: actions/checkout@v4.2.2 18 | 19 | - name: Install required packages 20 | run: | 21 | sudo apt-get update 22 | sudo apt-get install -y sshpass jq 23 | 24 | - name: Process each account 25 | run: | 26 | echo "*****************************************************" 27 | echo "*****************************************************" 28 | echo "甬哥Github项目 :github.com/yonggekkk" 29 | echo "甬哥Blogger博客 :ygkkk.blogspot.com" 30 | echo "甬哥YouTube频道 :www.youtube.com/@ygkkk" 31 | echo "vps服务器远程登录一次SSH脚本【Github】" 32 | echo "*****************************************************" 33 | echo "*****************************************************" 34 | count=0 35 | for account in $(echo "${ACCOUNTS}" | jq -c '.[]'); do 36 | count=$((count+1)) 37 | SSH_USER=$(echo $account | jq -r '.SSH_USER') 38 | SSH_PASS=$(echo $account | jq -r '.SSH_PASS') 39 | HOST=$(echo $account | jq -r '.HOST') 40 | if sshpass -p "$SSH_PASS" ssh -o StrictHostKeyChecking=no "$SSH_USER@$HOST" -q exit; then 41 | echo "🎉恭喜!✅第【$count】台服务器连接成功!🚀服务器地址:$HOST ,账户名:$SSH_USER" 42 | else 43 | echo "====================================================" 44 | echo "💥杯具!❌第【$count】台服务器连接失败!🚀服务器地址:$HOST ,账户名:$SSH_USER" 45 | echo "⚠️可能账号名、密码、服务器名称输入错误,或者当前服务器在维护中" 46 | echo "====================================================" 47 | fi 48 | sleep 10 49 | done 50 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | require('dotenv').config(); 2 | const express = require("express"); 3 | const { spawn, exec } = require("child_process"); 4 | const app = express(); 5 | app.use(express.json()); 6 | const commandToRun = "cd ~ && bash serv00keep.sh"; 7 | function runCustomCommand() { 8 | exec(commandToRun, (err, stdout, stderr) => { 9 | if (err) console.error("执行错误:", err); 10 | else console.log("执行成功:", stdout); 11 | }); 12 | } 13 | app.get("/up", (req, res) => { 14 | runCustomCommand(); 15 | res.type("html").send("
Serv00-name服务器网页保活启动:Serv00-name!UP!UP!UP!
"); 16 | }); 17 | app.get("/re", (req, res) => { 18 | const additionalCommands = ` 19 | USERNAME=$(whoami | tr '[:upper:]' '[:lower:]') 20 | FULL_PATH="/home/\${USERNAME}/domains/\${USERNAME}.serv00.net/logs" 21 | cd "\$FULL_PATH" 22 | pkill -f 'run -c con' || echo "无进程可终止,准备执行重启……" 23 | sbb="\$(cat sb.txt 2>/dev/null)" 24 | nohup ./"\$sbb" run -c config.json >/dev/null 2>&1 & 25 | sleep 2 26 | (cd ~ && bash serv00keep.sh >/dev/null 2>&1) & 27 | echo '主程序重启成功,请检测三个主节点是否可用,如不可用,可再次刷新重启网页或者重置端口' 28 | `; 29 | exec(additionalCommands, (err, stdout, stderr) => { 30 | console.log('stdout:', stdout); 31 | console.error('stderr:', stderr); 32 | if (err) { 33 | return res.status(500).send(`错误:${stderr || stdout}`); 34 | } 35 | res.type('text').send(stdout); 36 | }); 37 | }); 38 | 39 | const changeportCommands = "cd ~ && bash webport.sh"; 40 | function runportCommand() { 41 | exec(changeportCommands, { maxBuffer: 1024 * 1024 * 10 }, (err, stdout, stderr) => { 42 | console.log('stdout:', stdout); 43 | console.error('stderr:', stderr); 44 | if (err) { 45 | console.error('Execution error:', err); 46 | return res.status(500).send(`错误:${stderr || stdout}`); 47 | } 48 | if (stderr) { 49 | console.error('stderr output:', stderr); 50 | return res.status(500).send(`stderr: ${stderr}`); 51 | } 52 | res.type('text').send(stdout); 53 | }); 54 | } 55 | app.get("/rp", (req, res) => { 56 | runportCommand(); 57 | res.type("html").send("
重置三个节点端口完成!请立即关闭本网页并稍等20秒,将主页后缀改为  /list/你的uuid  可查看更新端口后的节点及订阅信息
"); 58 | }); 59 | app.get("/list/key", (req, res) => { 60 | const listCommands = ` 61 | USERNAME=$(whoami | tr '[:upper:]' '[:lower:]') 62 | USERNAME1=$(whoami) 63 | FULL_PATH="/home/\${USERNAME1}/domains/\${USERNAME}.serv00.net/logs/list.txt" 64 | cat "\$FULL_PATH" 65 | `; 66 | exec(listCommands, (err, stdout, stderr) => { 67 | if (err) { 68 | console.error(`路径验证失败: ${stderr}`); 69 | return res.status(404).send(stderr); 70 | } 71 | res.type('text').send(stdout); 72 | }); 73 | }); 74 | 75 | app.get("/jc", (req, res) => { 76 | const ps = spawn("ps", ["aux"]); 77 | res.type("text"); 78 | ps.stdout.on("data", (data) => res.write(data)); 79 | ps.stderr.on("data", (data) => res.write(`Error: ${data}`)); 80 | ps.on("close", (code) => { 81 | if (code !== 0) { 82 | res.status(500).send(`ps aux 进程退出,错误码: ${code}`); 83 | } else { 84 | res.end(); 85 | } 86 | }); 87 | }); 88 | 89 | app.use((req, res) => { 90 | res.status(404).send('请在浏览器地址:http://where.name.serv00.net 后面加三种路径功能:/up是保活,/re是重启,/rp是重置节点端口,/jc是查看当前系统进程,/list/你的uuid 是节点及订阅信息'); 91 | }); 92 | setInterval(runCustomCommand, (2 * 60 + 15) * 60 * 1000); 93 | app.listen(3000, () => { 94 | console.log("服务器运行在端口 3000"); 95 | runCustomCommand(); 96 | }); 97 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Serv00-sb-yg本地SSH专用一键脚本:https://github.com/yonggekkk/sing-box-yg 6 | 69 | 70 | 71 | 72 | 73 |
74 |
75 |

===========================================

76 |

甬哥侃侃侃ygkkk Serv00-sb-yg一键三协议共存脚本

77 |

===========================================

78 |

YouTubu视频教程 点击进入.

79 |

Github项目地址 点击进入.

80 |

教程博客地址 点击进入.

81 |
82 |
83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /kp.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 定时设置:*/10 * * * * /bin/bash /root/kp.sh 每10分钟运行一次 3 | # 如果你已安装了Serv00本地SSH脚本,不要再运行此脚本部署了,这样会造成进程爆满,必须二选一! 4 | # serv00变量添加规则: 5 | # 如使用保活网页,请不要启用cron,以防止cron与网页保活重复运行造成进程爆满 6 | # RES(必填):n表示每次不重置部署,y表示每次重置部署。REP(必填):n表示不重置随机端口(三个端口留空),y表示重置端口(三个端口留空)。SSH_USER(必填)表示serv00账号名。SSH_PASS(必填)表示serv00密码。REALITY表示reality域名(留空表示serv00官方域名:你serv00账号名.serv00.net)。SUUID表示uuid(留空表示随机uuid)。TCP1_PORT表示vless的tcp端口(留空表示随机tcp端口)。TCP2_PORT表示vmess的tcp端口(留空表示随机tcp端口)。UDP_PORT表示hy2的udp端口(留空表示随机udp端口)。HOST(必填)表示登录serv00服务器域名。ARGO_DOMAIN表示argo固定域名(留空表示临时域名)。ARGO_AUTH表示argo固定域名token(留空表示临时域名)。 7 | # 必填变量:RES、REP、SSH_USER、SSH_PASS、HOST 8 | # 注意[]"",:这些符号不要乱删,按规律对齐 9 | # 每行一个{serv00服务器},一个服务也可,末尾用,间隔,最后一个服务器末尾无需用,间隔 10 | ACCOUNTS='[ 11 | {"RES":"n", "REP":"n", "SSH_USER":"你的serv00账号名", "SSH_PASS":"你的serv00账号密码", "REALITY":"你serv00账号名.serv00.net", "SUUID":"自设UUID", "TCP1_PORT":"vless的tcp端口", "TCP2_PORT":"vmess的tcp端口", "UDP_PORT":"hy2的udp端口", "HOST":"s1.serv00.com", "ARGO_DOMAIN":"", "ARGO_AUTH":""}, 12 | {"RES":"y", "REP":"y", "SSH_USER":"123456", "SSH_PASS":"7890000", "REALITY":"time.is", "SUUID":"73203ee6-b3fa-4a3d-b5df-6bb2f55073ad", "TCP1_PORT":"", "TCP2_PORT":"", "UDP_PORT":"", "HOST":"s16.serv00.com", "ARGO_DOMAIN":"你的argo固定域名", "ARGO_AUTH":"eyJhIjoiOTM3YzFjYWI88552NTFiYTM4ZTY0ZDQzRmlNelF0TkRBd1pUQTRNVEJqTUdVeCJ9"} 13 | ]' 14 | run_remote_command() { 15 | local RES=$1 16 | local REP=$2 17 | local SSH_USER=$3 18 | local SSH_PASS=$4 19 | local REALITY=${5} 20 | local SUUID=$6 21 | local TCP1_PORT=$7 22 | local TCP2_PORT=$8 23 | local UDP_PORT=$9 24 | local HOST=${10} 25 | local ARGO_DOMAIN=${11} 26 | local ARGO_AUTH=${12} 27 | if [ -z "${ARGO_DOMAIN}" ]; then 28 | echo "Argo域名为空,申请Argo临时域名" 29 | else 30 | echo "Argo已设置固定域名:${ARGO_DOMAIN}" 31 | fi 32 | remote_command="export reym=$REALITY UUID=$SUUID vless_port=$TCP1_PORT vmess_port=$TCP2_PORT hy2_port=$UDP_PORT reset=$RES resport=$REP ARGO_DOMAIN=${ARGO_DOMAIN} ARGO_AUTH=${ARGO_AUTH} && bash <(curl -Ls https://raw.githubusercontent.com/yonggekkk/sing-box-yg/main/serv00keep.sh)" 33 | echo "Executing remote command on $HOST as $SSH_USER with command: $remote_command" 34 | sshpass -p "$SSH_PASS" ssh -o StrictHostKeyChecking=no "$SSH_USER@$HOST" "$remote_command" 35 | } 36 | if cat /etc/issue /proc/version /etc/os-release 2>/dev/null | grep -q -E -i "openwrt"; then 37 | opkg update 38 | opkg install sshpass curl jq 39 | else 40 | if [ -f /etc/debian_version ]; then 41 | package_manager="apt-get install -y" 42 | apt-get update >/dev/null 2>&1 43 | elif [ -f /etc/redhat-release ]; then 44 | package_manager="yum install -y" 45 | elif [ -f /etc/fedora-release ]; then 46 | package_manager="dnf install -y" 47 | elif [ -f /etc/alpine-release ]; then 48 | package_manager="apk add" 49 | fi 50 | $package_manager sshpass curl jq cron >/dev/null 2>&1 & 51 | fi 52 | echo "*****************************************************" 53 | echo "*****************************************************" 54 | echo "甬哥Github项目 :github.com/yonggekkk" 55 | echo "甬哥Blogger博客 :ygkkk.blogspot.com" 56 | echo "甬哥YouTube频道 :www.youtube.com/@ygkkk" 57 | echo "自动远程部署Serv00三合一协议脚本【VPS+软路由】" 58 | echo "版本:V25.3.26" 59 | echo "*****************************************************" 60 | echo "*****************************************************" 61 | count=0 62 | for account in $(echo "${ACCOUNTS}" | jq -c '.[]'); do 63 | count=$((count+1)) 64 | RES=$(echo $account | jq -r '.RES') 65 | REP=$(echo $account | jq -r '.REP') 66 | SSH_USER=$(echo $account | jq -r '.SSH_USER') 67 | SSH_PASS=$(echo $account | jq -r '.SSH_PASS') 68 | REALITY=$(echo $account | jq -r '.REALITY') 69 | SUUID=$(echo $account | jq -r '.SUUID') 70 | TCP1_PORT=$(echo $account | jq -r '.TCP1_PORT') 71 | TCP2_PORT=$(echo $account | jq -r '.TCP2_PORT') 72 | UDP_PORT=$(echo $account | jq -r '.UDP_PORT') 73 | HOST=$(echo $account | jq -r '.HOST') 74 | ARGO_DOMAIN=$(echo $account | jq -r '.ARGO_DOMAIN') 75 | ARGO_AUTH=$(echo $account | jq -r '.ARGO_AUTH') 76 | if sshpass -p "$SSH_PASS" ssh -o StrictHostKeyChecking=no "$SSH_USER@$HOST" -q exit; then 77 | echo "🎉恭喜!✅第【$count】台服务器连接成功!🚀服务器地址:$HOST ,账户名:$SSH_USER" 78 | if [ -z "${ARGO_DOMAIN}" ]; then 79 | check_process="ps aux | grep '[c]onfig' > /dev/null && ps aux | grep [l]ocalhost:$TCP2_PORT > /dev/null" 80 | else 81 | check_process="ps aux | grep '[c]onfig' > /dev/null && ps aux | grep '[t]oken $ARGO_AUTH' > /dev/null" 82 | fi 83 | if ! sshpass -p "$SSH_PASS" ssh -o StrictHostKeyChecking=no "$SSH_USER@$HOST" "$check_process" || [[ "$RES" =~ ^[Yy]$ ]]; then 84 | echo "⚠️检测到主进程或者argo进程未启动,或者执行重置" 85 | echo "⚠️现在开始修复或重置部署……请稍等" 86 | output=$(run_remote_command "$RES" "$REP" "$SSH_USER" "$SSH_PASS" "${REALITY}" "$SUUID" "$TCP1_PORT" "$TCP2_PORT" "$UDP_PORT" "$HOST" "${ARGO_DOMAIN}" "${ARGO_AUTH}") 87 | echo "远程命令执行结果:$output" 88 | else 89 | echo "🎉恭喜!✅检测到所有进程正常运行中 " 90 | SSH_USER_LOWER=$(echo "$SSH_USER" | tr '[:upper:]' '[:lower:]') 91 | sshpass -p "$SSH_PASS" ssh -o StrictHostKeyChecking=no "$SSH_USER@$HOST" " 92 | echo \"配置显示如下:\" 93 | cat domains/${SSH_USER_LOWER}.serv00.net/logs/list.txt 94 | echo \"====================================================\"" 95 | fi 96 | else 97 | echo "====================================================" 98 | echo "💥杯具!❌第【$count】台服务器连接失败!🚀服务器地址:$HOST ,账户名:$SSH_USER" 99 | echo "⚠️可能账号名、密码、服务器名称输入错误,或者当前服务器在维护中" 100 | echo "====================================================" 101 | fi 102 | done 103 | -------------------------------------------------------------------------------- /sbwpph_amd64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yonggekkk/sing-box-yg/03a0ecc9c7e97b5e86e1a35b800d06889503ac17/sbwpph_amd64 -------------------------------------------------------------------------------- /sbwpph_arm64: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/yonggekkk/sing-box-yg/03a0ecc9c7e97b5e86e1a35b800d06889503ac17/sbwpph_arm64 -------------------------------------------------------------------------------- /sb官方客户端配置说明.txt: -------------------------------------------------------------------------------- 1 | sing-box官方SFA/SFI/SFW客户端配置简要说明 2 | 小白关键点操作指南 V23.11.15(不定时更新) 3 | 4 | 注意:小白在自己的sing-box配置文件中,只要改动节点区与分流组这两块区域即可 5 | ------------------------------------------------------------------------------------ 6 | 节点区 7 | ------------------------------------------------------------------------------------ 8 | 一、vless-reality-vision节点 9 | ------------------------------------------------------------------------------------ 10 | { 11 | "type": "vless", 12 | "tag": "vless-sb", 自定义节点名称 13 | "server": "1.2.3.4", 服务器本地ip 14 | "server_port": 12345, 自定义的端口 15 | "uuid": "658ff7f4-0448-4368-a104-c3108517f56a", 自定义的uuid 16 | "flow": "xtls-rprx-vision", 17 | "tls": { 18 | "enabled": true, 19 | "server_name": "www.yahoo.com", 自定义的第三方偷域名 20 | "utls": { 21 | "enabled": true, 22 | "fingerprint": "chrome" 23 | }, 24 | "reality": { 25 | "enabled": true, 26 | "public_key": "oBwBeiq8MjOqHS0fTXm39gRM_fdXgbAvtEWfAaW", 自定义的public-key 27 | "short_id": "91b4db47" 自定义的short-id 28 | } 29 | } 30 | }, 31 | 32 | 33 | ------------------------------------------------------------------------------------ 34 | 二、vmess-ws(tls)+argo节点 35 | ------------------------------------------------------------------------------------ 36 | { 37 | "server": "1.2.3.4", 服务器本地ip、解析的域名、优选IP、优选域名 38 | "server_port": 12345, 自定义的端口,vps-cdn与argo-cdn,注意13个端口变化 39 | "tag": "vmess-sb", 自定义节点名称 40 | "tls": { 41 | "enabled": true, tls开启:true tls关闭:false 42 | "server_name": "yg.ygkkk.eu.org", tls开启:解析的域名或者argo域名 43 | "insecure": false, 44 | "utls": { 45 | "enabled": true, 46 | "fingerprint": "chrome" 47 | } 48 | }, 49 | "transport": { 50 | "headers": { 51 | "Host": [ 52 | "yg.ygkkk.eu.org" 解析的域名或者argo域名 53 | ] 54 | }, 55 | "path": "658ff7f4-0448-4368-a104-c3108517f56a-vm", 自定义的uuid值-vm 56 | "type": "ws" 57 | }, 58 | "type": "vmess", 59 | "security": "auto", 60 | "uuid": "658ff7f4-0448-4368-a104-c3108517f56a" 自定义的uuid 61 | }, 62 | 63 | ------------------------------------------------------------------------------------ 64 | 三、hysteria2节点 65 | ------------------------------------------------------------------------------------ 66 | { 67 | "type": "hysteria2", 68 | "tag": "hy2-sb", 自定义节点名称 69 | "server": "1.2.3.4", 自签证书:服务器本地ip 域名证书:解析的域名 70 | "server_port": 12345, 自定义的端口 71 | "password": "658ff7f4-0448-4368-a104-c3108517f56a", 自定义的uuid 72 | "tls": { 73 | "enabled": true, 74 | "server_name": "www.bing.com", 自签证书:www.bing.com 域名证书:解析的域名 75 | "insecure": true, 自签证书:true 域名证书:false 76 | "alpn": [ 77 | "h3" 78 | ] 79 | } 80 | }, 81 | 82 | 83 | ------------------------------------------------------------------------------------ 84 | 四、tuic5节点 85 | ------------------------------------------------------------------------------------ 86 | { 87 | "type":"tuic", 88 | "tag": "tuic5-sb", 自定义节点名称 89 | "server": "1.2.3.4", 自签证书:服务器本地ip 域名证书:解析的域名 90 | "server_port": 12345, 自定义的端口 91 | "uuid": "658ff7f4-0448-4368-a104-c3108517f56a", 自定义的uuid 92 | "password": "658ff7f4-0448-4368-a104-c3108517f56a", 自定义的uuid 93 | "congestion_control": "bbr", 94 | "udp_relay_mode": "native", 95 | "udp_over_stream": false, 96 | "zero_rtt_handshake": false, 97 | "heartbeat": "10s", 98 | "tls":{ 99 | "enabled": true, 100 | "server_name": "www.bing.com", 自签证书:www.bing.com 域名证书:解析的域名 101 | "insecure": true, 自签证书:true 域名证书:false 102 | "alpn": [ 103 | "h3" 104 | ] 105 | } 106 | }, 107 | 108 | ------------------------------------------------------------------------------------ 109 | 五、cf-vless(tls)节点 110 | ------------------------------------------------------------------------------------ 111 | { 112 | "server": "1.2.3.4", 优选IP、优选域名 113 | "server_port": 12345, 自定义的端口,注意13个端口变化 114 | "tag": "cf-vless-sb", 自定义节点名称 115 | "tls": { 116 | "enabled": true, tls开启:true tls关闭:false 117 | "server_name": "yg.ygkkk.eu.org", tls开启:pages域名或者自定义域名 118 | "insecure": false, 119 | "utls": { 120 | "enabled": true, 121 | "fingerprint": "chrome" 122 | } 123 | }, 124 | "transport": { 125 | "headers": { 126 | "Host": [ 127 | "yg.ygkkk.eu.org" workers、pages域名或者自定义域名 128 | ] 129 | }, 130 | "path": "/?ed=2048", path路径:/?ed=2048 131 | "type": "ws" 132 | }, 133 | "type": "vless", 134 | "uuid": "658ff7f4-0448-4368-a104-c3108517f56a" 自定义的uuid 135 | }, 136 | 137 | 138 | 139 | ------------------------------------------------------------------------------------ 140 | 分流组:共两组,分为手动选择select与自动选择auto,每组节点可按需求自行增减,确保出现的自定义节点名称可以在节点区中查找到 141 | ------------------------------------------------------------------------------------ 142 | 手动选择select 143 | { 144 | "tag": "select", 145 | "type": "selector", 146 | "default": "auto", 147 | "outbounds": [ 148 | "auto", 149 | "vless-sb", 自定义节点名称 150 | "vmess-sb", 自定义节点名称 151 | "hy2-sb", 自定义节点名称 152 | "tuic5-sb", 自定义节点名称 153 | "cf-vless-sb" 自定义节点名称 154 | ………… ………… 155 | ] 156 | }, 157 | ------------------------------------------------------------------------------------ 158 | 自动选择auto 159 | { 160 | "tag": "auto", 161 | "type": "urltest", 162 | "outbounds": [ 163 | "vless-sb", 自定义节点名称 164 | "vmess-sb", 自定义节点名称 165 | "hy2-sb", 自定义节点名称 166 | "tuic5-sb", 自定义节点名称 167 | "cf-vless-sb" 自定义节点名称 168 | ……………… ………… 169 | ] 170 | }, 171 | ------------------------------------------------------------------------------------ 172 | -------------------------------------------------------------------------------- /serv00.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | re="\033[0m" 3 | red="\033[1;91m" 4 | green="\e[1;32m" 5 | yellow="\e[1;33m" 6 | purple="\e[1;35m" 7 | red() { echo -e "\e[1;91m$1\033[0m"; } 8 | green() { echo -e "\e[1;32m$1\033[0m"; } 9 | yellow() { echo -e "\e[1;33m$1\033[0m"; } 10 | purple() { echo -e "\e[1;35m$1\033[0m"; } 11 | reading() { read -p "$(red "$1")" "$2"; } 12 | USERNAME=$(whoami | tr '[:upper:]' '[:lower:]') 13 | snb=$(hostname | cut -d. -f1) 14 | nb=$(hostname | cut -d '.' -f 1 | tr -d 's') 15 | HOSTNAME=$(hostname) 16 | hona=$(hostname | cut -d. -f2) 17 | if [ "$hona" = "serv00" ]; then 18 | address="serv00.net" 19 | keep_path="${HOME}/domains/${snb}.${USERNAME}.serv00.net/public_nodejs" 20 | [ -d "$keep_path" ] || mkdir -p "$keep_path" 21 | else 22 | address="useruno.com" 23 | fi 24 | WORKDIR="${HOME}/domains/${USERNAME}.${address}/logs" 25 | devil www add ${USERNAME}.${address} php > /dev/null 2>&1 26 | FILE_PATH="${HOME}/domains/${USERNAME}.${address}/public_html" 27 | [ -d "$FILE_PATH" ] || mkdir -p "$FILE_PATH" 28 | [ -d "$WORKDIR" ] || (mkdir -p "$WORKDIR" && chmod 777 "$WORKDIR") 29 | devil binexec on >/dev/null 2>&1 30 | curl -sk "http://${snb}.${USERNAME}.${hona}.net/up" > /dev/null 2>&1 31 | 32 | read_ip() { 33 | cat ip.txt 34 | reading "请输入上面三个IP中的任意一个 (建议默认回车自动选择可用IP): " IP 35 | if [[ -z "$IP" ]]; then 36 | IP=$(grep -m 1 "可用" ip.txt | awk -F ':' '{print $1}') 37 | if [ -z "$IP" ]; then 38 | IP=$(okip) 39 | if [ -z "$IP" ]; then 40 | IP=$(head -n 1 ip.txt | awk -F ':' '{print $1}') 41 | fi 42 | fi 43 | fi 44 | echo "$IP" > $WORKDIR/ipone.txt 45 | IP=$(<$WORKDIR/ipone.txt) 46 | green "你选择的IP为: $IP" 47 | } 48 | 49 | read_uuid() { 50 | reading "请输入统一的uuid密码 (建议回车默认随机): " UUID 51 | if [[ -z "$UUID" ]]; then 52 | UUID=$(uuidgen -r) 53 | fi 54 | echo "$UUID" > $WORKDIR/UUID.txt 55 | UUID=$(<$WORKDIR/UUID.txt) 56 | green "你的uuid为: $UUID" 57 | } 58 | 59 | read_reym() { 60 | yellow "方式一:(推荐)使用Serv00/Hostuno自带域名,不支持proxyip功能:输入回车" 61 | yellow "方式二:使用CF域名(blog.cloudflare.com),支持proxyip+非标端口反代ip功能:输入s" 62 | yellow "方式三:支持其他域名,注意要符合reality域名规则:输入域名" 63 | reading "请输入reality域名 【请选择 回车 或者 s 或者 输入域名】: " reym 64 | if [[ -z "$reym" ]]; then 65 | reym=$USERNAME.${address} 66 | elif [[ "$reym" == "s" || "$reym" == "S" ]]; then 67 | reym=blog.cloudflare.com 68 | fi 69 | echo "$reym" > $WORKDIR/reym.txt 70 | reym=$(<$WORKDIR/reym.txt) 71 | green "你的reality域名为: $reym" 72 | } 73 | 74 | resallport(){ 75 | portlist=$(devil port list | grep -E '^[0-9]+[[:space:]]+[a-zA-Z]+' | sed 's/^[[:space:]]*//') 76 | if [[ -z "$portlist" ]]; then 77 | yellow "无端口" 78 | else 79 | while read -r line; do 80 | port=$(echo "$line" | awk '{print $1}') 81 | port_type=$(echo "$line" | awk '{print $2}') 82 | yellow "删除端口 $port ($port_type)" 83 | devil port del "$port_type" "$port" 84 | done <<< "$portlist" 85 | fi 86 | check_port 87 | if [[ -e $WORKDIR/config.json ]]; then 88 | hyp=$(jq -r '.inbounds[0].listen_port' $WORKDIR/config.json) 89 | vlp=$(jq -r '.inbounds[3].listen_port' $WORKDIR/config.json) 90 | vmp=$(jq -r '.inbounds[4].listen_port' $WORKDIR/config.json) 91 | purple "检测到Serv00/Hostuno-sb-yg脚本已安装,执行端口替换,请稍等……" 92 | sed -i '' "12s/$hyp/$hy2_port/g" $WORKDIR/config.json 93 | sed -i '' "33s/$hyp/$hy2_port/g" $WORKDIR/config.json 94 | sed -i '' "54s/$hyp/$hy2_port/g" $WORKDIR/config.json 95 | sed -i '' "75s/$vlp/$vless_port/g" $WORKDIR/config.json 96 | sed -i '' "102s/$vmp/$vmess_port/g" $WORKDIR/config.json 97 | if [ "$hona" = "serv00" ]; then 98 | sed -i '' -e "17s|'$vlp'|'$vless_port'|" serv00keep.sh 99 | sed -i '' -e "18s|'$vmp'|'$vmess_port'|" serv00keep.sh 100 | sed -i '' -e "19s|'$hyp'|'$hy2_port'|" serv00keep.sh 101 | fi 102 | resservsb 103 | green "端口替换完成!" 104 | ps aux | grep '[r]un -c con' > /dev/null && green "主进程启动成功,单节点用户修改下客户端三协议端口" || yellow "Sing-box主进程启动失败" 105 | if [ -f "$WORKDIR/boot.log" ]; then 106 | ps aux | grep '[t]unnel --u' > /dev/null && green "Argo临时隧道已启动,临时域名可能已变更" || yellow "Argo临时隧道启动失败" 107 | else 108 | ps aux | grep '[t]unnel --n' > /dev/null && green "Argo固定隧道已启动" || yellow "Argo固定隧道启动失败,请先在CF更改隧道端口:$vmess_port,再重启下Argo隧道" 109 | fi 110 | cd $WORKDIR 111 | showchangelist 112 | cd 113 | fi 114 | } 115 | 116 | check_port () { 117 | port_list=$(devil port list) 118 | tcp_ports=$(echo "$port_list" | grep -c "tcp") 119 | udp_ports=$(echo "$port_list" | grep -c "udp") 120 | if [[ $tcp_ports -ne 2 || $udp_ports -ne 1 ]]; then 121 | red "端口数量不符合要求,正在调整..." 122 | 123 | if [[ $tcp_ports -gt 2 ]]; then 124 | tcp_to_delete=$((tcp_ports - 2)) 125 | echo "$port_list" | awk '/tcp/ {print $1, $2}' | head -n $tcp_to_delete | while read port type; do 126 | devil port del $type $port 127 | green "已删除TCP端口: $port" 128 | done 129 | fi 130 | if [[ $udp_ports -gt 1 ]]; then 131 | udp_to_delete=$((udp_ports - 1)) 132 | echo "$port_list" | awk '/udp/ {print $1, $2}' | head -n $udp_to_delete | while read port type; do 133 | devil port del $type $port 134 | green "已删除UDP端口: $port" 135 | done 136 | fi 137 | if [[ $tcp_ports -lt 2 ]]; then 138 | tcp_ports_to_add=$((2 - tcp_ports)) 139 | tcp_ports_added=0 140 | while [[ $tcp_ports_added -lt $tcp_ports_to_add ]]; do 141 | tcp_port=$(shuf -i 10000-65535 -n 1) 142 | result=$(devil port add tcp $tcp_port 2>&1) 143 | if [[ $result == *"succesfully"* ]]; then 144 | green "已添加TCP端口: $tcp_port" 145 | if [[ $tcp_ports_added -eq 0 ]]; then 146 | tcp_port1=$tcp_port 147 | else 148 | tcp_port2=$tcp_port 149 | fi 150 | tcp_ports_added=$((tcp_ports_added + 1)) 151 | else 152 | yellow "端口 $tcp_port 不可用,尝试其他端口..." 153 | fi 154 | done 155 | fi 156 | if [[ $udp_ports -lt 1 ]]; then 157 | while true; do 158 | udp_port=$(shuf -i 10000-65535 -n 1) 159 | result=$(devil port add udp $udp_port 2>&1) 160 | if [[ $result == *"succesfully"* ]]; then 161 | green "已添加UDP端口: $udp_port" 162 | break 163 | else 164 | yellow "端口 $udp_port 不可用,尝试其他端口..." 165 | fi 166 | done 167 | fi 168 | #green "端口已调整完成,将断开ssh连接,请重新连接shh重新执行脚本" 169 | #devil binexec on >/dev/null 2>&1 170 | #kill -9 $(ps -o ppid= -p $$) >/dev/null 2>&1 171 | sleep 3 172 | port_list=$(devil port list) 173 | tcp_ports=$(echo "$port_list" | grep -c "tcp") 174 | udp_ports=$(echo "$port_list" | grep -c "udp") 175 | tcp_ports=$(echo "$port_list" | awk '/tcp/ {print $1}') 176 | tcp_port1=$(echo "$tcp_ports" | sed -n '1p') 177 | tcp_port2=$(echo "$tcp_ports" | sed -n '2p') 178 | udp_port=$(echo "$port_list" | awk '/udp/ {print $1}') 179 | purple "当前TCP端口: $tcp_port1 和 $tcp_port2" 180 | purple "当前UDP端口: $udp_port" 181 | else 182 | tcp_ports=$(echo "$port_list" | awk '/tcp/ {print $1}') 183 | tcp_port1=$(echo "$tcp_ports" | sed -n '1p') 184 | tcp_port2=$(echo "$tcp_ports" | sed -n '2p') 185 | udp_port=$(echo "$port_list" | awk '/udp/ {print $1}') 186 | purple "当前TCP端口: $tcp_port1 和 $tcp_port2" 187 | purple "当前UDP端口: $udp_port" 188 | fi 189 | export vless_port=$tcp_port1 190 | export vmess_port=$tcp_port2 191 | export hy2_port=$udp_port 192 | green "你的vless-reality端口: $vless_port" 193 | green "你的vmess-ws端口(设置Argo固定域名端口): $vmess_port" 194 | green "你的hysteria2端口: $hy2_port" 195 | } 196 | 197 | install_singbox() { 198 | if [[ -e $WORKDIR/list.txt ]]; then 199 | yellow "已安装sing-box,请先选择2卸载,再执行安装" && exit 200 | fi 201 | sleep 2 202 | cd $WORKDIR 203 | echo 204 | read_ip 205 | echo 206 | read_reym 207 | echo 208 | read_uuid 209 | echo 210 | check_port 211 | echo 212 | sleep 2 213 | argo_configure 214 | echo 215 | download_and_run_singbox 216 | cd 217 | fastrun 218 | green "创建快捷方式:sb" 219 | echo 220 | if [ "$hona" = "serv00" ]; then 221 | servkeep 222 | fi 223 | cd $WORKDIR 224 | echo 225 | get_links 226 | cd 227 | purple "************************************************************" 228 | purple "Serv00/Hostuno-sb-yg脚本安装结束" 229 | purple "退出SSH" 230 | purple "请再次连接SSH,查看主菜单,请输入快捷方式:sb" 231 | purple "************************************************************" 232 | sleep 2 233 | kill -9 $(ps -o ppid= -p $$) >/dev/null 2>&1 234 | } 235 | 236 | uninstall_singbox() { 237 | reading "\n确定要卸载吗?【y/n】: " choice 238 | case "$choice" in 239 | [Yy]) 240 | bash -c 'ps aux | grep $(whoami) | grep -v "sshd\|bash\|grep" | awk "{print \$2}" | xargs -r kill -9 >/dev/null 2>&1' >/dev/null 2>&1 241 | rm -rf bin domains serv00keep.sh webport.sh 242 | devil www list | awk 'NR > 1 && NF {print $1}' | xargs -I {} devil www del {} > /dev/null 2>&1 243 | sed -i '' '/export PATH="\$HOME\/bin:\$PATH"/d' ~/.bashrc 244 | source ~/.bashrc 245 | purple "************************************************************" 246 | purple "Serv00/Hostuno-sb-yg卸载完成!" 247 | purple "欢迎继续使用脚本:bash <(curl -Ls https://raw.githubusercontent.com/yonggekkk/sing-box-yg/main/serv00.sh)" 248 | purple "************************************************************" 249 | ;; 250 | [Nn]) exit 0 ;; 251 | *) red "无效的选择,请输入y或n" && menu ;; 252 | esac 253 | } 254 | 255 | kill_all_tasks() { 256 | reading "\n注意!!!清理所有进程并清空所有安装内容,将退出ssh连接,确定继续清理吗?【y/n】: " choice 257 | case "$choice" in 258 | [Yy]) 259 | bash -c 'ps aux | grep $(whoami) | grep -v "sshd\|bash\|grep" | awk "{print \$2}" | xargs -r kill -9 >/dev/null 2>&1' >/dev/null 2>&1 260 | devil www list | awk 'NR > 1 && NF {print $1}' | xargs -I {} devil www del {} > /dev/null 2>&1 261 | sed -i '' '/export PATH="\$HOME\/bin:\$PATH"/d' ~/.bashrc 262 | source ~/.bashrc 263 | purple "************************************************************" 264 | purple "Serv00/Hostuno-sb-yg清理重置完成!" 265 | purple "欢迎继续使用脚本:bash <(curl -Ls https://raw.githubusercontent.com/yonggekkk/sing-box-yg/main/serv00.sh)" 266 | purple "************************************************************" 267 | find ~ -type f -exec chmod 644 {} \; 2>/dev/null 268 | find ~ -type d -exec chmod 755 {} \; 2>/dev/null 269 | find ~ -type f -exec rm -f {} \; 2>/dev/null 270 | find ~ -type d -empty -exec rmdir {} \; 2>/dev/null 271 | find ~ -exec rm -rf {} \; 2>/dev/null 272 | killall -9 -u $(whoami) 273 | ;; 274 | *) menu ;; 275 | esac 276 | } 277 | 278 | argo_configure() { 279 | while true; do 280 | yellow "方式一:(推荐)无需域名的Argo临时隧道:输入回车" 281 | yellow "方式二:需要域名的Argo固定隧道(需要CF设置提取Token):输入g" 282 | reading "【请选择 g 或者 回车】: " argo_choice 283 | if [[ "$argo_choice" != "g" && "$argo_choice" != "G" && -n "$argo_choice" ]]; then 284 | red "无效的选择,请输入 g 或回车" 285 | continue 286 | fi 287 | if [[ "$argo_choice" == "g" || "$argo_choice" == "G" ]]; then 288 | reading "请输入argo固定隧道域名: " ARGO_DOMAIN 289 | echo "$ARGO_DOMAIN" | tee ARGO_DOMAIN.log ARGO_DOMAIN_show.log > /dev/null 290 | green "你的argo固定隧道域名为: $ARGO_DOMAIN" 291 | reading "请输入argo固定隧道密钥(当你粘贴Token时,必须以ey开头): " ARGO_AUTH 292 | echo "$ARGO_AUTH" | tee ARGO_AUTH.log ARGO_AUTH_show.log > /dev/null 293 | green "你的argo固定隧道密钥为: $ARGO_AUTH" 294 | rm -rf boot.log 295 | else 296 | green "使用Argo临时隧道" 297 | rm -rf ARGO_AUTH.log ARGO_DOMAIN.log 298 | fi 299 | break 300 | done 301 | } 302 | 303 | download_and_run_singbox() { 304 | if [ ! -s sb.txt ] && [ ! -s ag.txt ]; then 305 | DOWNLOAD_DIR="." && mkdir -p "$DOWNLOAD_DIR" && FILE_INFO=() 306 | 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") 307 | declare -A FILE_MAP 308 | generate_random_name() { 309 | local chars=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 310 | local name="" 311 | for i in {1..6}; do 312 | name="$name${chars:RANDOM%${#chars}:1}" 313 | done 314 | echo "$name" 315 | } 316 | 317 | download_with_fallback() { 318 | local URL=$1 319 | local NEW_FILENAME=$2 320 | 321 | curl -L -sS --max-time 2 -o "$NEW_FILENAME" "$URL" & 322 | CURL_PID=$! 323 | CURL_START_SIZE=$(stat -c%s "$NEW_FILENAME" 2>/dev/null || echo 0) 324 | 325 | sleep 1 326 | CURL_CURRENT_SIZE=$(stat -c%s "$NEW_FILENAME" 2>/dev/null || echo 0) 327 | 328 | if [ "$CURL_CURRENT_SIZE" -le "$CURL_START_SIZE" ]; then 329 | kill $CURL_PID 2>/dev/null 330 | wait $CURL_PID 2>/dev/null 331 | wget -q -O "$NEW_FILENAME" "$URL" 332 | echo -e "\e[1;32mDownloading $NEW_FILENAME by wget\e[0m" 333 | else 334 | wait $CURL_PID 335 | echo -e "\e[1;32mDownloading $NEW_FILENAME by curl\e[0m" 336 | fi 337 | } 338 | 339 | for entry in "${FILE_INFO[@]}"; do 340 | URL=$(echo "$entry" | cut -d ' ' -f 1) 341 | RANDOM_NAME=$(generate_random_name) 342 | NEW_FILENAME="$DOWNLOAD_DIR/$RANDOM_NAME" 343 | 344 | if [ -e "$NEW_FILENAME" ]; then 345 | echo -e "\e[1;32m$NEW_FILENAME already exists, Skipping download\e[0m" 346 | else 347 | download_with_fallback "$URL" "$NEW_FILENAME" 348 | fi 349 | 350 | chmod +x "$NEW_FILENAME" 351 | FILE_MAP[$(echo "$entry" | cut -d ' ' -f 2)]="$NEW_FILENAME" 352 | done 353 | wait 354 | fi 355 | 356 | if [ ! -e private_key.txt ]; then 357 | output=$(./"$(basename ${FILE_MAP[web]})" generate reality-keypair) 358 | private_key=$(echo "${output}" | awk '/PrivateKey:/ {print $2}') 359 | public_key=$(echo "${output}" | awk '/PublicKey:/ {print $2}') 360 | echo "${private_key}" > private_key.txt 361 | echo "${public_key}" > public_key.txt 362 | fi 363 | private_key=$( config.json << EOF 368 | { 369 | "log": { 370 | "disabled": true, 371 | "level": "info", 372 | "timestamp": true 373 | }, 374 | "inbounds": [ 375 | { 376 | "tag": "hysteria-in1", 377 | "type": "hysteria2", 378 | "listen": "$(dig @8.8.8.8 +time=5 +short "web$nb.${hona}.com" | sort -u)", 379 | "listen_port": $hy2_port, 380 | "users": [ 381 | { 382 | "password": "$UUID" 383 | } 384 | ], 385 | "masquerade": "https://www.bing.com", 386 | "ignore_client_bandwidth":false, 387 | "tls": { 388 | "enabled": true, 389 | "alpn": [ 390 | "h3" 391 | ], 392 | "certificate_path": "cert.pem", 393 | "key_path": "private.key" 394 | } 395 | }, 396 | { 397 | "tag": "hysteria-in2", 398 | "type": "hysteria2", 399 | "listen": "$(dig @8.8.8.8 +time=5 +short "$HOSTNAME" | sort -u)", 400 | "listen_port": $hy2_port, 401 | "users": [ 402 | { 403 | "password": "$UUID" 404 | } 405 | ], 406 | "masquerade": "https://www.bing.com", 407 | "ignore_client_bandwidth":false, 408 | "tls": { 409 | "enabled": true, 410 | "alpn": [ 411 | "h3" 412 | ], 413 | "certificate_path": "cert.pem", 414 | "key_path": "private.key" 415 | } 416 | }, 417 | { 418 | "tag": "hysteria-in3", 419 | "type": "hysteria2", 420 | "listen": "$(dig @8.8.8.8 +time=5 +short "cache$nb.${hona}.com" | sort -u)", 421 | "listen_port": $hy2_port, 422 | "users": [ 423 | { 424 | "password": "$UUID" 425 | } 426 | ], 427 | "masquerade": "https://www.bing.com", 428 | "ignore_client_bandwidth":false, 429 | "tls": { 430 | "enabled": true, 431 | "alpn": [ 432 | "h3" 433 | ], 434 | "certificate_path": "cert.pem", 435 | "key_path": "private.key" 436 | } 437 | }, 438 | { 439 | "tag": "vless-reality-vesion", 440 | "type": "vless", 441 | "listen": "::", 442 | "listen_port": $vless_port, 443 | "users": [ 444 | { 445 | "uuid": "$UUID", 446 | "flow": "xtls-rprx-vision" 447 | } 448 | ], 449 | "tls": { 450 | "enabled": true, 451 | "server_name": "$reym", 452 | "reality": { 453 | "enabled": true, 454 | "handshake": { 455 | "server": "$reym", 456 | "server_port": 443 457 | }, 458 | "private_key": "$private_key", 459 | "short_id": [ 460 | "" 461 | ] 462 | } 463 | } 464 | }, 465 | { 466 | "tag": "vmess-ws-in", 467 | "type": "vmess", 468 | "listen": "::", 469 | "listen_port": $vmess_port, 470 | "users": [ 471 | { 472 | "uuid": "$UUID" 473 | } 474 | ], 475 | "transport": { 476 | "type": "ws", 477 | "path": "$UUID-vm", 478 | "early_data_header_name": "Sec-WebSocket-Protocol" 479 | } 480 | } 481 | ], 482 | "outbounds": [ 483 | { 484 | "type": "wireguard", 485 | "tag": "wg", 486 | "server": "162.159.192.200", 487 | "server_port": 4500, 488 | "local_address": [ 489 | "172.16.0.2/32", 490 | "2606:4700:110:8f77:1ca9:f086:846c:5f9e/128" 491 | ], 492 | "private_key": "wIxszdR2nMdA7a2Ul3XQcniSfSZqdqjPb6w6opvf5AU=", 493 | "peer_public_key": "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=", 494 | "reserved": [ 495 | 126, 496 | 246, 497 | 173 498 | ] 499 | }, 500 | { 501 | "type": "direct", 502 | "tag": "direct" 503 | } 504 | ], 505 | "route": { 506 | "rule_set": [ 507 | { 508 | "tag": "google-gemini", 509 | "type": "remote", 510 | "format": "binary", 511 | "url": "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/google-gemini.srs", 512 | "download_detour": "direct" 513 | } 514 | ], 515 | EOF 516 | if [[ "$nb" =~ 14|15 ]]; then 517 | cat >> config.json <> config.json < /dev/null; then 545 | ps aux | grep '[r]un -c con' | awk '{print $2}' | xargs -r kill -9 > /dev/null 2>&1 546 | if [ -e "$(basename "${FILE_MAP[web]}")" ]; then 547 | echo "$(basename "${FILE_MAP[web]}")" > sb.txt 548 | sbb=$(cat sb.txt) 549 | nohup ./"$sbb" run -c config.json >/dev/null 2>&1 & 550 | sleep 5 551 | if pgrep -x "$sbb" > /dev/null; then 552 | green "$sbb 主进程已启动" 553 | else 554 | red "$sbb 主进程未启动, 重启中..." 555 | pkill -x "$sbb" 556 | nohup ./"$sbb" run -c config.json >/dev/null 2>&1 & 557 | sleep 2 558 | purple "$sbb 主进程已重启" 559 | fi 560 | else 561 | sbb=$(cat sb.txt) 562 | nohup ./"$sbb" run -c config.json >/dev/null 2>&1 & 563 | sleep 5 564 | if pgrep -x "$sbb" > /dev/null; then 565 | green "$sbb 主进程已启动" 566 | else 567 | red "$sbb 主进程未启动, 重启中..." 568 | pkill -x "$sbb" 569 | nohup ./"$sbb" run -c config.json >/dev/null 2>&1 & 570 | sleep 2 571 | purple "$sbb 主进程已重启" 572 | fi 573 | fi 574 | else 575 | green "主进程已启动" 576 | fi 577 | cfgo() { 578 | rm -rf boot.log 579 | if [ -e "$(basename "${FILE_MAP[bot]}")" ]; then 580 | echo "$(basename "${FILE_MAP[bot]}")" > ag.txt 581 | agg=$(cat ag.txt) 582 | if [[ $ARGO_AUTH =~ ^[A-Z0-9a-z=]{120,250}$ ]]; then 583 | #args="tunnel --edge-ip-version auto --no-autoupdate --protocol http2 run --token ${ARGO_AUTH}" 584 | args="tunnel --no-autoupdate run --token ${ARGO_AUTH}" 585 | else 586 | #args="tunnel --edge-ip-version auto --no-autoupdate --protocol http2 --logfile boot.log --loglevel info --url http://localhost:$vmess_port" 587 | args="tunnel --url http://localhost:$vmess_port --no-autoupdate --logfile boot.log --loglevel info" 588 | fi 589 | nohup ./"$agg" $args >/dev/null 2>&1 & 590 | sleep 10 591 | if pgrep -x "$agg" > /dev/null; then 592 | green "$agg Arog进程已启动" 593 | else 594 | red "$agg Argo进程未启动, 重启中..." 595 | pkill -x "$agg" 596 | nohup ./"$agg" "${args}" >/dev/null 2>&1 & 597 | sleep 5 598 | purple "$agg Argo进程已重启" 599 | fi 600 | else 601 | agg=$(cat ag.txt) 602 | if [[ $ARGO_AUTH =~ ^[A-Z0-9a-z=]{120,250}$ ]]; then 603 | #args="tunnel --edge-ip-version auto --no-autoupdate --protocol http2 run --token ${ARGO_AUTH}" 604 | args="tunnel --no-autoupdate run --token ${ARGO_AUTH}" 605 | else 606 | #args="tunnel --edge-ip-version auto --no-autoupdate --protocol http2 --logfile boot.log --loglevel info --url http://localhost:$vmess_port" 607 | args="tunnel --url http://localhost:$vmess_port --no-autoupdate --logfile boot.log --loglevel info" 608 | fi 609 | pkill -x "$agg" 610 | nohup ./"$agg" $args >/dev/null 2>&1 & 611 | sleep 10 612 | if pgrep -x "$agg" > /dev/null; then 613 | green "$agg Arog进程已启动" 614 | else 615 | red "$agg Argo进程未启动, 重启中..." 616 | pkill -x "$agg" 617 | nohup ./"$agg" "${args}" >/dev/null 2>&1 & 618 | sleep 5 619 | purple "$agg Argo进程已重启" 620 | fi 621 | fi 622 | } 623 | 624 | if [ -f "$WORKDIR/boot.log" ]; then 625 | argosl=$(cat "$WORKDIR/boot.log" 2>/dev/null | grep -a trycloudflare.com | awk 'NR==2{print}' | awk -F// '{print $2}' | awk '{print $1}') 626 | checkhttp=$(curl -o /dev/null -s -w "%{http_code}\n" "https://$argosl") 627 | else 628 | argogd=$(cat $WORKDIR/ARGO_DOMAIN.log 2>/dev/null) 629 | checkhttp=$(curl --max-time 2 -o /dev/null -s -w "%{http_code}\n" "https://$argogd") 630 | fi 631 | if ([ -z "$ARGO_DOMAIN" ] && ! ps aux | grep '[t]unnel --u' > /dev/null) || [ "$checkhttp" -ne 404 ]; then 632 | ps aux | grep '[t]unnel --u' | awk '{print $2}' | xargs -r kill -9 > /dev/null 2>&1 633 | cfgo 634 | elif ([ -n "$ARGO_DOMAIN" ] && ! ps aux | grep '[t]unnel --n' > /dev/null) || [ "$checkhttp" -ne 404 ]; then 635 | ps aux | grep '[t]unnel --n' | awk '{print $2}' | xargs -r kill -9 > /dev/null 2>&1 636 | cfgo 637 | else 638 | green "Arog进程已启动" 639 | fi 640 | sleep 2 641 | if ! pgrep -x "$(cat sb.txt)" > /dev/null; then 642 | red "主进程未启动,根据以下情况一一排查" 643 | yellow "1、选择8重置端口,自动生成随机可用端口(重要)" 644 | yellow "2、选择9重置" 645 | yellow "3、当前Serv00/Hostuno服务器炸了?等会再试" 646 | red "4、以上都试了,哥直接躺平,交给进程保活,过会再来看" 647 | sleep 6 648 | fi 649 | } 650 | 651 | get_argodomain() { 652 | if [[ -n $ARGO_AUTH ]]; then 653 | echo "$ARGO_DOMAIN" 654 | else 655 | local retry=0 656 | local max_retries=6 657 | local argodomain="" 658 | while [[ $retry -lt $max_retries ]]; do 659 | ((retry++)) 660 | argodomain=$(cat boot.log 2>/dev/null | grep -a trycloudflare.com | awk 'NR==2{print}' | awk -F// '{print $2}' | awk '{print $1}') 661 | if [[ -n $argodomain ]]; then 662 | break 663 | fi 664 | sleep 2 665 | done 666 | if [ -z ${argodomain} ]; then 667 | argodomain="Argo临时域名暂时获取失败,Argo节点暂不可用(保活过程中会自动恢复),其他节点依旧可用" 668 | fi 669 | echo "$argodomain" 670 | fi 671 | } 672 | 673 | get_links(){ 674 | argodomain=$(get_argodomain) 675 | echo -e "\e[1;32mArgo域名:\e[1;35m${argodomain}\e[0m\n" 676 | a=$(dig @8.8.8.8 +time=5 +short "web$nb.${hona}.com" | sort -u) 677 | b=$(dig @8.8.8.8 +time=5 +short "$HOSTNAME" | sort -u) 678 | c=$(dig @8.8.8.8 +time=5 +short "cache$nb.${hona}.com" | sort -u) 679 | if [[ "$IP" == "$a" ]]; then 680 | CIP1=$b; CIP2=$c 681 | elif [[ "$IP" == "$b" ]]; then 682 | CIP1=$a; CIP2=$c 683 | elif [[ "$IP" == "$c" ]]; then 684 | CIP1=$a; CIP2=$b 685 | else 686 | red "执行出错,请卸载脚本再重装一次" 687 | fi 688 | 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#$snb-reality-$USERNAME" 689 | echo "$vl_link" > jh.txt 690 | vmws_link="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-$USERNAME\", \"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)" 691 | echo "$vmws_link" >> jh.txt 692 | vmatls_link="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-tls-argo-$USERNAME\", \"add\": \"www.visa.com.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)" 693 | echo "$vmatls_link" >> jh.txt 694 | vma_link="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-argo-$USERNAME\", \"add\": \"www.visa.com.hk\", \"port\": \"8880\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"auto\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"$argodomain\", \"path\": \"/$UUID-vm?ed=2048\", \"tls\": \"\"}" | base64 -w0)" 695 | echo "$vma_link" >> jh.txt 696 | hy2_link="hysteria2://$UUID@$IP:$hy2_port?security=tls&sni=www.bing.com&alpn=h3&insecure=1#$snb-hy2-$USERNAME" 697 | echo "$hy2_link" >> jh.txt 698 | vl_link1="vless://$UUID@$CIP1:$vless_port?encryption=none&flow=xtls-rprx-vision&security=reality&sni=$reym&fp=chrome&pbk=$public_key&type=tcp&headerType=none#$snb-reality-$USERNAME-$CIP1" 699 | echo "$vl_link1" >> jh.txt 700 | vmws_link1="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-$USERNAME-$CIP1\", \"add\": \"$CIP1\", \"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)" 701 | echo "$vmws_link1" >> jh.txt 702 | hy2_link1="hysteria2://$UUID@$CIP1:$hy2_port?security=tls&sni=www.bing.com&alpn=h3&insecure=1#$snb-hy2-$USERNAME-$CIP1" 703 | echo "$hy2_link1" >> jh.txt 704 | vl_link2="vless://$UUID@$CIP2:$vless_port?encryption=none&flow=xtls-rprx-vision&security=reality&sni=$reym&fp=chrome&pbk=$public_key&type=tcp&headerType=none#$snb-reality-$USERNAME-$CIP2" 705 | echo "$vl_link2" >> jh.txt 706 | vmws_link2="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-$USERNAME-$CIP2\", \"add\": \"$CIP2\", \"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)" 707 | echo "$vmws_link2" >> jh.txt 708 | hy2_link2="hysteria2://$UUID@$CIP2:$hy2_port?security=tls&sni=www.bing.com&alpn=h3&insecure=1#$snb-hy2-$USERNAME-$CIP2" 709 | echo "$hy2_link2" >> jh.txt 710 | 711 | argosl=$(cat "$WORKDIR/boot.log" 2>/dev/null | grep -a trycloudflare.com | awk 'NR==2{print}' | awk -F// '{print $2}' | awk '{print $1}') 712 | checkhttp1=$(curl -o /dev/null -s -w "%{http_code}\n" "https://$argosl") 713 | argogd=$(cat $WORKDIR/ARGO_DOMAIN.log 2>/dev/null) 714 | checkhttp2=$(curl --max-time 2 -o /dev/null -s -w "%{http_code}\n" "https://$argogd") 715 | if [[ "$checkhttp1" == 404 ]] || [[ "$checkhttp2" == 404 ]]; then 716 | vmatls_link1="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-tls-argo-$USERNAME-443\", \"add\": \"104.16.0.0\", \"port\": \"443\", \"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)" 717 | echo "$vmatls_link1" >> jh.txt 718 | vmatls_link2="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-tls-argo-$USERNAME-2053\", \"add\": \"104.17.0.0\", \"port\": \"2053\", \"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)" 719 | echo "$vmatls_link2" >> jh.txt 720 | vmatls_link3="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-tls-argo-$USERNAME-2083\", \"add\": \"104.18.0.0\", \"port\": \"2083\", \"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)" 721 | echo "$vmatls_link3" >> jh.txt 722 | vmatls_link4="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-tls-argo-$USERNAME-2087\", \"add\": \"104.19.0.0\", \"port\": \"2087\", \"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)" 723 | echo "$vmatls_link4" >> jh.txt 724 | vmatls_link5="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-tls-argo-$USERNAME-2096\", \"add\": \"104.20.0.0\", \"port\": \"2096\", \"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)" 725 | echo "$vmatls_link5" >> jh.txt 726 | vma_link6="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-argo-$USERNAME-80\", \"add\": \"104.21.0.0\", \"port\": \"80\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"auto\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"$argodomain\", \"path\": \"/$UUID-vm?ed=2048\", \"tls\": \"\"}" | base64 -w0)" 727 | echo "$vma_link6" >> jh.txt 728 | vma_link7="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-argo-$USERNAME-8080\", \"add\": \"104.22.0.0\", \"port\": \"8080\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"auto\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"$argodomain\", \"path\": \"/$UUID-vm?ed=2048\", \"tls\": \"\"}" | base64 -w0)" 729 | echo "$vma_link7" >> jh.txt 730 | vma_link8="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-argo-$USERNAME-2052\", \"add\": \"104.24.0.0\", \"port\": \"2052\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"auto\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"$argodomain\", \"path\": \"/$UUID-vm?ed=2048\", \"tls\": \"\"}" | base64 -w0)" 731 | echo "$vma_link8" >> jh.txt 732 | vma_link9="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-argo-$USERNAME-2082\", \"add\": \"104.25.0.0\", \"port\": \"2082\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"auto\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"$argodomain\", \"path\": \"/$UUID-vm?ed=2048\", \"tls\": \"\"}" | base64 -w0)" 733 | echo "$vma_link9" >> jh.txt 734 | vma_link10="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-argo-$USERNAME-2086\", \"add\": \"104.26.0.0\", \"port\": \"2086\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"auto\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"$argodomain\", \"path\": \"/$UUID-vm?ed=2048\", \"tls\": \"\"}" | base64 -w0)" 735 | echo "$vma_link10" >> jh.txt 736 | vma_link11="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-argo-$USERNAME-2095\", \"add\": \"104.27.0.0\", \"port\": \"2095\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"auto\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"$argodomain\", \"path\": \"/$UUID-vm?ed=2048\", \"tls\": \"\"}" | base64 -w0)" 737 | echo "$vma_link11" >> jh.txt 738 | fi 739 | v2sub=$(cat jh.txt) 740 | echo "$v2sub" > ${FILE_PATH}/${UUID}_v2sub.txt 741 | baseurl=$(base64 -w 0 < jh.txt) 742 | 743 | cat > sing_box.json < clash_meta.yaml < ${FILE_PATH}/${UUID}_clashmeta.txt 1214 | cat sing_box.json > ${FILE_PATH}/${UUID}_singbox.txt 1215 | V2rayN_LINK="https://${USERNAME}.${address}/${UUID}_v2sub.txt" 1216 | Clashmeta_LINK="https://${USERNAME}.${address}/${UUID}_clashmeta.txt" 1217 | Singbox_LINK="https://${USERNAME}.${address}/${UUID}_singbox.txt" 1218 | hyp=$(jq -r '.inbounds[0].listen_port' config.json) 1219 | vlp=$(jq -r '.inbounds[3].listen_port' config.json) 1220 | vmp=$(jq -r '.inbounds[4].listen_port' config.json) 1221 | showuuid=$(jq -r '.inbounds[0].users[0].password' config.json) 1222 | cat > list.txt < webport.sh 1363 | declare -f resallport >> webport.sh 1364 | declare -f check_port >> webport.sh 1365 | declare -f resservsb >> webport.sh 1366 | echo 'resallport' >> webport.sh 1367 | chmod +x webport.sh 1368 | green "开始安装多功能主页,请稍等……" 1369 | devil www del ${snb}.${USERNAME}.${hona}.net > /dev/null 2>&1 1370 | devil www add ${USERNAME}.${hona}.net php > /dev/null 2>&1 1371 | devil www add ${snb}.${USERNAME}.${hona}.net nodejs /usr/local/bin/node18 > /dev/null 2>&1 1372 | ln -fs /usr/local/bin/node18 ~/bin/node > /dev/null 2>&1 1373 | ln -fs /usr/local/bin/npm18 ~/bin/npm > /dev/null 2>&1 1374 | mkdir -p ~/.npm-global 1375 | npm config set prefix '~/.npm-global' 1376 | echo 'export PATH=~/.npm-global/bin:~/bin:$PATH' >> $HOME/.bash_profile && source $HOME/.bash_profile 1377 | rm -rf $HOME/.npmrc > /dev/null 2>&1 1378 | cd "$keep_path" 1379 | npm install basic-auth express dotenv axios --silent > /dev/null 2>&1 1380 | rm $HOME/domains/${snb}.${USERNAME}.${hona}.net/public_nodejs/public/index.html > /dev/null 2>&1 1381 | devil www restart ${snb}.${USERNAME}.${hona}.net 1382 | curl -sk "http://${snb}.${USERNAME}.${hona}.net/up" > /dev/null 2>&1 1383 | green "安装完毕,多功能主页地址:http://${snb}.${USERNAME}.${hona}.net" && sleep 2 1384 | } 1385 | 1386 | okip(){ 1387 | IP_LIST=($(devil vhost list | awk '/^[0-9]+/ {print $1}')) 1388 | API_URL="https://status.eooce.com/api" 1389 | IP="" 1390 | THIRD_IP=${IP_LIST[2]} 1391 | RESPONSE=$(curl -s --max-time 2 "${API_URL}/${THIRD_IP}") 1392 | if [[ $(echo "$RESPONSE" | jq -r '.status') == "Available" ]]; then 1393 | IP=$THIRD_IP 1394 | else 1395 | FIRST_IP=${IP_LIST[0]} 1396 | RESPONSE=$(curl -s --max-time 2 "${API_URL}/${FIRST_IP}") 1397 | 1398 | if [[ $(echo "$RESPONSE" | jq -r '.status') == "Available" ]]; then 1399 | IP=$FIRST_IP 1400 | else 1401 | IP=${IP_LIST[1]} 1402 | fi 1403 | fi 1404 | echo "$IP" 1405 | } 1406 | 1407 | fastrun(){ 1408 | if [[ -e $WORKDIR/config.json ]]; then 1409 | COMMAND="sb" 1410 | SCRIPT_PATH="$HOME/bin/$COMMAND" 1411 | mkdir -p "$HOME/bin" 1412 | curl -Ls https://raw.githubusercontent.com/yonggekkk/sing-box-yg/main/serv00.sh > "$SCRIPT_PATH" 1413 | chmod +x "$SCRIPT_PATH" 1414 | if [[ ":$PATH:" != *":$HOME/bin:"* ]]; then 1415 | echo 'export PATH="$HOME/bin:$PATH"' >> "$HOME/.bashrc" 1416 | grep -qxF 'source ~/.bashrc' ~/.bash_profile 2>/dev/null || echo 'source ~/.bashrc' >> ~/.bash_profile 1417 | source ~/.bashrc 1418 | fi 1419 | if [ "$hona" = "serv00" ]; then 1420 | curl -sL https://raw.githubusercontent.com/yonggekkk/sing-box-yg/main/app.js -o "$keep_path"/app.js 1421 | sed -i '' "15s/name/$snb/g" "$keep_path"/app.js 1422 | sed -i '' "59s/key/$UUID/g" "$keep_path"/app.js 1423 | sed -i '' "90s/name/$USERNAME/g" "$keep_path"/app.js 1424 | sed -i '' "90s/where/$snb/g" "$keep_path"/app.js 1425 | curl -sSL https://raw.githubusercontent.com/yonggekkk/sing-box-yg/main/serv00keep.sh -o serv00keep.sh && chmod +x serv00keep.sh 1426 | fi 1427 | curl -sL https://raw.githubusercontent.com/yonggekkk/sing-box-yg/main/index.html -o "$FILE_PATH"/index.html 1428 | curl -sL https://raw.githubusercontent.com/yonggekkk/sing-box-yg/main/sversion | awk -F "更新内容" '{print $1}' | head -n 1 > $WORKDIR/v 1429 | else 1430 | red "未安装脚本,请选择1进行安装" && exit 1431 | fi 1432 | } 1433 | 1434 | resservsb(){ 1435 | if [[ -e $WORKDIR/config.json ]]; then 1436 | yellow "重启中……请稍后……" 1437 | cd $WORKDIR 1438 | ps aux | grep '[r]un -c con' | awk '{print $2}' | xargs -r kill -9 > /dev/null 2>&1 1439 | if [ "$hona" = "serv00" ]; then 1440 | curl -sk "http://${snb}.${USERNAME}.${hona}.net/up" > /dev/null 2>&1 1441 | sleep 5 1442 | else 1443 | sbb=$(cat sb.txt) 1444 | nohup ./"$sbb" run -c config.json >/dev/null 2>&1 & 1445 | sleep 1 1446 | fi 1447 | if pgrep -x "$sbb" > /dev/null; then 1448 | green "$sbb 主进程重启成功" 1449 | else 1450 | red "$sbb 主进程重启失败" 1451 | fi 1452 | cd 1453 | else 1454 | red "未安装脚本,请选择1进行安装" && exit 1455 | fi 1456 | } 1457 | 1458 | resargo(){ 1459 | if [[ -e $WORKDIR/config.json ]]; then 1460 | cd $WORKDIR 1461 | argoport=$(jq -r '.inbounds[4].listen_port' config.json) 1462 | yellow "你可以重置临时隧道; 可以继续使用上回的固定隧道; 也可以更换固定隧道的域名或token" 1463 | argogdshow(){ 1464 | echo 1465 | if [ -f ARGO_AUTH_show.log ]; then 1466 | purple "上回设置的Argo固定域名:$(cat ARGO_DOMAIN_show.log 2>/dev/null)" 1467 | purple "上回固定隧道的Token:$(cat ARGO_AUTH_show.log 2>/dev/null)" 1468 | purple "目前检查CF官网的Argo固定隧道端口:$argoport" 1469 | fi 1470 | echo 1471 | } 1472 | if [ -f boot.log ]; then 1473 | green "当前正在使用Argo临时隧道" 1474 | argogdshow 1475 | else 1476 | green "当前正在使用Argo固定隧道" 1477 | argogdshow 1478 | fi 1479 | argo_configure 1480 | ps aux | grep '[t]unnel --u' | awk '{print $2}' | xargs -r kill -9 > /dev/null 2>&1 1481 | ps aux | grep '[t]unnel --n' | awk '{print $2}' | xargs -r kill -9 > /dev/null 2>&1 1482 | agg=$(cat ag.txt) 1483 | if [[ "$argo_choice" =~ (G|g) ]]; then 1484 | if [ "$hona" = "serv00" ]; then 1485 | sed -i '' -e "15s|''|'$(cat ARGO_DOMAIN_show.log 2>/dev/null)'|" ~/serv00keep.sh 1486 | sed -i '' -e "16s|''|'$(cat ARGO_AUTH_show.log 2>/dev/null)'|" ~/serv00keep.sh 1487 | fi 1488 | args="tunnel --no-autoupdate run --token $(cat ARGO_AUTH_show.log)" 1489 | else 1490 | rm -rf boot.log 1491 | if [ "$hona" = "serv00" ]; then 1492 | sed -i '' -e "15s|'$(cat ARGO_DOMAIN_show.log 2>/dev/null)'|''|" ~/serv00keep.sh 1493 | sed -i '' -e "16s|'$(cat ARGO_AUTH_show.log 2>/dev/null)'|''|" ~/serv00keep.sh 1494 | fi 1495 | args="tunnel --url http://localhost:$argoport --no-autoupdate --logfile boot.log --loglevel info" 1496 | fi 1497 | nohup ./"$agg" $args >/dev/null 2>&1 & 1498 | sleep 10 1499 | if pgrep -x "$agg" > /dev/null; then 1500 | green "$agg Argo进程已启动" 1501 | else 1502 | red "$agg Argo进程未启动, 重启中..." 1503 | pkill -x "$agg" 1504 | nohup ./"$agg" "${args}" >/dev/null 2>&1 & 1505 | sleep 5 1506 | purple "$agg Argo进程已重启" 1507 | fi 1508 | showchangelist 1509 | cd 1510 | else 1511 | red "未安装脚本,请选择1进行安装" && exit 1512 | fi 1513 | } 1514 | 1515 | showchangelist(){ 1516 | IP=$(<$WORKDIR/ipone.txt) 1517 | UUID=$(<$WORKDIR/UUID.txt) 1518 | reym=$(<$WORKDIR/reym.txt) 1519 | ARGO_DOMAIN=$(cat "$WORKDIR/ARGO_DOMAIN.log" 2>/dev/null) 1520 | ARGO_AUTH=$(cat "$WORKDIR/ARGO_AUTH.log" 2>/dev/null) 1521 | check_port >/dev/null 2>&1 1522 | download_and_run_singbox >/dev/null 2>&1 1523 | get_links 1524 | } 1525 | 1526 | menu() { 1527 | clear 1528 | echo "============================================================" 1529 | green "甬哥Github项目 :github.com/yonggekkk" 1530 | green "甬哥Blogger博客 :ygkkk.blogspot.com" 1531 | green "甬哥YouTube频道 :www.youtube.com/@ygkkk" 1532 | green "Serv00/Hostuno三协议共存脚本:vless-reality/Vmess-ws(Argo)/Hy2" 1533 | green "脚本快捷方式:sb" 1534 | echo "============================================================" 1535 | green "1. 一键安装 Serv00/Hostuno-sb-yg" 1536 | echo "------------------------------------------------------------" 1537 | yellow "2. 卸载删除 Serv00/Hostuno-sb-yg" 1538 | echo "------------------------------------------------------------" 1539 | green "3. 重启主进程 (修复主节点)" 1540 | echo "------------------------------------------------------------" 1541 | green "4. Argo重置(临时隧道与固定隧道相互切换、更换固定域名)" 1542 | echo "------------------------------------------------------------" 1543 | green "5. 更新脚本" 1544 | echo "------------------------------------------------------------" 1545 | green "6. 查看各节点分享/sing-box与clash订阅链接/反代IP/ProxyIP" 1546 | echo "------------------------------------------------------------" 1547 | green "7. 查看sing-box与clash配置文件" 1548 | echo "------------------------------------------------------------" 1549 | yellow "8. 端口重置并随机生成新端口" 1550 | echo "------------------------------------------------------------" 1551 | red "9. 清理所有服务进程与文件 (系统初始化)" 1552 | echo "------------------------------------------------------------" 1553 | red "0. 退出脚本" 1554 | echo "============================================================" 1555 | ym=("$HOSTNAME" "cache$nb.${hona}.com" "web$nb.${hona}.com") 1556 | rm -rf $WORKDIR/ip.txt 1557 | for host in "${ym[@]}"; do 1558 | response=$(curl -sL --connect-timeout 5 --max-time 7 "https://ss.fkj.pp.ua/api/getip?host=$host") 1559 | if [[ "$response" =~ (unknown|not|error) ]]; then 1560 | dig @8.8.8.8 +time=5 +short $host | sort -u >> $WORKDIR/ip.txt 1561 | sleep 1 1562 | else 1563 | while IFS='|' read -r ip status; do 1564 | if [[ $status == "Accessible" ]]; then 1565 | echo "$ip: 可用" >> $WORKDIR/ip.txt 1566 | else 1567 | echo "$ip: 被墙 (Argo与CDN回源节点、proxyip依旧有效)" >> $WORKDIR/ip.txt 1568 | fi 1569 | done <<< "$response" 1570 | fi 1571 | done 1572 | if [[ ! "$response" =~ (unknown|not|error) ]]; then 1573 | grep ':' $WORKDIR/ip.txt | sort -u -o $WORKDIR/ip.txt 1574 | fi 1575 | if [ "$hona" = "serv00" ]; then 1576 | red "目前免费Serv00使用代理脚本会有被封账号的风险,请知晓!!!" 1577 | fi 1578 | green "${hona}服务器名称:${snb}" 1579 | echo 1580 | green "当前可选择的IP如下:" 1581 | cat $WORKDIR/ip.txt 1582 | echo 1583 | portlist=$(devil port list | grep -E '^[0-9]+[[:space:]]+[a-zA-Z]+' | sed 's/^[[:space:]]*//') 1584 | if [[ -n $portlist ]]; then 1585 | green "已设置的端口如下:" 1586 | echo -e "$portlist" 1587 | else 1588 | yellow "未设置端口" 1589 | fi 1590 | echo 1591 | insV=$(cat $WORKDIR/v 2>/dev/null) 1592 | latestV=$(curl -sL https://raw.githubusercontent.com/yonggekkk/sing-box-yg/main/sversion | awk -F "更新内容" '{print $1}' | head -n 1) 1593 | if [ -f $WORKDIR/v ]; then 1594 | if [ "$insV" = "$latestV" ]; then 1595 | echo -e "当前 Serv00/Hostuno-sb-yg 脚本最新版:${purple}${insV}${re} (已安装)" 1596 | else 1597 | echo -e "当前 Serv00/Hostuno-sb-yg 脚本版本号:${purple}${insV}${re}" 1598 | echo -e "检测到最新 Serv00/Hostuno-sb-yg 脚本版本号:${yellow}${latestV}${re} (可选择5进行更新)" 1599 | echo -e "${yellow}$(curl -sL https://raw.githubusercontent.com/yonggekkk/sing-box-yg/main/sversion)${re}" 1600 | fi 1601 | echo -e "=========================================================" 1602 | sbb=$(cat $WORKDIR/sb.txt 2>/dev/null) 1603 | if pgrep -x "$sbb" > /dev/null; then 1604 | green "Sing-box主进程运行正常" 1605 | else 1606 | yellow "Sing-box主进程启动失败,建议先选择3重启,依旧失败就选择8重置端口,再选择9卸载重装" 1607 | fi 1608 | if [ -f "$WORKDIR/boot.log" ]; then 1609 | argosl=$(cat "$WORKDIR/boot.log" 2>/dev/null | grep -a trycloudflare.com | awk 'NR==2{print}' | awk -F// '{print $2}' | awk '{print $1}') 1610 | checkhttp=$(curl -o /dev/null -s -w "%{http_code}\n" "https://$argosl") 1611 | [[ "$checkhttp" == 404 ]] && check="域名有效" || check="临时域名暂时无效,如已启用保活,后续会自动恢复有效" 1612 | green "Argo临时域名:$argosl $check" 1613 | else 1614 | argogd=$(cat $WORKDIR/ARGO_DOMAIN.log 2>/dev/null) 1615 | checkhttp=$(curl --max-time 2 -o /dev/null -s -w "%{http_code}\n" "https://$argogd") 1616 | if [[ "$checkhttp" == 404 ]]; then 1617 | check="域名有效" 1618 | elif [[ "$argogd" =~ ddns|cloudns|dynamic|cloud-ip ]]; then 1619 | check="域名可能有效,请自行检测argo节点是否可用" 1620 | else 1621 | check="固定域名无效,请检查域名、端口、密钥token是否输入有误" 1622 | fi 1623 | green "Argo固定域名:$argogd $check" 1624 | fi 1625 | if [ "$hona" = "serv00" ]; then 1626 | green "多功能主页如下 (支持保活、重启、重置端口、进程查看、节点查询)" 1627 | purple "http://${snb}.${USERNAME}.${hona}.net" 1628 | fi 1629 | else 1630 | echo -e "当前 Serv00/Hostuno-sb-yg 脚本版本号:${purple}${latestV}${re}" 1631 | yellow "未安装 Serv00/Hostuno-sb-yg 脚本!请选择 1 安装" 1632 | fi 1633 | echo -e "=========================================================" 1634 | reading "请输入选择【0-9】: " choice 1635 | echo 1636 | case "${choice}" in 1637 | 1) install_singbox ;; 1638 | 2) uninstall_singbox ;; 1639 | 3) resservsb ;; 1640 | 4) resargo ;; 1641 | 5) fastrun && green "脚本已更新成功" && sleep 2 && sb ;; 1642 | 6) showlist ;; 1643 | 7) showsbclash ;; 1644 | 8) resallport ;; 1645 | 9) kill_all_tasks ;; 1646 | 0) exit 0 ;; 1647 | *) red "无效的选项,请输入 0 到 9" ;; 1648 | esac 1649 | } 1650 | menu 1651 | -------------------------------------------------------------------------------- /serv00.yml: -------------------------------------------------------------------------------- 1 | name: Keep Servers Alive 2 | # 如果你已安装了Serv00本地SSH脚本,不要再运行此github部署了,这样会造成进程爆满,必须二选一! 3 | on: 4 | #如使用保活网页,请禁用cron,保持下面两行开头的#符号,以防止cron与网页保活重复运行造成进程爆满 5 | #schedule: 6 | # - cron: '0 */4 * * *' # 每4小时执行一次(私库每月500分钟运行时长,每天16分钟) 7 | workflow_dispatch: 8 | 9 | jobs: 10 | keep_servers_alive: 11 | runs-on: ubuntu-latest 12 | env: 13 | # serv00变量添加规则: 14 | # RES(必填):n表示每次不重置部署,y表示每次重置部署。REP(必填):n表示不重置随机端口(三个端口留空),y表示重置端口(三个端口留空)。SSH_USER(必填)表示serv00账号名。SSH_PASS(必填)表示serv00密码。REALITY表示reality域名(留空表示serv00官方域名:你serv00账号名.serv00.net)。SUUID表示uuid(留空表示随机uuid)。TCP1_PORT表示vless的tcp端口(留空表示随机tcp端口)。TCP2_PORT表示vmess的tcp端口(留空表示随机tcp端口)。UDP_PORT表示hy2的udp端口(留空表示随机udp端口)。HOST(必填)表示登录serv00服务器域名。ARGO_DOMAIN表示argo固定域名(留空表示临时域名)。ARGO_AUTH表示argo固定域名token(留空表示临时域名)。 15 | # 必填变量:RES、REP、SSH_USER、SSH_PASS、HOST 16 | # 注意[]"",:这些符号不要乱删,按规律对齐 17 | # 每行一个{serv00服务器},一个服务也可,末尾用,间隔,最后一个服务器末尾无需用,间隔 18 | ACCOUNTS: > 19 | [ 20 | {"RES":"n", "REP":"n", "SSH_USER":"你的serv00账号名", "SSH_PASS":"你的serv00账号密码", "REALITY":"你serv00账号名.serv00.net", "SUUID":"自设UUID", "TCP1_PORT":"vless的tcp端口", "TCP2_PORT":"vmess的tcp端口", "UDP_PORT":"hy2的udp端口", "HOST":"s1.serv00.com", "ARGO_DOMAIN":"", "ARGO_AUTH":""}, 21 | {"RES":"y", "REP":"y", "SSH_USER":"123456", "SSH_PASS":"7890000", "REALITY":"time.is", "SUUID":"73203ee6-b3fa-4a3d-b5df-6bb2f55073ad", "TCP1_PORT":"", "TCP2_PORT":"", "UDP_PORT":"", "HOST":"s16.serv00.com", "ARGO_DOMAIN":"你的argo固定域名", "ARGO_AUTH":"eyJhIjoiOTM3YzFjYWI88552NTFiYTM4ZTY0ZDQzRmlNelF0TkRBd1pUQTRNVEJqTUdVeCJ9"} 22 | ] 23 | steps: 24 | - name: Checkout Repository 25 | uses: actions/checkout@v2 26 | 27 | - name: Install required packages 28 | run: | 29 | sudo apt-get update 30 | sudo apt-get install -y sshpass curl jq 31 | 32 | - name: Process each account 33 | run: | 34 | run_remote_command() { 35 | local RES=$1 36 | local REP=$2 37 | local SSH_USER=$3 38 | local SSH_PASS=$4 39 | local REALITY=${5} 40 | local SUUID=$6 41 | local TCP1_PORT=$7 42 | local TCP2_PORT=$8 43 | local UDP_PORT=$9 44 | local HOST=${10} 45 | local ARGO_DOMAIN=${11} 46 | local ARGO_AUTH=${12} 47 | if [ -z "${ARGO_DOMAIN}" ]; then 48 | echo "Argo域名为空,申请Argo临时域名" 49 | else 50 | echo "Argo已设置固定域名:${ARGO_DOMAIN}" 51 | fi 52 | remote_command="export reym=$REALITY UUID=$SUUID vless_port=$TCP1_PORT vmess_port=$TCP2_PORT hy2_port=$UDP_PORT reset=$RES resport=$REP ARGO_DOMAIN=${ARGO_DOMAIN} ARGO_AUTH=${ARGO_AUTH} && bash <(curl -Ls https://raw.githubusercontent.com/yonggekkk/sing-box-yg/main/serv00keep.sh)" 53 | echo "Executing remote command on $HOST as $SSH_USER with command: $remote_command" 54 | sshpass -p "$SSH_PASS" ssh -o StrictHostKeyChecking=no "$SSH_USER@$HOST" "$remote_command" 55 | } 56 | echo "*****************************************************" 57 | echo "*****************************************************" 58 | echo "甬哥Github项目 :github.com/yonggekkk" 59 | echo "甬哥Blogger博客 :ygkkk.blogspot.com" 60 | echo "甬哥YouTube频道 :www.youtube.com/@ygkkk" 61 | echo "自动远程部署并保活Serv00三合一协议脚本【Github】" 62 | echo "版本:V25.3.26" 63 | echo "*****************************************************" 64 | echo "*****************************************************" 65 | count=0 66 | for account in $(echo "${ACCOUNTS}" | jq -c '.[]'); do 67 | count=$((count+1)) 68 | RES=$(echo $account | jq -r '.RES') 69 | REP=$(echo $account | jq -r '.REP') 70 | SSH_USER=$(echo $account | jq -r '.SSH_USER') 71 | SSH_PASS=$(echo $account | jq -r '.SSH_PASS') 72 | REALITY=$(echo $account | jq -r '.REALITY') 73 | SUUID=$(echo $account | jq -r '.SUUID') 74 | TCP1_PORT=$(echo $account | jq -r '.TCP1_PORT') 75 | TCP2_PORT=$(echo $account | jq -r '.TCP2_PORT') 76 | UDP_PORT=$(echo $account | jq -r '.UDP_PORT') 77 | HOST=$(echo $account | jq -r '.HOST') 78 | ARGO_DOMAIN=$(echo $account | jq -r '.ARGO_DOMAIN') 79 | ARGO_AUTH=$(echo $account | jq -r '.ARGO_AUTH') 80 | if sshpass -p "$SSH_PASS" ssh -o StrictHostKeyChecking=no "$SSH_USER@$HOST" -q exit; then 81 | echo "🎉恭喜!✅第【$count】台服务器连接成功!🚀服务器地址:$HOST ,账户名:$SSH_USER" 82 | if [ -z "${ARGO_DOMAIN}" ]; then 83 | check_process="ps aux | grep '[c]onfig' > /dev/null && ps aux | grep [l]ocalhost:$TCP2_PORT > /dev/null" 84 | else 85 | check_process="ps aux | grep '[c]onfig' > /dev/null && ps aux | grep '[t]oken $ARGO_AUTH' > /dev/null" 86 | fi 87 | if ! sshpass -p "$SSH_PASS" ssh -o StrictHostKeyChecking=no "$SSH_USER@$HOST" "$check_process" || [[ "$RES" =~ ^[Yy]$ ]]; then 88 | echo "⚠️检测到主进程或者argo进程未启动,或者执行重置" 89 | echo "⚠️现在开始修复或重置部署……请稍等" 90 | output=$(run_remote_command "$RES" "$REP" "$SSH_USER" "$SSH_PASS" "${REALITY}" "$SUUID" "$TCP1_PORT" "$TCP2_PORT" "$UDP_PORT" "$HOST" "${ARGO_DOMAIN}" "${ARGO_AUTH}") 91 | echo "远程命令执行结果:$output" 92 | else 93 | echo "🎉恭喜!✅检测到所有进程正常运行中 " 94 | SSH_USER_LOWER=$(echo "$SSH_USER" | tr '[:upper:]' '[:lower:]') 95 | sshpass -p "$SSH_PASS" ssh -o StrictHostKeyChecking=no "$SSH_USER@$HOST" " 96 | echo \"配置显示如下:\" 97 | cat domains/${SSH_USER_LOWER}.serv00.net/logs/list.txt 98 | echo \"====================================================\" 99 | " 100 | fi 101 | else 102 | echo "====================================================" 103 | echo "💥杯具!❌第【$count】台服务器连接失败!🚀服务器地址:$HOST ,账户名:$SSH_USER" 104 | echo "⚠️可能账号名、密码、服务器名称输入错误,或者当前服务器在维护中" 105 | echo "====================================================" 106 | fi 107 | done 108 | -------------------------------------------------------------------------------- /serv00keep.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # 定义颜色 3 | re="\033[0m" 4 | red="\033[1;91m" 5 | green="\e[1;32m" 6 | yellow="\e[1;33m" 7 | purple="\e[1;35m" 8 | red() { echo -e "\e[1;91m$1\033[0m"; } 9 | green() { echo -e "\e[1;32m$1\033[0m"; } 10 | yellow() { echo -e "\e[1;33m$1\033[0m"; } 11 | purple() { echo -e "\e[1;35m$1\033[0m"; } 12 | reading() { read -p "$(red "$1")" "$2"; } 13 | export LC_ALL=C 14 | export UUID=${UUID:-''} 15 | export ARGO_DOMAIN=${ARGO_DOMAIN:-''} 16 | export ARGO_AUTH=${ARGO_AUTH:-''} 17 | export vless_port=${vless_port:-''} 18 | export vmess_port=${vmess_port:-''} 19 | export hy2_port=${hy2_port:-''} 20 | export IP=${IP:-''} 21 | export reym=${reym:-''} 22 | export reset=${reset:-''} 23 | export resport=${resport:-''} 24 | devil binexec on >/dev/null 2>&1 25 | USERNAME=$(whoami | tr '[:upper:]' '[:lower:]') 26 | HOSTNAME=$(hostname) 27 | snb=$(hostname | cut -d. -f1) 28 | nb=$(hostname | cut -d '.' -f 1 | tr -d 's') 29 | if [[ "$reset" =~ ^[Yy]$ ]]; then 30 | bash -c 'ps aux | grep $(whoami) | grep -v "sshd\|bash\|grep" | awk "{print \$2}" | xargs -r kill -9 >/dev/null 2>&1' >/dev/null 2>&1 31 | devil www list | awk 'NR > 1 && NF {print $1}' | xargs -I {} devil www del {} > /dev/null 2>&1 32 | sed -i '/export PATH="\$HOME\/bin:\$PATH"/d' "${HOME}/.bashrc" >/dev/null 2>&1 33 | source "${HOME}/.bashrc" >/dev/null 2>&1 34 | find ~ -type f -exec chmod 644 {} \; 2>/dev/null 35 | find ~ -type d -exec chmod 755 {} \; 2>/dev/null 36 | find ~ -type f -exec rm -f {} \; 2>/dev/null 37 | find ~ -type d -empty -exec rmdir {} \; 2>/dev/null 38 | find ~ -exec rm -rf {} \; 2>/dev/null 39 | echo "重置系统完成" 40 | fi 41 | devil www add ${USERNAME}.serv00.net php > /dev/null 2>&1 42 | FILE_PATH="${HOME}/domains/${USERNAME}.serv00.net/public_html" 43 | WORKDIR="${HOME}/domains/${USERNAME}.serv00.net/logs" 44 | [ -d "$FILE_PATH" ] || mkdir -p "$FILE_PATH" 45 | [ -d "$WORKDIR" ] || (mkdir -p "$WORKDIR" && chmod 777 "$WORKDIR") 46 | keep_path="${HOME}/domains/${snb}.${USERNAME}.serv00.net/public_nodejs" 47 | [ -d "$keep_path" ] || mkdir -p "$keep_path" 48 | 49 | if [[ -z "$ARGO_AUTH" ]] && [[ -f "$WORKDIR/ARGO_AUTH.log" ]]; then 50 | ARGO_AUTH=$(cat "$WORKDIR/ARGO_AUTH.log" 2>/dev/null) 51 | elif [[ -z "$ARGO_AUTH" ]] && [[ ! -f "$WORKDIR/ARGO_AUTH.log" ]]; then 52 | echo "$ARGO_AUTH" > $WORKDIR/ARGO_AUTH.log 53 | else 54 | echo "$ARGO_AUTH" > $WORKDIR/ARGO_AUTH.log 55 | ARGO_AUTH=$(cat "$WORKDIR/ARGO_AUTH.log" 2>/dev/null) 56 | fi 57 | if [[ -z "$ARGO_DOMAIN" ]] && [[ -f "$WORKDIR/ARGO_DOMAIN.log" ]]; then 58 | ARGO_DOMAIN=$(cat "$WORKDIR/ARGO_DOMAIN.log" 2>/dev/null) 59 | elif [[ -z "$ARGO_DOMAIN" ]] && [[ ! -f "$WORKDIR/ARGO_DOMAIN.log" ]]; then 60 | echo "$ARGO_DOMAIN" > $WORKDIR/ARGO_DOMAIN.log 61 | else 62 | echo "$ARGO_DOMAIN" > $WORKDIR/ARGO_DOMAIN.log 63 | ARGO_DOMAIN=$(cat "$WORKDIR/ARGO_DOMAIN.log" 2>/dev/null) 64 | fi 65 | 66 | if [[ -z "$UUID" ]] && [[ -f "$WORKDIR/UUID.txt" ]]; then 67 | UUID=$(cat "$WORKDIR/UUID.txt" 2>/dev/null) 68 | elif [[ -z "$UUID" ]] && [[ ! -f "$WORKDIR/UUID.txt" ]]; then 69 | UUID=$(uuidgen -r) 70 | echo "$UUID" > $WORKDIR/UUID.txt 71 | else 72 | echo "$UUID" > $WORKDIR/UUID.txt 73 | UUID=$(cat "$WORKDIR/UUID.txt" 2>/dev/null) 74 | fi 75 | curl -sL https://raw.githubusercontent.com/yonggekkk/sing-box-yg/main/app.js -o "$keep_path"/app.js 76 | sed -i '' "15s/name/$snb/g" "$keep_path"/app.js 77 | sed -i '' "59s/key/$UUID/g" "$keep_path"/app.js 78 | sed -i '' "90s/name/$USERNAME/g" "$keep_path"/app.js 79 | sed -i '' "90s/where/$snb/g" "$keep_path"/app.js 80 | if [[ -z "$reym" ]] && [[ -f "$WORKDIR/reym.txt" ]]; then 81 | reym=$(cat "$WORKDIR/reym.txt" 2>/dev/null) 82 | elif [[ -z "$reym" ]] && [[ ! -f "$WORKDIR/reym.txt" ]]; then 83 | reym=$USERNAME.serv00.net 84 | echo "$reym" > $WORKDIR/reym.txt 85 | else 86 | echo "$reym" > $WORKDIR/reym.txt 87 | reym=$(cat "$WORKDIR/reym.txt" 2>/dev/null) 88 | fi 89 | 90 | resallport(){ 91 | portlist=$(devil port list | grep -E '^[0-9]+[[:space:]]+[a-zA-Z]+' | sed 's/^[[:space:]]*//') 92 | if [[ -z "$portlist" ]]; then 93 | yellow "无端口" 94 | else 95 | while read -r line; do 96 | port=$(echo "$line" | awk '{print $1}') 97 | port_type=$(echo "$line" | awk '{print $2}') 98 | yellow "删除端口 $port ($port_type)" 99 | devil port del "$port_type" "$port" 100 | done <<< "$portlist" 101 | fi 102 | check_port 103 | hyp=$(jq -r '.inbounds[0].listen_port' $WORKDIR/config.json) 104 | vlp=$(jq -r '.inbounds[3].listen_port' $WORKDIR/config.json) 105 | vmp=$(jq -r '.inbounds[4].listen_port' $WORKDIR/config.json) 106 | sed -i '' "12s/$hyp/$hy2_port/g" $WORKDIR/config.json 107 | sed -i '' "33s/$hyp/$hy2_port/g" $WORKDIR/config.json 108 | sed -i '' "54s/$hyp/$hy2_port/g" $WORKDIR/config.json 109 | sed -i '' "75s/$vlp/$vless_port/g" $WORKDIR/config.json 110 | sed -i '' "102s/$vmp/$vmess_port/g" $WORKDIR/config.json 111 | sed -i '' -e "17s|'$vlp'|'$vless_port'|" serv00keep.sh 112 | sed -i '' -e "18s|'$vmp'|'$vmess_port'|" serv00keep.sh 113 | sed -i '' -e "19s|'$hyp'|'$hy2_port'|" serv00keep.sh 114 | ps aux | grep '[r]un -c con' | awk '{print $2}' | xargs -r kill -9 > /dev/null 2>&1 115 | sleep 1 116 | curl -sk "http://${snb}.${USERNAME}.serv00.net/up" > /dev/null 2>&1 117 | sleep 5 118 | } 119 | 120 | okip(){ 121 | IP_LIST=($(devil vhost list | awk '/^[0-9]+/ {print $1}')) 122 | API_URL="https://status.eooce.com/api" 123 | IP="" 124 | THIRD_IP=${IP_LIST[2]} 125 | RESPONSE=$(curl -s --max-time 2 "${API_URL}/${THIRD_IP}") 126 | if [[ $(echo "$RESPONSE" | jq -r '.status') == "Available" ]]; then 127 | IP=$THIRD_IP 128 | else 129 | FIRST_IP=${IP_LIST[0]} 130 | RESPONSE=$(curl -s --max-time 2 "${API_URL}/${FIRST_IP}") 131 | 132 | if [[ $(echo "$RESPONSE" | jq -r '.status') == "Available" ]]; then 133 | IP=$FIRST_IP 134 | else 135 | IP=${IP_LIST[1]} 136 | fi 137 | fi 138 | echo "$IP" 139 | } 140 | 141 | check_port(){ 142 | port_list=$(devil port list) 143 | tcp_ports=$(echo "$port_list" | grep -c "tcp") 144 | udp_ports=$(echo "$port_list" | grep -c "udp") 145 | if [[ $tcp_ports -ne 2 || $udp_ports -ne 1 ]]; then 146 | echo "端口数量不符合要求,正在调整..." 147 | 148 | if [[ $tcp_ports -gt 2 ]]; then 149 | tcp_to_delete=$((tcp_ports - 2)) 150 | echo "$port_list" | awk '/tcp/ {print $1, $2}' | head -n $tcp_to_delete | while read port type; do 151 | devil port del $type $port 152 | echo "已删除TCP端口: $port" 153 | done 154 | fi 155 | 156 | if [[ $udp_ports -gt 1 ]]; then 157 | udp_to_delete=$((udp_ports - 1)) 158 | echo "$port_list" | awk '/udp/ {print $1, $2}' | head -n $udp_to_delete | while read port type; do 159 | devil port del $type $port 160 | echo "已删除UDP端口: $port" 161 | done 162 | fi 163 | 164 | if [[ $tcp_ports -lt 2 ]]; then 165 | tcp_ports_to_add=$((2 - tcp_ports)) 166 | tcp_ports_added=0 167 | while [[ $tcp_ports_added -lt $tcp_ports_to_add ]]; do 168 | tcp_port=$(shuf -i 10000-65535 -n 1) 169 | result=$(devil port add tcp $tcp_port 2>&1) 170 | if [[ $result == *"succesfully"* ]]; then 171 | echo "已添加TCP端口: $tcp_port" 172 | if [[ $tcp_ports_added -eq 0 ]]; then 173 | tcp_port1=$tcp_port 174 | else 175 | tcp_port2=$tcp_port 176 | fi 177 | tcp_ports_added=$((tcp_ports_added + 1)) 178 | else 179 | echo "端口 $tcp_port 不可用,尝试其他端口..." 180 | fi 181 | done 182 | fi 183 | 184 | if [[ $udp_ports -lt 1 ]]; then 185 | while true; do 186 | udp_port=$(shuf -i 10000-65535 -n 1) 187 | result=$(devil port add udp $udp_port 2>&1) 188 | if [[ $result == *"succesfully"* ]]; then 189 | echo "已添加UDP端口: $udp_port" 190 | break 191 | else 192 | echo "端口 $udp_port 不可用,尝试其他端口..." 193 | fi 194 | done 195 | fi 196 | #echo "端口已调整完成,将断开ssh连接" 197 | sleep 3 198 | #devil binexec on >/dev/null 2>&1 199 | #kill -9 $(ps -o ppid= -p $$) >/dev/null 2>&1 200 | port_list=$(devil port list) 201 | tcp_ports=$(echo "$port_list" | grep -c "tcp") 202 | udp_ports=$(echo "$port_list" | grep -c "udp") 203 | tcp_ports=$(echo "$port_list" | awk '/tcp/ {print $1}') 204 | tcp_port1=$(echo "$tcp_ports" | sed -n '1p') 205 | tcp_port2=$(echo "$tcp_ports" | sed -n '2p') 206 | udp_port=$(echo "$port_list" | awk '/udp/ {print $1}') 207 | purple "当前TCP端口: $tcp_port1 和 $tcp_port2" 208 | purple "当前UDP端口: $udp_port" 209 | else 210 | tcp_ports=$(echo "$port_list" | awk '/tcp/ {print $1}') 211 | tcp_port1=$(echo "$tcp_ports" | sed -n '1p') 212 | tcp_port2=$(echo "$tcp_ports" | sed -n '2p') 213 | udp_port=$(echo "$port_list" | awk '/udp/ {print $1}') 214 | echo "你的vless-reality的TCP端口: $tcp_port1" 215 | echo "你的vmess的TCP端口(设置Argo固定域名端口):$tcp_port2" 216 | echo "你的hysteria2的UDP端口: $udp_port" 217 | fi 218 | export vless_port=$tcp_port1 219 | export vmess_port=$tcp_port2 220 | export hy2_port=$udp_port 221 | } 222 | 223 | get_argodomain() { 224 | if [[ -n $ARGO_AUTH ]]; then 225 | echo "$ARGO_DOMAIN" > ARGO_DOMAIN.log 226 | echo "$ARGO_DOMAIN" 227 | else 228 | local retry=0 229 | local max_retries=6 230 | local argodomain="" 231 | while [[ $retry -lt $max_retries ]]; do 232 | ((retry++)) 233 | argodomain=$(cat boot.log 2>/dev/null | grep -a trycloudflare.com | awk 'NR==2{print}' | awk -F// '{print $2}' | awk '{print $1}') 234 | if [[ -n $argodomain ]]; then 235 | break 236 | fi 237 | sleep 2 238 | done 239 | if [ -z ${argodomain} ]; then 240 | argodomain="Argo临时域名暂时获取失败,Argo节点暂不可用(保活过程中会自动恢复),其他节点依旧可用" 241 | fi 242 | echo "$argodomain" 243 | fi 244 | } 245 | 246 | if [ ! -f serv00keep.sh ]; then 247 | curl -sSL https://raw.githubusercontent.com/yonggekkk/sing-box-yg/main/serv00keep.sh -o serv00keep.sh && chmod +x serv00keep.sh 248 | echo '#!/bin/bash 249 | red() { echo -e "\e[1;91m$1\033[0m"; } 250 | green() { echo -e "\e[1;32m$1\033[0m"; } 251 | yellow() { echo -e "\e[1;33m$1\033[0m"; } 252 | purple() { echo -e "\e[1;35m$1\033[0m"; } 253 | USERNAME=$(whoami | tr '\''[:upper:]'\'' '\''[:lower:]'\'') 254 | WORKDIR="${HOME}/domains/${USERNAME}.serv00.net/logs" 255 | snb=$(hostname | cut -d. -f1) 256 | ' > webport.sh 257 | declare -f resallport >> webport.sh 258 | declare -f check_port >> webport.sh 259 | echo 'resallport' >> webport.sh 260 | chmod +x webport.sh 261 | green "开始安装多功能主页,请稍等……" 262 | devil www del ${snb}.${USERNAME}.serv00.net > /dev/null 2>&1 263 | devil www add ${USERNAME}.serv00.net php > /dev/null 2>&1 264 | devil www add ${snb}.${USERNAME}.serv00.net nodejs /usr/local/bin/node18 > /dev/null 2>&1 265 | ln -fs /usr/local/bin/node18 ~/bin/node > /dev/null 2>&1 266 | ln -fs /usr/local/bin/npm18 ~/bin/npm > /dev/null 2>&1 267 | mkdir -p ~/.npm-global 268 | npm config set prefix '~/.npm-global' 269 | echo 'export PATH=~/.npm-global/bin:~/bin:$PATH' >> $HOME/.bash_profile && source $HOME/.bash_profile 270 | rm -rf $HOME/.npmrc > /dev/null 2>&1 271 | cd "$keep_path" 272 | npm install basic-auth express dotenv axios --silent > /dev/null 2>&1 273 | rm $HOME/domains/${snb}.${USERNAME}.serv00.net/public_nodejs/public/index.html > /dev/null 2>&1 274 | devil www restart ${snb}.${USERNAME}.serv00.net 275 | green "安装完毕,多功能主页地址:http://${snb}.${USERNAME}.serv00.net" 276 | fi 277 | 278 | if [[ "$resport" =~ ^[Yy]$ ]]; then 279 | portlist=$(devil port list | grep -E '^[0-9]+[[:space:]]+[a-zA-Z]+' | sed 's/^[[:space:]]*//') 280 | if [[ -z "$portlist" ]]; then 281 | yellow "无端口" 282 | else 283 | while read -r line; do 284 | port=$(echo "$line" | awk '{print $1}') 285 | port_type=$(echo "$line" | awk '{print $2}') 286 | yellow "删除端口 $port ($port_type)" 287 | devil port del "$port_type" "$port" 288 | done <<< "$portlist" 289 | fi 290 | check_port 291 | fi 292 | rm -rf $HOME/domains/${snb}.${USERNAME}.serv00.net/logs/* 293 | 294 | cd $WORKDIR 295 | ym=("$HOSTNAME" "cache$nb.serv00.com" "web$nb.serv00.com") 296 | rm -rf ip.txt 297 | for host in "${ym[@]}"; do 298 | response=$(curl -sL --connect-timeout 5 --max-time 7 "https://ss.fkj.pp.ua/api/getip?host=$host") 299 | if [[ "$response" =~ (unknown|not|error) ]]; then 300 | dig @8.8.8.8 +time=5 +short $host | sort -u >> ip.txt 301 | sleep 1 302 | else 303 | while IFS='|' read -r ip status; do 304 | if [[ $status == "Accessible" ]]; then 305 | echo "$ip: 可用" >> ip.txt 306 | else 307 | echo "$ip: 被墙 (Argo与CDN回源节点、proxyip依旧有效)" >> ip.txt 308 | fi 309 | done <<< "$response" 310 | fi 311 | done 312 | if [[ ! "$response" =~ (unknown|not|error) ]]; then 313 | grep ':' $WORKDIR/ip.txt | sort -u -o $WORKDIR/ip.txt 314 | fi 315 | if [[ -z "$IP" ]]; then 316 | IP=$(grep -m 1 "可用" ip.txt | awk -F ':' '{print $1}') 317 | if [ -z "$IP" ]; then 318 | IP=$(okip) 319 | if [ -z "$IP" ]; then 320 | IP=$(head -n 1 ip.txt | awk -F ':' '{print $1}') 321 | fi 322 | fi 323 | fi 324 | 325 | if [[ -z "$vless_port" ]] || [[ -z "$vmess_port" ]] || [[ -z "$hy2_port" ]]; then 326 | check_port 327 | fi 328 | if [ ! -s sb.txt ] && [ ! -s ag.txt ]; then 329 | DOWNLOAD_DIR="." && mkdir -p "$DOWNLOAD_DIR" && FILE_INFO=() 330 | 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") 331 | declare -A FILE_MAP 332 | generate_random_name() { 333 | local chars=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890 334 | local name="" 335 | for i in {1..6}; do 336 | name="$name${chars:RANDOM%${#chars}:1}" 337 | done 338 | echo "$name" 339 | } 340 | 341 | download_with_fallback() { 342 | local URL=$1 343 | local NEW_FILENAME=$2 344 | 345 | curl -L -sS --max-time 2 -o "$NEW_FILENAME" "$URL" & 346 | CURL_PID=$! 347 | CURL_START_SIZE=$(stat -c%s "$NEW_FILENAME" 2>/dev/null || echo 0) 348 | 349 | sleep 1 350 | CURL_CURRENT_SIZE=$(stat -c%s "$NEW_FILENAME" 2>/dev/null || echo 0) 351 | 352 | if [ "$CURL_CURRENT_SIZE" -le "$CURL_START_SIZE" ]; then 353 | kill $CURL_PID 2>/dev/null 354 | wait $CURL_PID 2>/dev/null 355 | wget -q -O "$NEW_FILENAME" "$URL" 356 | echo -e "\e[1;32mDownloading $NEW_FILENAME by wget\e[0m" 357 | else 358 | wait $CURL_PID 359 | echo -e "\e[1;32mDownloading $NEW_FILENAME by curl\e[0m" 360 | fi 361 | } 362 | 363 | for entry in "${FILE_INFO[@]}"; do 364 | URL=$(echo "$entry" | cut -d ' ' -f 1) 365 | RANDOM_NAME=$(generate_random_name) 366 | NEW_FILENAME="$DOWNLOAD_DIR/$RANDOM_NAME" 367 | 368 | if [ -e "$NEW_FILENAME" ]; then 369 | echo -e "\e[1;32m$NEW_FILENAME already exists, Skipping download\e[0m" 370 | else 371 | download_with_fallback "$URL" "$NEW_FILENAME" 372 | fi 373 | 374 | chmod +x "$NEW_FILENAME" 375 | FILE_MAP[$(echo "$entry" | cut -d ' ' -f 2)]="$NEW_FILENAME" 376 | done 377 | wait 378 | fi 379 | 380 | if [ ! -e private_key.txt ]; then 381 | output=$(./"$(basename ${FILE_MAP[web]})" generate reality-keypair) 382 | private_key=$(echo "${output}" | awk '/PrivateKey:/ {print $2}') 383 | public_key=$(echo "${output}" | awk '/PublicKey:/ {print $2}') 384 | echo "${private_key}" > private_key.txt 385 | echo "${public_key}" > public_key.txt 386 | fi 387 | private_key=$( config.json << EOF 392 | { 393 | "log": { 394 | "disabled": true, 395 | "level": "info", 396 | "timestamp": true 397 | }, 398 | "inbounds": [ 399 | { 400 | "tag": "hysteria-in1", 401 | "type": "hysteria2", 402 | "listen": "$(dig @8.8.8.8 +time=5 +short "web$nb.serv00.com" | sort -u)", 403 | "listen_port": $hy2_port, 404 | "users": [ 405 | { 406 | "password": "$UUID" 407 | } 408 | ], 409 | "masquerade": "https://www.bing.com", 410 | "ignore_client_bandwidth":false, 411 | "tls": { 412 | "enabled": true, 413 | "alpn": [ 414 | "h3" 415 | ], 416 | "certificate_path": "cert.pem", 417 | "key_path": "private.key" 418 | } 419 | }, 420 | { 421 | "tag": "hysteria-in2", 422 | "type": "hysteria2", 423 | "listen": "$(dig @8.8.8.8 +time=5 +short "$HOSTNAME" | sort -u)", 424 | "listen_port": $hy2_port, 425 | "users": [ 426 | { 427 | "password": "$UUID" 428 | } 429 | ], 430 | "masquerade": "https://www.bing.com", 431 | "ignore_client_bandwidth":false, 432 | "tls": { 433 | "enabled": true, 434 | "alpn": [ 435 | "h3" 436 | ], 437 | "certificate_path": "cert.pem", 438 | "key_path": "private.key" 439 | } 440 | }, 441 | { 442 | "tag": "hysteria-in3", 443 | "type": "hysteria2", 444 | "listen": "$(dig @8.8.8.8 +time=5 +short "cache$nb.serv00.com" | sort -u)", 445 | "listen_port": $hy2_port, 446 | "users": [ 447 | { 448 | "password": "$UUID" 449 | } 450 | ], 451 | "masquerade": "https://www.bing.com", 452 | "ignore_client_bandwidth":false, 453 | "tls": { 454 | "enabled": true, 455 | "alpn": [ 456 | "h3" 457 | ], 458 | "certificate_path": "cert.pem", 459 | "key_path": "private.key" 460 | } 461 | }, 462 | { 463 | "tag": "vless-reality-vesion", 464 | "type": "vless", 465 | "listen": "::", 466 | "listen_port": $vless_port, 467 | "users": [ 468 | { 469 | "uuid": "$UUID", 470 | "flow": "xtls-rprx-vision" 471 | } 472 | ], 473 | "tls": { 474 | "enabled": true, 475 | "server_name": "$reym", 476 | "reality": { 477 | "enabled": true, 478 | "handshake": { 479 | "server": "$reym", 480 | "server_port": 443 481 | }, 482 | "private_key": "$private_key", 483 | "short_id": [ 484 | "" 485 | ] 486 | } 487 | } 488 | }, 489 | { 490 | "tag": "vmess-ws-in", 491 | "type": "vmess", 492 | "listen": "::", 493 | "listen_port": $vmess_port, 494 | "users": [ 495 | { 496 | "uuid": "$UUID" 497 | } 498 | ], 499 | "transport": { 500 | "type": "ws", 501 | "path": "$UUID-vm", 502 | "early_data_header_name": "Sec-WebSocket-Protocol" 503 | } 504 | } 505 | ], 506 | "outbounds": [ 507 | { 508 | "type": "wireguard", 509 | "tag": "wg", 510 | "server": "162.159.192.200", 511 | "server_port": 4500, 512 | "local_address": [ 513 | "172.16.0.2/32", 514 | "2606:4700:110:8f77:1ca9:f086:846c:5f9e/128" 515 | ], 516 | "private_key": "wIxszdR2nMdA7a2Ul3XQcniSfSZqdqjPb6w6opvf5AU=", 517 | "peer_public_key": "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=", 518 | "reserved": [ 519 | 126, 520 | 246, 521 | 173 522 | ] 523 | }, 524 | { 525 | "type": "direct", 526 | "tag": "direct" 527 | } 528 | ], 529 | "route": { 530 | "rule_set": [ 531 | { 532 | "tag": "google-gemini", 533 | "type": "remote", 534 | "format": "binary", 535 | "url": "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/google-gemini.srs", 536 | "download_detour": "direct" 537 | } 538 | ], 539 | EOF 540 | if [[ "$nb" =~ 14|15 ]]; then 541 | cat >> config.json <> config.json < /dev/null; then 569 | ps aux | grep '[r]un -c con' | awk '{print $2}' | xargs -r kill -9 > /dev/null 2>&1 570 | if [ -e "$(basename "${FILE_MAP[web]}")" ]; then 571 | echo "$(basename "${FILE_MAP[web]}")" > sb.txt 572 | sbb=$(cat sb.txt) 573 | nohup ./"$sbb" run -c config.json >/dev/null 2>&1 & 574 | sleep 5 575 | if pgrep -x "$sbb" > /dev/null; then 576 | green "$sbb 主进程已启动" 577 | else 578 | red "$sbb 主进程未启动, 重启中..." 579 | pkill -x "$sbb" 580 | nohup ./"$sbb" run -c config.json >/dev/null 2>&1 & 581 | sleep 2 582 | purple "$sbb 主进程已重启" 583 | fi 584 | else 585 | sbb=$(cat sb.txt) 586 | nohup ./"$sbb" run -c config.json >/dev/null 2>&1 & 587 | sleep 5 588 | if pgrep -x "$sbb" > /dev/null; then 589 | green "$sbb 主进程已启动" 590 | else 591 | red "$sbb 主进程未启动, 重启中..." 592 | pkill -x "$sbb" 593 | nohup ./"$sbb" run -c config.json >/dev/null 2>&1 & 594 | sleep 2 595 | purple "$sbb 主进程已重启" 596 | fi 597 | fi 598 | else 599 | green "主进程已启动" 600 | fi 601 | cfgo() { 602 | rm -rf boot.log 603 | if [ -e "$(basename "${FILE_MAP[bot]}")" ]; then 604 | echo "$(basename "${FILE_MAP[bot]}")" > ag.txt 605 | agg=$(cat ag.txt) 606 | if [[ $ARGO_AUTH =~ ^[A-Z0-9a-z=]{120,250}$ ]]; then 607 | #args="tunnel --edge-ip-version auto --no-autoupdate --protocol http2 run --token ${ARGO_AUTH}" 608 | args="tunnel --no-autoupdate run --token ${ARGO_AUTH}" 609 | else 610 | #args="tunnel --edge-ip-version auto --no-autoupdate --protocol http2 --logfile boot.log --loglevel info --url http://localhost:$vmess_port" 611 | args="tunnel --url http://localhost:$vmess_port --no-autoupdate --logfile boot.log --loglevel info" 612 | fi 613 | nohup ./"$agg" $args >/dev/null 2>&1 & 614 | sleep 10 615 | if pgrep -x "$agg" > /dev/null; then 616 | green "$agg Arog进程已启动" 617 | else 618 | red "$agg Argo进程未启动, 重启中..." 619 | pkill -x "$agg" 620 | nohup ./"$agg" "${args}" >/dev/null 2>&1 & 621 | sleep 5 622 | purple "$agg Argo进程已重启" 623 | fi 624 | else 625 | agg=$(cat ag.txt) 626 | if [[ $ARGO_AUTH =~ ^[A-Z0-9a-z=]{120,250}$ ]]; then 627 | #args="tunnel --edge-ip-version auto --no-autoupdate --protocol http2 run --token ${ARGO_AUTH}" 628 | args="tunnel --no-autoupdate run --token ${ARGO_AUTH}" 629 | else 630 | #args="tunnel --edge-ip-version auto --no-autoupdate --protocol http2 --logfile boot.log --loglevel info --url http://localhost:$vmess_port" 631 | args="tunnel --url http://localhost:$vmess_port --no-autoupdate --logfile boot.log --loglevel info" 632 | fi 633 | pkill -x "$agg" 634 | nohup ./"$agg" $args >/dev/null 2>&1 & 635 | sleep 10 636 | if pgrep -x "$agg" > /dev/null; then 637 | green "$agg Arog进程已启动" 638 | else 639 | red "$agg Argo进程未启动, 重启中..." 640 | pkill -x "$agg" 641 | nohup ./"$agg" "${args}" >/dev/null 2>&1 & 642 | sleep 5 643 | purple "$agg Argo进程已重启" 644 | fi 645 | fi 646 | } 647 | 648 | if [ -f "$WORKDIR/boot.log" ]; then 649 | argosl=$(cat "$WORKDIR/boot.log" 2>/dev/null | grep -a trycloudflare.com | awk 'NR==2{print}' | awk -F// '{print $2}' | awk '{print $1}') 650 | checkhttp=$(curl -o /dev/null -s -w "%{http_code}\n" "https://$argosl") 651 | fi 652 | if ([ -z "$ARGO_DOMAIN" ] && ! ps aux | grep '[t]unnel --u' > /dev/null) || [[ "$checkhttp" != 404 ]]; then 653 | ps aux | grep '[t]unnel --u' | awk '{print $2}' | xargs -r kill -9 > /dev/null 2>&1 654 | cfgo 655 | elif [ -n "$ARGO_DOMAIN" ] && ! ps aux | grep '[t]unnel --n' > /dev/null; then 656 | ps aux | grep '[t]unnel --n' | awk '{print $2}' | xargs -r kill -9 > /dev/null 2>&1 657 | cfgo 658 | else 659 | green "Arog进程已启动" 660 | fi 661 | sleep 2 662 | if ! pgrep -x "$(cat sb.txt)" > /dev/null; then 663 | red "主进程未启动,根据以下情况一一排查" 664 | yellow "1、REP选择y重置一次随机端口,三个端口参数留空不填,再改为n(重要)" 665 | yellow "2、RES选择y运行一次重置系统,再改为n(重要)" 666 | yellow "3、当前Serv00服务器炸了?等会再试" 667 | red "4、以上都试了,哥直接躺平,交给进程保活,过会再来看" 668 | fi 669 | 670 | 671 | argodomain=$(get_argodomain) 672 | rm -rf ${FILE_PATH}/*.txt 673 | echo -e "\e[1;32mArgo域名:\e[1;35m${argodomain}\e[0m\n" 674 | a=$(dig @8.8.8.8 +time=5 +short "web$nb.serv00.com" | sort -u) 675 | b=$(dig @8.8.8.8 +time=5 +short "$HOSTNAME" | sort -u) 676 | c=$(dig @8.8.8.8 +time=5 +short "cache$nb.serv00.com" | sort -u) 677 | if [[ "$IP" == "$a" ]]; then 678 | CIP1=$b; CIP2=$c 679 | elif [[ "$IP" == "$b" ]]; then 680 | CIP1=$a; CIP2=$c 681 | elif [[ "$IP" == "$c" ]]; then 682 | CIP1=$a; CIP2=$b 683 | else 684 | red "执行出错,请卸载脚本再重装一次" 685 | fi 686 | 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#$snb-reality-$USERNAME" 687 | echo "$vl_link" > jh.txt 688 | vmws_link="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-$USERNAME\", \"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)" 689 | echo "$vmws_link" >> jh.txt 690 | vmatls_link="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-tls-argo-$USERNAME\", \"add\": \"www.visa.com.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)" 691 | echo "$vmatls_link" >> jh.txt 692 | vma_link="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-argo-$USERNAME\", \"add\": \"www.visa.com.hk\", \"port\": \"8880\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"auto\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"$argodomain\", \"path\": \"/$UUID-vm?ed=2048\", \"tls\": \"\"}" | base64 -w0)" 693 | echo "$vma_link" >> jh.txt 694 | hy2_link="hysteria2://$UUID@$IP:$hy2_port?security=tls&sni=www.bing.com&alpn=h3&insecure=1#$snb-hy2-$USERNAME" 695 | echo "$hy2_link" >> jh.txt 696 | vl_link1="vless://$UUID@$CIP1:$vless_port?encryption=none&flow=xtls-rprx-vision&security=reality&sni=$reym&fp=chrome&pbk=$public_key&type=tcp&headerType=none#$snb-reality-$USERNAME-$CIP1" 697 | echo "$vl_link1" >> jh.txt 698 | vmws_link1="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-$USERNAME-$CIP1\", \"add\": \"$CIP1\", \"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)" 699 | echo "$vmws_link1" >> jh.txt 700 | hy2_link1="hysteria2://$UUID@$CIP1:$hy2_port?security=tls&sni=www.bing.com&alpn=h3&insecure=1#$snb-hy2-$USERNAME-$CIP1" 701 | echo "$hy2_link1" >> jh.txt 702 | vl_link2="vless://$UUID@$CIP2:$vless_port?encryption=none&flow=xtls-rprx-vision&security=reality&sni=$reym&fp=chrome&pbk=$public_key&type=tcp&headerType=none#$snb-reality-$USERNAME-$CIP2" 703 | echo "$vl_link2" >> jh.txt 704 | vmws_link2="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-$USERNAME-$CIP2\", \"add\": \"$CIP2\", \"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)" 705 | echo "$vmws_link2" >> jh.txt 706 | hy2_link2="hysteria2://$UUID@$CIP2:$hy2_port?security=tls&sni=www.bing.com&alpn=h3&insecure=1#$snb-hy2-$USERNAME-$CIP2" 707 | echo "$hy2_link2" >> jh.txt 708 | 709 | argosl=$(cat "$WORKDIR/boot.log" 2>/dev/null | grep -a trycloudflare.com | awk 'NR==2{print}' | awk -F// '{print $2}' | awk '{print $1}') 710 | checkhttp1=$(curl -o /dev/null -s -w "%{http_code}\n" "https://$argosl") 711 | argogd=$(cat $WORKDIR/ARGO_DOMAIN.log 2>/dev/null) 712 | checkhttp2=$(curl --max-time 2 -o /dev/null -s -w "%{http_code}\n" "https://$argogd") 713 | if [[ "$checkhttp1" == 404 ]] || [[ "$checkhttp2" == 404 ]]; then 714 | vmatls_link1="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-tls-argo-$USERNAME-443\", \"add\": \"104.16.0.0\", \"port\": \"443\", \"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)" 715 | echo "$vmatls_link1" >> jh.txt 716 | vmatls_link2="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-tls-argo-$USERNAME-2053\", \"add\": \"104.17.0.0\", \"port\": \"2053\", \"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)" 717 | echo "$vmatls_link2" >> jh.txt 718 | vmatls_link3="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-tls-argo-$USERNAME-2083\", \"add\": \"104.18.0.0\", \"port\": \"2083\", \"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)" 719 | echo "$vmatls_link3" >> jh.txt 720 | vmatls_link4="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-tls-argo-$USERNAME-2087\", \"add\": \"104.19.0.0\", \"port\": \"2087\", \"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)" 721 | echo "$vmatls_link4" >> jh.txt 722 | vmatls_link5="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-tls-argo-$USERNAME-2096\", \"add\": \"104.20.0.0\", \"port\": \"2096\", \"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)" 723 | echo "$vmatls_link5" >> jh.txt 724 | vma_link6="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-argo-$USERNAME-80\", \"add\": \"104.21.0.0\", \"port\": \"80\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"auto\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"$argodomain\", \"path\": \"/$UUID-vm?ed=2048\", \"tls\": \"\"}" | base64 -w0)" 725 | echo "$vma_link6" >> jh.txt 726 | vma_link7="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-argo-$USERNAME-8080\", \"add\": \"104.22.0.0\", \"port\": \"8080\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"auto\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"$argodomain\", \"path\": \"/$UUID-vm?ed=2048\", \"tls\": \"\"}" | base64 -w0)" 727 | echo "$vma_link7" >> jh.txt 728 | vma_link8="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-argo-$USERNAME-2052\", \"add\": \"104.24.0.0\", \"port\": \"2052\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"auto\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"$argodomain\", \"path\": \"/$UUID-vm?ed=2048\", \"tls\": \"\"}" | base64 -w0)" 729 | echo "$vma_link8" >> jh.txt 730 | vma_link9="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-argo-$USERNAME-2082\", \"add\": \"104.25.0.0\", \"port\": \"2082\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"auto\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"$argodomain\", \"path\": \"/$UUID-vm?ed=2048\", \"tls\": \"\"}" | base64 -w0)" 731 | echo "$vma_link9" >> jh.txt 732 | vma_link10="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-argo-$USERNAME-2086\", \"add\": \"104.26.0.0\", \"port\": \"2086\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"auto\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"$argodomain\", \"path\": \"/$UUID-vm?ed=2048\", \"tls\": \"\"}" | base64 -w0)" 733 | echo "$vma_link10" >> jh.txt 734 | vma_link11="vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$snb-vmess-ws-argo-$USERNAME-2095\", \"add\": \"104.27.0.0\", \"port\": \"2095\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"auto\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"$argodomain\", \"path\": \"/$UUID-vm?ed=2048\", \"tls\": \"\"}" | base64 -w0)" 735 | echo "$vma_link11" >> jh.txt 736 | fi 737 | v2sub=$(cat jh.txt) 738 | echo "$v2sub" > ${FILE_PATH}/${UUID}_v2sub.txt 739 | baseurl=$(base64 -w 0 < jh.txt) 740 | 741 | cat > sing_box.json < clash_meta.yaml < ${FILE_PATH}/${UUID}_clashmeta.txt 1212 | cat sing_box.json > ${FILE_PATH}/${UUID}_singbox.txt 1213 | curl -sL https://raw.githubusercontent.com/yonggekkk/sing-box-yg/main/index.html -o "$FILE_PATH"/index.html 1214 | V2rayN_LINK="https://${USERNAME}.serv00.net/${UUID}_v2sub.txt" 1215 | Clashmeta_LINK="https://${USERNAME}.serv00.net/${UUID}_clashmeta.txt" 1216 | Singbox_LINK="https://${USERNAME}.serv00.net/${UUID}_singbox.txt" 1217 | hyp=$(jq -r '.inbounds[0].listen_port' config.json) 1218 | vlp=$(jq -r '.inbounds[3].listen_port' config.json) 1219 | vmp=$(jq -r '.inbounds[4].listen_port' config.json) 1220 | showuuid=$(jq -r '.inbounds[0].users[0].password' config.json) 1221 | cat > list.txt < event.waitUntil(handleScheduled())); 2 | // 配合甬哥的serv00的SSH脚本或者Github/VPS/软路由脚本,生成保活网页与重启网页 3 | // 每个保活/up网页或每个重启/re网页之间用空格或者,或者,间隔开,网页前带http:// 4 | const urlString = 'http://保活或重启网页1 http://保活或重启网页2 http://保活或重启网页3 ………'; 5 | const urls = urlString.split(/[\s,,]+/); 6 | const TIMEOUT = 5000; 7 | async function fetchWithTimeout(url) { 8 | const controller = new AbortController(); 9 | const timeout = setTimeout(() => controller.abort(), TIMEOUT); 10 | try { 11 | await fetch(url, { signal: controller.signal }); 12 | console.log(`✅ 成功: ${url}`); 13 | } catch (error) { 14 | console.warn(`❌ 访问失败: ${url}, 错误: ${error.message}`); 15 | } finally { 16 | clearTimeout(timeout); 17 | } 18 | } 19 | async function handleScheduled() { 20 | console.log('⏳ 任务开始'); 21 | await Promise.all(urls.map(fetchWithTimeout)); 22 | console.log('📊 任务结束'); 23 | } 24 | --------------------------------------------------------------------------------