mirror of
https://github.com/schroinerxy/Sing-box.git
synced 2026-06-22 04:35:49 +08:00
546 lines
18 KiB
Bash
546 lines
18 KiB
Bash
#!/bin/bash
|
||
|
||
re="\033[0m"
|
||
red="\033[1;91m"
|
||
green="\e[1;32m"
|
||
yellow="\e[1;33m"
|
||
purple="\e[1;35m"
|
||
red() { echo -e "\e[1;91m$1\033[0m"; }
|
||
green() { echo -e "\e[1;32m$1\033[0m"; }
|
||
yellow() { echo -e "\e[1;33m$1\033[0m"; }
|
||
purple() { echo -e "\e[1;35m$1\033[0m"; }
|
||
reading() { read -p "$(red "$1")" "$2"; }
|
||
export LC_ALL=C
|
||
USERNAME=$(whoami)
|
||
HOSTNAME=$(hostname)
|
||
export UUID=${UUID:-'bc97f674-c578-4940-9234-0a1da46041b9'}
|
||
export NEZHA_SERVER=${NEZHA_SERVER:-''}
|
||
export NEZHA_PORT=${NEZHA_PORT:-'5555'}
|
||
export NEZHA_KEY=${NEZHA_KEY:-''}
|
||
export ARGO_DOMAIN=${ARGO_DOMAIN:-''}
|
||
export ARGO_AUTH=${ARGO_AUTH:-''}
|
||
export CFIP=${CFIP:-'www.visa.com.tw'}
|
||
export CFPORT=${CFPORT:-'443'}
|
||
|
||
[[ "$HOSTNAME" == "s1.ct8.pl" ]] && WORKDIR="domains/${USERNAME}.ct8.pl/logs" || WORKDIR="domains/${USERNAME}.serv00.net/logs"
|
||
[ -d "$WORKDIR" ] || (mkdir -p "$WORKDIR" && chmod 777 "$WORKDIR")
|
||
ps aux | grep $(whoami) | grep -v "sshd\|bash\|grep" | awk '{print $2}' | xargs -r kill -9 2>/dev/null
|
||
|
||
read_vmess_port() {
|
||
while true; do
|
||
reading "请输入vmess端口 (面板开放的tcp端口): " vmess_port
|
||
if [[ "$vmess_port" =~ ^[0-9]+$ ]] && [ "$vmess_port" -ge 1 ] && [ "$vmess_port" -le 65535 ]; then
|
||
green "你的vmess端口为: $vmess_port"
|
||
break
|
||
else
|
||
yellow "输入错误,请重新输入面板开放的TCP端口"
|
||
fi
|
||
done
|
||
}
|
||
|
||
read_hy2_port() {
|
||
while true; do
|
||
reading "请输入hysteria2端口 (面板开放的UDP端口): " hy2_port
|
||
if [[ "$hy2_port" =~ ^[0-9]+$ ]] && [ "$hy2_port" -ge 1 ] && [ "$hy2_port" -le 65535 ]; then
|
||
green "你的hysteria2端口为: $hy2_port"
|
||
break
|
||
else
|
||
yellow "输入错误,请重新输入面板开放的UDP端口"
|
||
fi
|
||
done
|
||
}
|
||
|
||
read_tuic_port() {
|
||
while true; do
|
||
reading "请输入Tuic端口 (面板开放的UDP端口): " tuic_port
|
||
if [[ "$tuic_port" =~ ^[0-9]+$ ]] && [ "$tuic_port" -ge 1 ] && [ "$tuic_port" -le 65535 ]; then
|
||
green "你的tuic端口为: $tuic_port"
|
||
break
|
||
else
|
||
yellow "输入错误,请重新输入面板开放的UDP端口"
|
||
fi
|
||
done
|
||
}
|
||
|
||
read_nz_variables() {
|
||
if [ -n "$NEZHA_SERVER" ] && [ -n "$NEZHA_PORT" ] && [ -n "$NEZHA_KEY" ]; then
|
||
green "使用自定义变量哪吒运行哪吒探针"
|
||
return
|
||
else
|
||
reading "是否需要安装哪吒探针?【y/n】: " nz_choice
|
||
[[ -z $nz_choice ]] && return
|
||
[[ "$nz_choice" != "y" && "$nz_choice" != "Y" ]] && return
|
||
reading "请输入哪吒探针域名或ip:" NEZHA_SERVER
|
||
green "你的哪吒域名为: $NEZHA_SERVER"
|
||
reading "请输入哪吒探针端口(回车跳过默认使用5555):" NEZHA_PORT
|
||
[[ -z $NEZHA_PORT ]] && NEZHA_PORT="5555"
|
||
green "你的哪吒端口为: $NEZHA_PORT"
|
||
reading "请输入哪吒探针密钥:" NEZHA_KEY
|
||
green "你的哪吒密钥为: $NEZHA_KEY"
|
||
fi
|
||
}
|
||
|
||
install_singbox() {
|
||
echo -e "${yellow}本脚本同时四协议共存${purple}(vmess-ws,vmess-ws-tls(argo),hysteria2,tuic)${re}"
|
||
echo -e "${yellow}开始运行前,请确保在面板${purple}已开放3个端口,一个tcp端口和两个udp端口${re}"
|
||
echo -e "${yellow}面板${purple}Additional services中的Run your own applications${yellow}已开启为${purplw}Enabled${yellow}状态${re}"
|
||
reading "\n确定继续安装吗?【y/n】: " choice
|
||
case "$choice" in
|
||
[Yy])
|
||
cd $WORKDIR
|
||
read_nz_variables
|
||
read_vmess_port
|
||
read_hy2_port
|
||
read_tuic_port
|
||
argo_configure
|
||
generate_config
|
||
download_singbox
|
||
get_links
|
||
;;
|
||
[Nn]) exit 0 ;;
|
||
*) red "无效的选择,请输入y或n" && menu ;;
|
||
esac
|
||
}
|
||
|
||
uninstall_singbox() {
|
||
reading "\n确定要卸载吗?【y/n】: " choice
|
||
case "$choice" in
|
||
[Yy])
|
||
ps aux | grep $(whoami) | grep -v "sshd\|bash\|grep" | awk '{print $2}' | xargs -r kill -9 2>/dev/null
|
||
rm -rf $WORKDIR
|
||
clear
|
||
green “四合一已完全卸载”
|
||
;;
|
||
[Nn]) exit 0 ;;
|
||
*) red "无效的选择,请输入y或n" && menu ;;
|
||
esac
|
||
}
|
||
|
||
kill_all_tasks() {
|
||
reading "\n清理所有进程将退出ssh连接,确定继续清理吗?【y/n】: " choice
|
||
case "$choice" in
|
||
[Yy]) killall -9 -u $(whoami) ;;
|
||
*) menu ;;
|
||
esac
|
||
}
|
||
|
||
# Generating argo Config
|
||
argo_configure() {
|
||
if [[ -z $ARGO_AUTH || -z $ARGO_DOMAIN ]]; then
|
||
reading "是否需要使用固定argo隧道?【y/n】: " argo_choice
|
||
[[ -z $argo_choice ]] && return
|
||
[[ "$argo_choice" != "y" && "$argo_choice" != "Y" && "$argo_choice" != "n" && "$argo_choice" != "N" ]] && { red "无效的选择,请输入y或n"; return; }
|
||
if [[ "$argo_choice" == "y" || "$argo_choice" == "Y" ]]; then
|
||
reading "请输入argo固定隧道域名: " ARGO_DOMAIN
|
||
green "你的argo固定隧道域名为: $ARGO_DOMAIN"
|
||
reading "请输入argo固定隧道密钥(Json或Token): " ARGO_AUTH
|
||
green "你的argo固定隧道密钥为: $ARGO_AUTH"
|
||
echo -e "${red}注意:${purple}使用token,需要在cloudflare后台设置隧道端口和面板开放的tcp端口一致${re}"
|
||
else
|
||
green "ARGO隧道变量未设置,将使用临时隧道"
|
||
return
|
||
fi
|
||
fi
|
||
|
||
if [[ $ARGO_AUTH =~ TunnelSecret ]]; then
|
||
echo $ARGO_AUTH > tunnel.json
|
||
cat > tunnel.yml << EOF
|
||
tunnel: $(cut -d\" -f12 <<< "$ARGO_AUTH")
|
||
credentials-file: tunnel.json
|
||
protocol: http2
|
||
|
||
ingress:
|
||
- hostname: $ARGO_DOMAIN
|
||
service: http://localhost:$vmess_port
|
||
originRequest:
|
||
noTLSVerify: true
|
||
- service: http_status:404
|
||
EOF
|
||
else
|
||
green "ARGO_AUTH mismatch TunnelSecret,use token connect to tunnel"
|
||
fi
|
||
}
|
||
|
||
# Generating Configuration Files
|
||
generate_config() {
|
||
|
||
openssl ecparam -genkey -name prime256v1 -out "private.key"
|
||
openssl req -new -x509 -days 3650 -key "private.key" -out "cert.pem" -subj "/CN=$USERNAME.serv00.net"
|
||
|
||
cat > config.json << EOF
|
||
{
|
||
"log": {
|
||
"disabled": true,
|
||
"level": "info",
|
||
"timestamp": true
|
||
},
|
||
"dns": {
|
||
"servers": [
|
||
{
|
||
"tag": "google",
|
||
"address": "tls://8.8.8.8",
|
||
"strategy": "ipv4_only",
|
||
"detour": "direct"
|
||
}
|
||
],
|
||
"rules": [
|
||
{
|
||
"rule_set": [
|
||
"geosite-openai"
|
||
],
|
||
"server": "wireguard"
|
||
},
|
||
{
|
||
"rule_set": [
|
||
"geosite-netflix"
|
||
],
|
||
"server": "wireguard"
|
||
},
|
||
{
|
||
"rule_set": [
|
||
"geosite-category-ads-all"
|
||
],
|
||
"server": "block"
|
||
}
|
||
],
|
||
"final": "google",
|
||
"strategy": "",
|
||
"disable_cache": false,
|
||
"disable_expire": false
|
||
},
|
||
"inbounds": [
|
||
{
|
||
"tag": "hysteria-in",
|
||
"type": "hysteria2",
|
||
"listen": "::",
|
||
"listen_port": $hy2_port,
|
||
"users": [
|
||
{
|
||
"password": "$UUID"
|
||
}
|
||
],
|
||
"masquerade": "https://bing.com",
|
||
"tls": {
|
||
"enabled": true,
|
||
"alpn": [
|
||
"h3"
|
||
],
|
||
"certificate_path": "cert.pem",
|
||
"key_path": "private.key"
|
||
}
|
||
},
|
||
{
|
||
"tag": "vmess-ws-in",
|
||
"type": "vmess",
|
||
"listen": "::",
|
||
"listen_port": $vmess_port,
|
||
"users": [
|
||
{
|
||
"uuid": "$UUID"
|
||
}
|
||
],
|
||
"transport": {
|
||
"type": "ws",
|
||
"path": "/vmess",
|
||
"early_data_header_name": "Sec-WebSocket-Protocol"
|
||
}
|
||
},
|
||
{
|
||
"tag": "tuic-in",
|
||
"type": "tuic",
|
||
"listen": "::",
|
||
"listen_port": $tuic_port,
|
||
"users": [
|
||
{
|
||
"uuid": "$UUID",
|
||
"password": "admin123"
|
||
}
|
||
],
|
||
"congestion_control": "bbr",
|
||
"tls": {
|
||
"enabled": true,
|
||
"alpn": [
|
||
"h3"
|
||
],
|
||
"certificate_path": "cert.pem",
|
||
"key_path": "private.key"
|
||
}
|
||
}
|
||
|
||
],
|
||
"outbounds": [
|
||
{
|
||
"type": "direct",
|
||
"tag": "direct"
|
||
},
|
||
{
|
||
"type": "block",
|
||
"tag": "block"
|
||
},
|
||
{
|
||
"type": "dns",
|
||
"tag": "dns-out"
|
||
},
|
||
{
|
||
"type": "wireguard",
|
||
"tag": "wireguard-out",
|
||
"server": "162.159.195.100",
|
||
"server_port": 4500,
|
||
"local_address": [
|
||
"172.16.0.2/32",
|
||
"2606:4700:110:83c7:b31f:5858:b3a8:c6b1/128"
|
||
],
|
||
"private_key": "mPZo+V9qlrMGCZ7+E6z2NI6NOV34PD++TpAR09PtCWI=",
|
||
"peer_public_key": "bmXOC+F1FxEMF9dyiK2H5/1SUtzH0JuVo51h2wPfgyo=",
|
||
"reserved": [
|
||
26,
|
||
21,
|
||
228
|
||
]
|
||
}
|
||
],
|
||
"route": {
|
||
"rules": [
|
||
{
|
||
"protocol": "dns",
|
||
"outbound": "dns-out"
|
||
},
|
||
{
|
||
"ip_is_private": true,
|
||
"outbound": "direct"
|
||
},
|
||
{
|
||
"rule_set": [
|
||
"geosite-openai"
|
||
],
|
||
"outbound": "wireguard-out"
|
||
},
|
||
{
|
||
"rule_set": [
|
||
"geosite-netflix"
|
||
],
|
||
"outbound": "wireguard-out"
|
||
},
|
||
{
|
||
"rule_set": [
|
||
"geosite-category-ads-all"
|
||
],
|
||
"outbound": "block"
|
||
}
|
||
],
|
||
"rule_set": [
|
||
{
|
||
"tag": "geosite-netflix",
|
||
"type": "remote",
|
||
"format": "binary",
|
||
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-netflix.srs",
|
||
"download_detour": "direct"
|
||
},
|
||
{
|
||
"tag": "geosite-openai",
|
||
"type": "remote",
|
||
"format": "binary",
|
||
"url": "https://raw.githubusercontent.com/MetaCubeX/meta-rules-dat/sing/geo/geosite/openai.srs",
|
||
"download_detour": "direct"
|
||
},
|
||
{
|
||
"tag": "geosite-category-ads-all",
|
||
"type": "remote",
|
||
"format": "binary",
|
||
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-category-ads-all.srs",
|
||
"download_detour": "direct"
|
||
}
|
||
],
|
||
"final": "direct"
|
||
},
|
||
"experimental": {
|
||
"cache_file": {
|
||
"path": "cache.db",
|
||
"cache_id": "mycacheid",
|
||
"store_fakeip": true
|
||
}
|
||
}
|
||
}
|
||
EOF
|
||
}
|
||
|
||
# Download Dependency Files
|
||
download_singbox() {
|
||
ARCH=$(uname -m) && DOWNLOAD_DIR="." && mkdir -p "$DOWNLOAD_DIR" && FILE_INFO=()
|
||
if [ "$ARCH" == "arm" ] || [ "$ARCH" == "arm64" ] || [ "$ARCH" == "aarch64" ]; then
|
||
FILE_INFO=("https://github.com/eooce/test/releases/download/arm64/sb web" "https://github.com/eooce/test/releases/download/arm64/bot13 bot" "https://github.com/eooce/test/releases/download/ARM/swith npm")
|
||
elif [ "$ARCH" == "amd64" ] || [ "$ARCH" == "x86_64" ] || [ "$ARCH" == "x86" ]; then
|
||
FILE_INFO=("https://github.com/eooce/test/releases/download/freebsd/sb web" "https://github.com/eooce/test/releases/download/freebsd/server bot" "https://github.com/eooce/test/releases/download/freebsd/npm npm")
|
||
else
|
||
echo "Unsupported architecture: $ARCH"
|
||
exit 1
|
||
fi
|
||
declare -A FILE_MAP
|
||
generate_random_name() {
|
||
local chars=abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890
|
||
local name=""
|
||
for i in {1..6}; do
|
||
name="$name${chars:RANDOM%${#chars}:1}"
|
||
done
|
||
echo "$name"
|
||
}
|
||
|
||
download_with_fallback() {
|
||
local URL=$1
|
||
local NEW_FILENAME=$2
|
||
|
||
curl -L -sS --max-time 2 -o "$NEW_FILENAME" "$URL" &
|
||
CURL_PID=$!
|
||
CURL_START_SIZE=$(stat -c%s "$NEW_FILENAME" 2>/dev/null || echo 0)
|
||
|
||
sleep 1
|
||
CURL_CURRENT_SIZE=$(stat -c%s "$NEW_FILENAME" 2>/dev/null || echo 0)
|
||
|
||
if [ "$CURL_CURRENT_SIZE" -le "$CURL_START_SIZE" ]; then
|
||
kill $CURL_PID 2>/dev/null
|
||
wait $CURL_PID 2>/dev/null
|
||
wget -q -O "$NEW_FILENAME" "$URL"
|
||
echo -e "\e[1;32mDownloading $NEW_FILENAME by wget\e[0m"
|
||
else
|
||
wait $CURL_PID
|
||
echo -e "\e[1;32mDownloading $NEW_FILENAME by curl\e[0m"
|
||
fi
|
||
}
|
||
|
||
for entry in "${FILE_INFO[@]}"; do
|
||
URL=$(echo "$entry" | cut -d ' ' -f 1)
|
||
RANDOM_NAME=$(generate_random_name)
|
||
NEW_FILENAME="$DOWNLOAD_DIR/$RANDOM_NAME"
|
||
|
||
if [ -e "$NEW_FILENAME" ]; then
|
||
echo -e "\e[1;32m$NEW_FILENAME already exists, Skipping download\e[0m"
|
||
else
|
||
download_with_fallback "$URL" "$NEW_FILENAME"
|
||
fi
|
||
|
||
chmod +x "$NEW_FILENAME"
|
||
FILE_MAP[$(echo "$entry" | cut -d ' ' -f 2)]="$NEW_FILENAME"
|
||
done
|
||
wait
|
||
|
||
if [ -e "$(basename ${FILE_MAP[npm]})" ]; then
|
||
tlsPorts=("443" "8443" "2096" "2087" "2083" "2053")
|
||
if [[ "${tlsPorts[*]}" =~ "${NEZHA_PORT}" ]]; then
|
||
NEZHA_TLS="--tls"
|
||
else
|
||
NEZHA_TLS=""
|
||
fi
|
||
if [ -n "$NEZHA_SERVER" ] && [ -n "$NEZHA_PORT" ] && [ -n "$NEZHA_KEY" ]; then
|
||
export TMPDIR=$(pwd)
|
||
nohup ./"$(basename ${FILE_MAP[npm]})" -s ${NEZHA_SERVER}:${NEZHA_PORT} -p ${NEZHA_KEY} ${NEZHA_TLS} >/dev/null 2>&1 &
|
||
sleep 2
|
||
pgrep -x "$(basename ${FILE_MAP[npm]})" > /dev/null && green "$(basename ${FILE_MAP[npm]}) is running" || { red "$(basename ${FILE_MAP[npm]}) is not running, restarting..."; pkill -x "$(basename ${FILE_MAP[npm]})" && nohup ./"$(basename ${FILE_MAP[npm]})" -s "${NEZHA_SERVER}:${NEZHA_PORT}" -p "${NEZHA_KEY}" ${NEZHA_TLS} >/dev/null 2>&1 & sleep 2; purple "$(basename ${FILE_MAP[npm]}) restarted"; }
|
||
else
|
||
purple "NEZHA variable is empty, skipping running"
|
||
fi
|
||
fi
|
||
|
||
if [ -e "$(basename ${FILE_MAP[web]})" ]; then
|
||
nohup ./"$(basename ${FILE_MAP[web]})" run -c config.json >/dev/null 2>&1 &
|
||
sleep 2
|
||
pgrep -x "$(basename ${FILE_MAP[web]})" > /dev/null && green "$(basename ${FILE_MAP[web]}) is running" || { red "$(basename ${FILE_MAP[web]}) is not running, restarting..."; pkill -x "$(basename ${FILE_MAP[web]})" && nohup ./"$(basename ${FILE_MAP[web]})" run -c config.json >/dev/null 2>&1 & sleep 2; purple "$(basename ${FILE_MAP[web]}) restarted"; }
|
||
fi
|
||
|
||
if [ -e "$(basename ${FILE_MAP[bot]})" ]; then
|
||
if [[ $ARGO_AUTH =~ ^[A-Z0-9a-z=]{120,250}$ ]]; then
|
||
args="tunnel --edge-ip-version auto --no-autoupdate --protocol http2 run --token ${ARGO_AUTH}"
|
||
elif [[ $ARGO_AUTH =~ TunnelSecret ]]; then
|
||
args="tunnel --edge-ip-version auto --config tunnel.yml run"
|
||
else
|
||
args="tunnel --edge-ip-version auto --no-autoupdate --protocol http2 --logfile boot.log --loglevel info --url http://localhost:$vmess_port"
|
||
fi
|
||
nohup ./"$(basename ${FILE_MAP[bot]})" $args >/dev/null 2>&1 &
|
||
sleep 2
|
||
pgrep -x "$(basename ${FILE_MAP[bot]})" > /dev/null && green "$(basename ${FILE_MAP[bot]}) is running" || { red "$(basename ${FILE_MAP[bot]}) is not running, restarting..."; pkill -x "$(basename ${FILE_MAP[bot]})" && nohup ./"$(basename ${FILE_MAP[bot]})" "${args}" >/dev/null 2>&1 & sleep 2; purple "$(basename ${FILE_MAP[bot]}) restarted"; }
|
||
fi
|
||
sleep 5
|
||
rm -f "$(basename ${FILE_MAP[npm]})" "$(basename ${FILE_MAP[web]})" "$(basename ${FILE_MAP[bot]})"
|
||
}
|
||
|
||
get_argodomain() {
|
||
if [[ -n $ARGO_AUTH ]]; then
|
||
echo "$ARGO_DOMAIN"
|
||
else
|
||
grep -oE 'https://[[:alnum:]+\.-]+\.trycloudflare\.com' boot.log | sed 's@https://@@'
|
||
fi
|
||
}
|
||
|
||
get_ip() {
|
||
ip=$(curl -s --max-time 2 ipv4.ip.sb)
|
||
if [ -z "$ip" ]; then
|
||
ip=$( [[ "$HOSTNAME" =~ s[0-9]\.serv00\.com ]] && echo "${HOSTNAME/s/web}" || echo "$HOSTNAME" )
|
||
else
|
||
url="https://www.toolsdaquan.com/toolapi/public/ipchecking/$ip/443"
|
||
response=$(curl -s --location --max-time 3.5 --request GET "$url" --header 'Referer: https://www.toolsdaquan.com/ipcheck')
|
||
if [ -z "$response" ] || ! echo "$response" | grep -q '"icmp":"success"'; then
|
||
accessible=false
|
||
else
|
||
accessible=true
|
||
fi
|
||
if [ "$accessible" = false ]; then
|
||
ip=$( [[ "$HOSTNAME" =~ s[0-9]\.serv00\.com ]] && echo "${HOSTNAME/s/web}" || echo "$ip" )
|
||
fi
|
||
fi
|
||
echo "$ip"
|
||
}
|
||
|
||
get_links(){
|
||
argodomain=$(get_argodomain)
|
||
echo -e "\e[1;32mArgoDomain:\e[1;35m${argodomain}\e[0m\n"
|
||
sleep 1
|
||
IP=$(get_ip)
|
||
ISP=$(curl -s https://speed.cloudflare.com/meta | awk -F\" '{print $26"-"$18}' | sed -e 's/ /_/g')
|
||
sleep 1
|
||
yellow "注意:v2ray或其他软件的跳过证书验证需设置为true,否则hy2或tuic节点可能不通\n"
|
||
cat > list.txt <<EOF
|
||
vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$ISP\", \"add\": \"$IP\", \"port\": \"$vmess_port\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"none\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"\", \"path\": \"/vmess?ed=2048\", \"tls\": \"\", \"sni\": \"\", \"alpn\": \"\", \"fp\": \"\"}" | base64 -w0)
|
||
|
||
vmess://$(echo "{ \"v\": \"2\", \"ps\": \"$ISP\", \"add\": \"$CFIP\", \"port\": \"$CFPORT\", \"id\": \"$UUID\", \"aid\": \"0\", \"scy\": \"none\", \"net\": \"ws\", \"type\": \"none\", \"host\": \"$argodomain\", \"path\": \"/vmess?ed=2048\", \"tls\": \"tls\", \"sni\": \"$argodomain\", \"alpn\": \"\", \"fp\": \"\"}" | base64 -w0)
|
||
|
||
hysteria2://$UUID@$IP:$hy2_port/?sni=www.bing.com&alpn=h3&insecure=1#$ISP
|
||
|
||
tuic://$UUID:admin123@$IP:$tuic_port?sni=www.bing.com&congestion_control=bbr&udp_relay_mode=native&alpn=h3&allow_insecure=1#$ISP
|
||
EOF
|
||
cat list.txt
|
||
purple "\n$WORKDIR/list.txt saved successfully"
|
||
purple "Running done!"
|
||
sleep 2
|
||
rm -rf boot.log config.json sb.log core tunnel.yml tunnel.json fake_useragent_0.2.0.json
|
||
}
|
||
|
||
menu() {
|
||
clear
|
||
echo ""
|
||
purple "=== Serv00|ct8老王sing-box一键四合一安装脚本 ===\n"
|
||
echo -e "${green}脚本地址:${re}${yellow}https://github.com/eooce/Sing-box${re}\n"
|
||
echo -e "${green}反馈论坛:${re}${yellow}https://bbs.vps8.me${re}\n"
|
||
echo -e "${green}TG反馈群组:${re}${yellow}https://t.me/vps888${re}\n"
|
||
purple "转载请著名出处,请勿滥用\n"
|
||
green "1. 安装sing-box"
|
||
echo "==============="
|
||
red "2. 卸载sing-box"
|
||
echo "==============="
|
||
green "3. 查看节点信息"
|
||
echo "==============="
|
||
yellow "4. 清理所有进程"
|
||
echo "==============="
|
||
red "0. 退出脚本"
|
||
echo "==========="
|
||
reading "请输入选择(0-3): " choice
|
||
echo ""
|
||
case "${choice}" in
|
||
1) install_singbox ;;
|
||
2) uninstall_singbox ;;
|
||
3) cat $WORKDIR/list.txt ;;
|
||
4) kill_all_tasks ;;
|
||
0) exit 0 ;;
|
||
*) red "无效的选项,请输入 0 到 4" ;;
|
||
esac
|
||
}
|
||
menu
|