393 lines
14 KiB
Bash
393 lines
14 KiB
Bash
#!/usr/bin/env bash
|
|
# ==============================================================================
|
|
# 项目:Sing-box 极简现代化核心部署管理脚本 (全协议增强版)
|
|
# 支持五大协议:VLESS-Reality / Hysteria 2 / TUIC v5 / VMess-WS / AnyTLS
|
|
# 特性:原生二进制、安全防火墙精准放行、零隐私泄露、零后门、多平台订阅一键生成
|
|
# ==============================================================================
|
|
|
|
set -eo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
BOOTSTRAP_DIR="/usr/local/share/singbox-script"
|
|
TAR_URL="https://git.draws.qzz.io/jocay/singbox-script/archive/main.tar.gz"
|
|
GIT_URL="https://git.draws.qzz.io/jocay/singbox-script.git"
|
|
|
|
# 检测是否通过网络管道 (curl | bash 或 wget | bash) 远程单行执行
|
|
if [[ ! -d "${SCRIPT_DIR}/lib" ]]; then
|
|
if [[ $EUID -ne 0 ]]; then
|
|
echo -e "\033[31m[ERROR]\033[0m 本脚本需要 root 权限,请使用 sudo 或切换至 root 用户执行!" >&2
|
|
exit 1
|
|
fi
|
|
|
|
echo -e "\033[36m[INFO]\033[0m 检测到通过网络管道一键运行,正在自动化拉取完整组件至 ${BOOTSTRAP_DIR}..."
|
|
|
|
# 确保基础下载与解压依赖
|
|
if ! command -v tar >/dev/null 2>&1 || (! command -v curl >/dev/null 2>&1 && ! command -v wget >/dev/null 2>&1); then
|
|
if command -v apt-get >/dev/null 2>&1; then
|
|
apt-get update -y >/dev/null 2>&1 && apt-get install -y curl tar ca-certificates >/dev/null 2>&1
|
|
elif command -v dnf >/dev/null 2>&1; then
|
|
dnf install -y curl tar ca-certificates >/dev/null 2>&1
|
|
elif command -v yum >/dev/null 2>&1; then
|
|
yum install -y curl tar ca-certificates >/dev/null 2>&1
|
|
elif command -v apk >/dev/null 2>&1; then
|
|
apk update >/dev/null 2>&1 && apk add --no-cache curl tar ca-certificates >/dev/null 2>&1
|
|
fi
|
|
fi
|
|
|
|
rm -rf "${BOOTSTRAP_DIR}"
|
|
mkdir -p "${BOOTSTRAP_DIR}"
|
|
temp_archive="/tmp/singbox-script-$$.tar.gz"
|
|
|
|
download_success=false
|
|
if command -v curl >/dev/null 2>&1; then
|
|
if curl -sSL --fail --connect-timeout 10 -o "$temp_archive" "$TAR_URL"; then
|
|
download_success=true
|
|
fi
|
|
elif command -v wget >/dev/null 2>&1; then
|
|
if wget -qO "$temp_archive" "$TAR_URL"; then
|
|
download_success=true
|
|
fi
|
|
fi
|
|
|
|
if [[ "$download_success" == "true" ]]; then
|
|
tar -xzf "$temp_archive" -C "${BOOTSTRAP_DIR}" --strip-components=1 2>/dev/null || tar -xzf "$temp_archive" -C "${BOOTSTRAP_DIR}"
|
|
rm -f "$temp_archive"
|
|
elif command -v git >/dev/null 2>&1; then
|
|
rm -rf "${BOOTSTRAP_DIR}"
|
|
git clone --depth=1 "$GIT_URL" "${BOOTSTRAP_DIR}" >/dev/null 2>&1
|
|
else
|
|
echo -e "\033[31m[ERROR]\033[0m 下载失败,请检查网络或确认仓库地址有效: ${TAR_URL}" >&2
|
|
exit 1
|
|
fi
|
|
|
|
chmod +x "${BOOTSTRAP_DIR}/sb.sh" "${BOOTSTRAP_DIR}/lib/"*.sh 2>/dev/null || true
|
|
ln -sf "${BOOTSTRAP_DIR}/sb.sh" /usr/local/bin/sb
|
|
chmod +x /usr/local/bin/sb
|
|
|
|
exec bash "${BOOTSTRAP_DIR}/sb.sh" "$@"
|
|
fi
|
|
|
|
# 加载各核心子模块
|
|
source "${SCRIPT_DIR}/lib/env.sh"
|
|
source "${SCRIPT_DIR}/lib/system.sh"
|
|
source "${SCRIPT_DIR}/lib/cert.sh"
|
|
source "${SCRIPT_DIR}/lib/singbox.sh"
|
|
source "${SCRIPT_DIR}/lib/config.sh"
|
|
source "${SCRIPT_DIR}/lib/info.sh"
|
|
|
|
# 创建或确保全局快捷指令
|
|
ensure_symlink() {
|
|
if [[ ! -e "${SCRIPT_LINK}" ]]; then
|
|
ln -sf "${SCRIPT_DIR}/sb.sh" "${SCRIPT_LINK}"
|
|
chmod +x "${SCRIPT_LINK}"
|
|
log_info "已创建全局快捷指令:直接在终端输入 ${CLR_GREEN}sb${CLR_RESET} 即可随时调出菜单"
|
|
fi
|
|
}
|
|
|
|
# 部署并启动服务
|
|
finish_setup() {
|
|
setup_systemd_service
|
|
restart_service
|
|
ensure_symlink
|
|
sleep 1
|
|
|
|
if is_service_active; then
|
|
log_success "Sing-box 核心代理守护服务已平稳启动!"
|
|
show_node_info
|
|
else
|
|
log_error "Sing-box 启动异常,请通过 'sb log' 查看详细报错!"
|
|
fi
|
|
}
|
|
|
|
# 模式 1:一键五协议共存模式部署
|
|
do_install_all() {
|
|
check_root
|
|
log_info "========== 开始安装 Sing-box 五协议共存套件 =========="
|
|
|
|
install_dependencies || exit 1
|
|
install_singbox_binary || exit 1
|
|
|
|
local p_vless="${1:-443}"
|
|
local p_hy2="${2:-8443}"
|
|
local p_tuic="${3:-9443}"
|
|
local p_vmess="${4:-8080}"
|
|
local p_anytls="${5:-10443}"
|
|
|
|
if [[ -z "${1:-}" ]]; then
|
|
echo -e "${CLR_BOLD}请指定各协议监听端口(直接回车使用推荐默认值):${CLR_RESET}"
|
|
read -rp "1. VLESS-Reality 端口 [默认: 443/tcp]: " in_vless
|
|
read -rp "2. Hysteria 2 端口 [默认: 8443/udp]: " in_hy2
|
|
read -rp "3. TUIC v5 端口 [默认: 9443/udp]: " in_tuic
|
|
read -rp "4. VMess-WS 端口 [默认: 8080/tcp]: " in_vmess
|
|
read -rp "5. AnyTLS 端口 [默认: 10443/tcp]: " in_anytls
|
|
|
|
p_vless="${in_vless:-443}"
|
|
p_hy2="${in_hy2:-8443}"
|
|
p_tuic="${in_tuic:-9443}"
|
|
p_vmess="${in_vmess:-8080}"
|
|
p_anytls="${in_anytls:-10443}"
|
|
fi
|
|
|
|
# 生成多协议套件配置
|
|
generate_suite_config "all" "$p_vless" "$p_hy2" "$p_tuic" "$p_vmess" "$p_anytls" || exit 1
|
|
|
|
# 安全放行对应端口与协议
|
|
open_firewall_port "$p_vless" "tcp"
|
|
open_firewall_port "$p_hy2" "udp"
|
|
open_firewall_port "$p_tuic" "udp"
|
|
open_firewall_port "$p_vmess" "tcp"
|
|
open_firewall_port "$p_anytls" "tcp"
|
|
|
|
finish_setup
|
|
}
|
|
|
|
# 模式 2:指定单协议独立安装
|
|
do_install_single() {
|
|
local proto="$1"
|
|
check_root
|
|
|
|
install_dependencies || exit 1
|
|
install_singbox_binary || exit 1
|
|
|
|
case "$proto" in
|
|
vless)
|
|
local port="${2:-}"
|
|
local sni="${3:-}"
|
|
if [[ -z "$port" ]]; then
|
|
read -rp "请输入 VLESS-Reality 端口 [默认: 443]: " in_port
|
|
read -rp "请输入伪装域名 SNI [默认: www.apple.com]: " in_sni
|
|
port="${in_port:-443}"
|
|
sni="${in_sni:-www.apple.com}"
|
|
fi
|
|
generate_suite_config "vless" "$port" "$sni" || exit 1
|
|
open_firewall_port "$port" "tcp"
|
|
;;
|
|
hy2)
|
|
local port="${2:-}"
|
|
if [[ -z "$port" ]]; then
|
|
read -rp "请输入 Hysteria 2 端口 [默认: 8443]: " in_port
|
|
port="${in_port:-8443}"
|
|
fi
|
|
generate_suite_config "hy2" "$port" || exit 1
|
|
open_firewall_port "$port" "udp"
|
|
;;
|
|
tuic)
|
|
local port="${2:-}"
|
|
if [[ -z "$port" ]]; then
|
|
read -rp "请输入 TUIC v5 端口 [默认: 9443]: " in_port
|
|
port="${in_port:-9443}"
|
|
fi
|
|
generate_suite_config "tuic" "$port" || exit 1
|
|
open_firewall_port "$port" "udp"
|
|
;;
|
|
vmess)
|
|
local port="${2:-}"
|
|
if [[ -z "$port" ]]; then
|
|
read -rp "请输入 VMess-WS 端口 [默认: 8080]: " in_port
|
|
port="${in_port:-8080}"
|
|
fi
|
|
generate_suite_config "vmess" "$port" || exit 1
|
|
open_firewall_port "$port" "tcp"
|
|
;;
|
|
anytls)
|
|
local port="${2:-}"
|
|
if [[ -z "$port" ]]; then
|
|
read -rp "请输入 AnyTLS 端口 [默认: 10443]: " in_port
|
|
port="${in_port:-10443}"
|
|
fi
|
|
generate_suite_config "anytls" "$port" || exit 1
|
|
open_firewall_port "$port" "tcp"
|
|
;;
|
|
*)
|
|
log_error "不支持的协议: $proto"
|
|
return 1
|
|
;;
|
|
esac
|
|
|
|
finish_setup
|
|
}
|
|
|
|
# 单协议交互选择子菜单
|
|
show_single_menu() {
|
|
clear
|
|
echo -e "${CLR_GREEN}================================================================${CLR_RESET}"
|
|
echo -e "${CLR_BOLD}${CLR_GREEN} 请选择要单独安装的代理协议 ${CLR_RESET}"
|
|
echo -e "${CLR_GREEN}================================================================${CLR_RESET}"
|
|
echo -e " ${CLR_BOLD}1)${CLR_RESET} VLESS-Reality-Vision (免证书顶级抗封锁)"
|
|
echo -e " ${CLR_BOLD}2)${CLR_RESET} Hysteria 2 (极速 QUIC/UDP,恶劣网络首选)"
|
|
echo -e " ${CLR_BOLD}3)${CLR_RESET} TUIC v5 (BBR 拥塞控制 QUIC)"
|
|
echo -e " ${CLR_BOLD}4)${CLR_RESET} VMess-WS (经典 WebSocket,兼容 CDN 反代)"
|
|
echo -e " ${CLR_BOLD}5)${CLR_RESET} AnyTLS (Sing-box 原生 TLS 协议)"
|
|
echo -e " ${CLR_BOLD}0)${CLR_RESET} 返回上一级菜单"
|
|
echo -e "${CLR_GREEN}================================================================${CLR_RESET}"
|
|
read -rp "请选择 [0-5]: " sub_choice
|
|
|
|
case "$sub_choice" in
|
|
1) do_install_single "vless" ;;
|
|
2) do_install_single "hy2" ;;
|
|
3) do_install_single "tuic" ;;
|
|
4) do_install_single "vmess" ;;
|
|
5) do_install_single "anytls" ;;
|
|
0) return 0 ;;
|
|
*) log_warn "无效选项!" ;;
|
|
esac
|
|
}
|
|
|
|
# 查看实时日志
|
|
do_logs() {
|
|
check_root
|
|
log_info "正在查看 Sing-box 实时运行日志 (按 Ctrl+C 退出)..."
|
|
journalctl -u "${SERVICE_NAME}" -f -n 50
|
|
}
|
|
|
|
# 安全清理卸载
|
|
do_uninstall() {
|
|
check_root
|
|
echo -e "${CLR_YELLOW}确定要彻底卸载 Sing-box 代理服务吗?[y/N]: ${CLR_RESET}"
|
|
read -r choice
|
|
case "$choice" in
|
|
[Yy]*)
|
|
log_info "开始安全清理 Sing-box..."
|
|
|
|
# 清理所有已启用的防火墙放行规则
|
|
if [[ -f "${META_FILE}" ]]; then
|
|
local p_vl p_hy p_tu p_vm p_an
|
|
p_vl=$(jq -r '.protocols.vless_reality.port // empty' "${META_FILE}")
|
|
p_hy=$(jq -r '.protocols.hysteria2.port // empty' "${META_FILE}")
|
|
p_tu=$(jq -r '.protocols.tuic.port // empty' "${META_FILE}")
|
|
p_vm=$(jq -r '.protocols.vmess_ws.port // empty' "${META_FILE}")
|
|
p_an=$(jq -r '.protocols.anytls.port // empty' "${META_FILE}")
|
|
|
|
[[ -n "$p_vl" ]] && close_firewall_port "$p_vl" "tcp"
|
|
[[ -n "$p_hy" ]] && close_firewall_port "$p_hy" "udp"
|
|
[[ -n "$p_tu" ]] && close_firewall_port "$p_tu" "udp"
|
|
[[ -n "$p_vm" ]] && close_firewall_port "$p_vm" "tcp"
|
|
[[ -n "$p_an" ]] && close_firewall_port "$p_an" "tcp"
|
|
fi
|
|
|
|
# 停止并清理守护服务
|
|
if systemctl is-enabled --quiet "${SERVICE_NAME}" 2>/dev/null; then
|
|
systemctl stop "${SERVICE_NAME}" >/dev/null 2>&1 || true
|
|
systemctl disable "${SERVICE_NAME}" >/dev/null 2>&1 || true
|
|
fi
|
|
rm -f "${SERVICE_FILE}"
|
|
systemctl daemon-reload >/dev/null 2>&1 || true
|
|
|
|
# 仅清理程序自身目录,杜绝误伤
|
|
rm -rf "${INSTALL_DIR}"
|
|
rm -rf "${BOOTSTRAP_DIR}"
|
|
rm -f "${BIN_PATH}" "${SCRIPT_LINK}"
|
|
|
|
log_success "Sing-box 核心服务已完全且干净地卸载!"
|
|
;;
|
|
*)
|
|
log_info "已取消卸载。"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# 交互式主菜单
|
|
show_menu() {
|
|
clear
|
|
echo -e "${CLR_GREEN}================================================================${CLR_RESET}"
|
|
echo -e "${CLR_BOLD}${CLR_GREEN} Sing-box 现代化核心管理工具 (全协议纯净版) ${CLR_RESET}"
|
|
echo -e "${CLR_GREEN}================================================================${CLR_RESET}"
|
|
|
|
local status_text
|
|
if is_service_active 2>/dev/null; then
|
|
status_text="${CLR_GREEN}● 运行中${CLR_RESET}"
|
|
else
|
|
status_text="${CLR_RED}○ 未运行${CLR_RESET}"
|
|
fi
|
|
echo -e "核心状态: ${status_text}"
|
|
echo -e "${CLR_GREEN}----------------------------------------------------------------${CLR_RESET}"
|
|
echo -e " ${CLR_BOLD}1)${CLR_RESET} 一键安装【五协议共存套件】 (VLESS+Hy2+TUIC+VMess+AnyTLS)"
|
|
echo -e " ${CLR_BOLD}2)${CLR_RESET} 自选单协议独立安装"
|
|
echo -e " ${CLR_BOLD}3)${CLR_RESET} 查看当前已装节点信息与分享链接"
|
|
echo -e " ${CLR_BOLD}4)${CLR_RESET} 启动服务"
|
|
echo -e " ${CLR_BOLD}5)${CLR_RESET} 停止服务"
|
|
echo -e " ${CLR_BOLD}6)${CLR_RESET} 重启服务"
|
|
echo -e " ${CLR_BOLD}7)${CLR_RESET} 查看实时日志"
|
|
echo -e " ${CLR_BOLD}8)${CLR_RESET} 彻底干净卸载"
|
|
echo -e " ${CLR_BOLD}0)${CLR_RESET} 退出"
|
|
echo -e "${CLR_GREEN}================================================================${CLR_RESET}"
|
|
read -rp "请选择操作 [0-8]: " menu_choice
|
|
|
|
case "$menu_choice" in
|
|
1) do_install_all ;;
|
|
2) show_single_menu ;;
|
|
3) show_node_info ;;
|
|
4)
|
|
start_service
|
|
log_success "服务已启动!"
|
|
;;
|
|
5)
|
|
stop_service
|
|
log_success "服务已停止!"
|
|
;;
|
|
6)
|
|
restart_service
|
|
log_success "服务已重启!"
|
|
;;
|
|
7) do_logs ;;
|
|
8) do_uninstall ;;
|
|
0) exit 0 ;;
|
|
*) log_warn "无效选项,请重新输入!" ;;
|
|
esac
|
|
}
|
|
|
|
# 命令行 CLI 支持
|
|
case "${1:-}" in
|
|
install)
|
|
shift
|
|
case "${1:-}" in
|
|
all)
|
|
shift
|
|
do_install_all "$@"
|
|
;;
|
|
vless|hy2|tuic|vmess|anytls)
|
|
proto="$1"
|
|
shift
|
|
do_install_single "$proto" "$@"
|
|
;;
|
|
*)
|
|
do_install_all
|
|
;;
|
|
esac
|
|
;;
|
|
info|show)
|
|
show_node_info
|
|
;;
|
|
start)
|
|
check_root
|
|
start_service
|
|
log_success "服务已启动!"
|
|
;;
|
|
stop)
|
|
check_root
|
|
stop_service
|
|
log_success "服务已停止!"
|
|
;;
|
|
restart)
|
|
check_root
|
|
restart_service
|
|
log_success "服务已重启!"
|
|
;;
|
|
status)
|
|
if is_service_active; then
|
|
log_success "Sing-box 正在稳定运行中。"
|
|
else
|
|
log_warn "Sing-box 当前未运行。"
|
|
fi
|
|
;;
|
|
log|logs)
|
|
do_logs
|
|
;;
|
|
uninstall)
|
|
do_uninstall
|
|
;;
|
|
*)
|
|
show_menu
|
|
;;
|
|
esac
|