From 34565faa6b927d9645b1a140371bebb8c5aab262 Mon Sep 17 00:00:00 2001 From: jocay Date: Sun, 27 Sep 2026 13:11:24 +0800 Subject: [PATCH] feat: initial commit of clean multi-protocol singbox core script --- .gitattributes | 3 + .gitignore | 3 + README.md | 115 +++++++++++++++++ lib/cert.sh | 48 +++++++ lib/config.sh | 339 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/env.sh | 48 +++++++ lib/info.sh | 328 +++++++++++++++++++++++++++++++++++++++++++++++ lib/singbox.sh | 119 +++++++++++++++++ lib/system.sh | 139 ++++++++++++++++++++ sb.sh | 333 ++++++++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 1475 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 README.md create mode 100644 lib/cert.sh create mode 100644 lib/config.sh create mode 100644 lib/env.sh create mode 100644 lib/info.sh create mode 100644 lib/singbox.sh create mode 100644 lib/system.sh create mode 100644 sb.sh diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..49ce79a --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +* text=auto eol=lf +*.sh text eol=lf +*.md text eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b8eb3e3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.DS_Store +*.log +*.tmp diff --git a/README.md b/README.md new file mode 100644 index 0000000..83fd5f8 --- /dev/null +++ b/README.md @@ -0,0 +1,115 @@ +# Sing-box Core (Clean 全协议版) + +基于官方原版架构重构的 Sing-box 极简核心部署与管理工具。彻底剥离原项目中 4400+ 行的臃肿代码与高危隐患,专注纯净代理服务部署与标准化多平台订阅生成。 + +--- + +## 🌟 支持协议全景 + +| 协议类型 | 底层传输 / 认证 | 端口默认 | 特点与适用场景 | 免域名/证书 | +| :--- | :--- | :--- | :--- | :--- | +| **VLESS-Reality** | TCP + Vision + Reality | `443/tcp` | 顶级伪装防封锁,主流科学上网首选 | **是** (借用顶级站点 SNI) | +| **Hysteria 2** | UDP + QUIC (ALPN: h3) | `8443/udp` | 恶劣网络丢包环境下极速救星,自带拥塞控制 | **是** (内置自签 EC 证书) | +| **TUIC v5** | UDP + QUIC + BBR | `9443/udp` | 低延迟双向原生 UDP 转发,移动设备表现优异 | **是** (内置自签 EC 证书) | +| **VMess-WS** | TCP + WebSocket | `8080/tcp` | 经典通用传输,可结合 CDN 反代 | **是** (纯净明文/本地反代) | +| **AnyTLS** | TCP + TLS (Padding Scheme) | `10443/tcp`| Sing-box 原生 TLS 高效协议 | **是** (内置自签 EC 证书) | + +--- + +## 📁 模块化目录结构 + +```text +sb-core/ +├── sb.sh # 主程序入口(交互式菜单与 CLI 自动化指令) +├── README.md # 本项目使用与开发文档 +└── lib/ + ├── env.sh # 环境变量、常量路径定义、权限检查与终端彩色日志 + ├── system.sh # 系统架构检测 (amd64/arm64)、依赖安装、安全防火墙放行 + ├── cert.sh # ECDSA (P-256) 现代自签证书自动化生成与管理 + ├── singbox.sh # Sing-box 官方正版二进制下载、校验与 Systemd 守护服务 + ├── config.sh # 多协议配置生成引擎与 Sing-box 原生语法校验 + └── info.sh # 多协议分享链接、聚合 Base64 订阅与客户端配置生成 +``` + +--- + +## 🚀 快速使用 + +### 1. 部署与运行 + +在 Linux VPS(Ubuntu / Debian / CentOS / Rocky 等)以 `root` 权限执行: + +```bash +git clone https://git.draws.qzz.io/jocay/singbox-script.git +cd singbox-script +chmod +x sb.sh lib/*.sh +./sb.sh +``` + +首次运行后会自动建立全局快捷指令,之后在系统任意目录输入 `sb` 即可调出菜单。 + +### 2. 交互式菜单功能 + +```text +================================================================ + Sing-box 现代化核心管理工具 (全协议纯净版) +================================================================ +核心状态: ● 运行中 +---------------------------------------------------------------- + 1) 一键安装【五协议共存套件】 (VLESS+Hy2+TUIC+VMess+AnyTLS) + 2) 自选单协议独立安装 + 3) 查看当前已装节点信息与分享链接 + 4) 启动服务 + 5) 停止服务 + 6) 重启服务 + 7) 查看实时日志 + 8) 彻底干净卸载 + 0) 退出 +================================================================ +``` + +### 3. CLI 命令行无交互快捷调用(适合自动化部署) + +```bash +# 一键安装五协议共存套件(使用默认端口) +sb install all + +# 自定义指定各协议端口安装五协议 +sb install all [vless端口] [hy2端口] [tuic端口] [vmess端口] [anytls端口] + +# 单独安装指定协议 +sb install vless [端口] [伪装SNI] # 例如: sb install vless 443 www.apple.com +sb install hy2 [端口] # 例如: sb install hy2 8443 +sb install tuic [端口] # 例如: sb install tuic 9443 +sb install vmess [端口] # 例如: sb install vmess 8080 +sb install anytls [端口] # 例如: sb install anytls 10443 + +# 常用运维 +sb info # 查看当前所有节点、通用分享链接及订阅内容 +sb status # 查看服务运行状态 +sb restart # 重启服务 +sb stop # 停止服务 +sb start # 启动服务 +sb log # 查看实时内核运行日志 (Ctrl+C 退出) +sb uninstall # 彻底干净卸载 +``` + +--- + +## 📱 客户端配置与导出文件 + +执行 `sb info` 或安装完成后,所有客户端所需格式都会保存在 `/etc/sing-box/`: + +1. **单协议标准通用链接**: + - `vless://...` (VLESS-Reality) + - `hy2://...` (Hysteria 2) + - `tuic://...` (TUIC v5) + - `vmess://...` (VMess-WS) + - `anytls://...` (AnyTLS) +2. **聚合 Base64 订阅内容 (`/etc/sing-box/sub_base64.txt`)**: + - 包含当前已部署的所有协议节点,可直接整段复制粘贴到客户端(v2rayN、Nekobox、Shadowrocket、Quantumult X 等)作为批量导入或订阅。 +3. **Clash-Meta / Mihomo 配置文件 (`/etc/sing-box/clash_meta.yaml`)**: + - 已经按 Mihomo 规范写好各协议代理节点,直接复制进客户端配置的 `proxies` 组即可。 +4. **Sing-box 官方客户端出站配置 (`/etc/sing-box/singbox_client.json`)**: + - 包含完整的 `outbounds` 片段,直接贴入官方客户端即可。 +5. **完整明文信息汇总 (`/etc/sing-box/node_info.txt`)**。 diff --git a/lib/cert.sh b/lib/cert.sh new file mode 100644 index 0000000..25da130 --- /dev/null +++ b/lib/cert.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +# ============================================================================== +# 模块:TLS 证书自动化生成与管理 (支持 ECDSA 现代自签与自定义证书) +# ============================================================================== + +CERT_DIR="${INSTALL_DIR}/cert" +CERT_FILE="${CERT_DIR}/cert.pem" +KEY_FILE="${CERT_DIR}/private.key" + +# 生成现代椭圆曲线 (prime256v1) 自签名证书 +generate_self_signed_cert() { + local sni="${1:-www.bing.com}" + mkdir -p "${CERT_DIR}" + + # 如果证书已存在且有效期超过30天,直接复用 + if [[ -f "${CERT_FILE}" && -f "${KEY_FILE}" ]]; then + if openssl x509 -checkend 2592000 -noout -in "${CERT_FILE}" >/dev/null 2>&1; then + log_info "现有 TLS 证书有效,直接复用: ${CERT_FILE}" + return 0 + fi + fi + + log_info "正在为伪装域名 [${sni}] 自动化生成 ECDSA (P-256) 高性能自签名 TLS 证书..." + + # 生成 EC 私钥 + openssl ecparam -name prime256v1 -genkey -noout -out "${KEY_FILE}" 2>/dev/null + + # 生成 10 年有效期的自签名证书 + openssl req -new -x509 -days 3650 \ + -key "${KEY_FILE}" \ + -out "${CERT_FILE}" \ + -subj "/CN=${sni}" \ + -addext "subjectAltName=DNS:${sni}" 2>/dev/null || \ + openssl req -new -x509 -days 3650 \ + -key "${KEY_FILE}" \ + -out "${CERT_FILE}" \ + -subj "/CN=${sni}" 2>/dev/null + + chmod 600 "${KEY_FILE}" "${CERT_FILE}" + + if [[ ! -s "${CERT_FILE}" || ! -s "${KEY_FILE}" ]]; then + log_error "TLS 自签名证书生成失败,请检查 openssl 环境!" + return 1 + fi + + log_success "TLS 证书自动化生成完成!" + return 0 +} diff --git a/lib/config.sh b/lib/config.sh new file mode 100644 index 0000000..7637566 --- /dev/null +++ b/lib/config.sh @@ -0,0 +1,339 @@ +#!/usr/bin/env bash +# ============================================================================== +# 模块:多协议配置生成器 (VLESS-Reality / Hysteria2 / TUIC / VMess / AnyTLS) +# ============================================================================== + +# 获取或生成统一 UUID +get_or_create_uuid() { + local uuid="${1:-}" + if [[ -z "$uuid" ]]; then + if command -v "${BIN_PATH}" >/dev/null 2>&1; then + uuid=$("${BIN_PATH}" generate uuid 2>/dev/null) + fi + if [[ -z "$uuid" && -f /proc/sys/kernel/random/uuid ]]; then + uuid=$(cat /proc/sys/kernel/random/uuid) + fi + if [[ -z "$uuid" ]]; then + uuid=$(openssl rand -hex 16 | sed -E 's/(.{8})(.{4})(.{4})(.{4})(.{12})/\1-\2-\3-\4-\5/') + fi + fi + echo "$uuid" +} + +# 1. 组装 VLESS-Reality 入站 JSON +build_vless_inbound() { + local port="$1" + local uuid="$2" + local sni="$3" + local priv_key="$4" + local short_id="$5" + + cat </dev/null || openssl rand -hex 4) + short_id=$(echo "$short_id" | tr -d ' "\r\n') + fi + + local inbounds_arr=() + local meta_protocols="{}" + + case "$mode" in + all) + 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}" + + inbounds_arr+=("$(build_vless_inbound "$p_vless" "$uuid" "$reality_sni" "$priv_key" "$short_id")") + inbounds_arr+=("$(build_hy2_inbound "$p_hy2" "$uuid")") + inbounds_arr+=("$(build_tuic_inbound "$p_tuic" "$uuid")") + inbounds_arr+=("$(build_vmess_inbound "$p_vmess" "$uuid")") + inbounds_arr+=("$(build_anytls_inbound "$p_anytls" "$uuid")") + + meta_protocols=$(cat < "${CONFIG_FILE}" </dev/null 2>&1; then + log_error "生成的配置文件未能通过 Sing-box 语法检测!请检查端口是否有冲突或参数错误。" + return 1 + fi + + # 写入持久化元数据 + cat > "${META_FILE}" <&2 +} + +# 权限校验:必须以 root 权限运行 +check_root() { + if [[ $EUID -ne 0 ]]; then + log_error "本脚本需要 root 权限,请使用 sudo 或切换至 root 用户执行!" + exit 1 + fi +} diff --git a/lib/info.sh b/lib/info.sh new file mode 100644 index 0000000..dae5a31 --- /dev/null +++ b/lib/info.sh @@ -0,0 +1,328 @@ +#!/usr/bin/env bash +# ============================================================================== +# 模块:多协议分享链接生成、聚合订阅与多客户端配置导出 +# ============================================================================== + +show_node_info() { + if [[ ! -f "${META_FILE}" ]]; then + log_error "未检测到已安装的节点配置元数据,请先执行安装!" + return 1 + fi + + local uuid server_ip + uuid=$(jq -r '.uuid' "${META_FILE}") + server_ip=$(get_public_ip) + + local share_links=() + local clash_proxies="" + local sb_outbounds=() + local summary_text="" + + # -------------------------------------------------------------------------- + # 1. VLESS-Reality + # -------------------------------------------------------------------------- + if [[ $(jq -r '.protocols.vless_reality.enabled // false' "${META_FILE}") == "true" ]]; then + local vl_port vl_sni vl_pub vl_sid vl_name vl_link + vl_port=$(jq -r '.protocols.vless_reality.port' "${META_FILE}") + vl_sni=$(jq -r '.protocols.vless_reality.sni' "${META_FILE}") + vl_pub=$(jq -r '.protocols.vless_reality.public_key' "${META_FILE}") + vl_sid=$(jq -r '.protocols.vless_reality.short_id' "${META_FILE}") + vl_name="VLESS-Reality-${server_ip}" + + vl_link="vless://${uuid}@${server_ip}:${vl_port}?security=reality&encryption=none&pbk=${vl_pub}&headerType=none&fp=chrome&type=tcp&flow=xtls-rprx-vision&sni=${vl_sni}&sid=${vl_sid}#${vl_name}" + share_links+=("$vl_link") + + summary_text+="[VLESS-Reality-Vision] 端口: ${vl_port}/tcp | SNI: ${vl_sni} | PublicKey: ${vl_pub} | ShortID: ${vl_sid}\n${vl_link}\n\n" + + clash_proxies+=$(cat < "$b64_file" + + cat > "$clash_file" < "$sb_client_file" < "$info_file" </dev/null | jq -r '.tag_name' 2>/dev/null | sed 's/^v//') + + # 备用方案:重定向网页抓取 + if [[ -z "$version" || "$version" == "null" ]]; then + version=$(curl -sL --max-time 5 "https://github.com/SagerNet/sing-box/releases/latest" 2>/dev/null | grep -oP 'tag/v\K[0-9.]+' | head -n 1) + fi + + # 兜底固定稳定版本 (如果 GitHub 无法连接) + if [[ -z "$version" || "$version" == "null" ]]; then + version="1.11.0" + fi + + echo "$version" +} + +# 下载并安装官方原版 Sing-box 二进制 +install_singbox_binary() { + local arch + arch=$(detect_arch) || return 1 + + local version + version=$(get_latest_singbox_version) + log_info "准备安装 Sing-box 官方核心版本: v${version} (架构: ${arch})..." + + local pkg_name="sing-box-${version}-linux-${arch}" + local download_url="https://github.com/SagerNet/sing-box/releases/download/v${version}/${pkg_name}.tar.gz" + local temp_tar="/tmp/${pkg_name}.tar.gz" + local temp_dir="/tmp/${pkg_name}" + + log_info "正在从 GitHub Releases 官方通道下载..." + if ! curl -L --fail --retry 3 --connect-timeout 10 -o "$temp_tar" "$download_url"; then + log_error "下载 Sing-box 失败,请检查服务器连接 GitHub 的网络状况!" + return 1 + fi + + # 解压并部署 + rm -rf "$temp_dir" + mkdir -p "$temp_dir" + tar -xzf "$temp_tar" -C /tmp/ || { + log_error "解压 Sing-box 压缩包失败!" + rm -f "$temp_tar" + return 1 + } + + mkdir -p "${BIN_DIR}" + cp -f "${temp_dir}/sing-box" "${BIN_PATH}" + chmod +x "${BIN_PATH}" + chown root:root "${BIN_PATH}" + + # 清理临时下载文件 + rm -rf "$temp_tar" "$temp_dir" + + # 验证是否可用 + if ! "${BIN_PATH}" version >/dev/null 2>&1; then + log_error "Sing-box 二进制文件执行测试失败!" + return 1 + fi + + local installed_ver + installed_ver=$("${BIN_PATH}" version | head -n 1) + log_success "Sing-box 核心安装成功: ${installed_ver}" + return 0 +} + +# 配置安全可靠的 Systemd 服务文件 +setup_systemd_service() { + log_info "配置 Sing-box Systemd 系统守护进程..." + + cat > "${SERVICE_FILE}" </dev/null 2>&1 + log_success "Systemd 守护服务配置完成!" +} + +# 服务启停控制 +start_service() { + systemctl start "${SERVICE_NAME}" +} + +stop_service() { + systemctl stop "${SERVICE_NAME}" +} + +restart_service() { + systemctl restart "${SERVICE_NAME}" +} + +is_service_active() { + systemctl is-active --quiet "${SERVICE_NAME}" +} diff --git a/lib/system.sh b/lib/system.sh new file mode 100644 index 0000000..72483ee --- /dev/null +++ b/lib/system.sh @@ -0,0 +1,139 @@ +#!/usr/bin/env bash +# ============================================================================== +# 模块:系统架构识别、依赖安装与安全防火墙配置 +# ============================================================================== + +# 识别系统架构 +detect_arch() { + local raw_arch + raw_arch=$(uname -m) + case "${raw_arch}" in + x86_64|amd64) + echo "amd64" + ;; + aarch64|arm64) + echo "arm64" + ;; + armv7*|armv8l) + echo "armv7" + ;; + *) + log_error "暂不支持的 CPU 架构: ${raw_arch}" + return 1 + ;; + esac +} + +# 识别系统包管理器并安装基础依赖 +install_dependencies() { + log_info "检查并安装必要系统工具 (curl, tar, jq, openssl, ca-certificates)..." + + local pkgs=("curl" "tar" "jq" "openssl" "ca-certificates") + + if command -v apt-get >/dev/null 2>&1; then + apt-get update -y >/dev/null 2>&1 + apt-get install -y "${pkgs[@]}" >/dev/null 2>&1 + elif command -v dnf >/dev/null 2>&1; then + dnf install -y "${pkgs[@]}" >/dev/null 2>&1 + elif command -v yum >/dev/null 2>&1; then + yum install -y "${pkgs[@]}" >/dev/null 2>&1 + elif command -v apk >/dev/null 2>&1; then + apk update >/dev/null 2>&1 + apk add --no-cache "${pkgs[@]}" >/dev/null 2>&1 + else + log_warn "未识别的包管理器,请手动确保安装了: ${pkgs[*]}" + fi + + # 验证关键工具安装结果 + for cmd in curl tar jq openssl; do + if ! command -v "$cmd" >/dev/null 2>&1; then + log_error "关键依赖工具 [${cmd}] 安装失败,请检查网络或系统源设置!" + return 1 + fi + done + + log_success "系统基础依赖检测通过!" + return 0 +} + +# 获取公网 IP(具备多节点故障自动切换机制) +get_public_ip() { + local ip="" + local apis=( + "https://api.ipify.org" + "https://icanhazip.com" + "https://ifconfig.me/ip" + "https://checkip.amazonaws.com" + ) + + for api in "${apis[@]}"; do + ip=$(curl -s4m 4 "$api" 2>/dev/null | tr -d '[:space:]') + if [[ -n "$ip" && "$ip" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then + echo "$ip" + return 0 + fi + done + + # 尝试获取 IPv6 (如果仅有 IPv6) + ip=$(curl -s6m 4 "https://api64.ipify.org" 2>/dev/null | tr -d '[:space:]') + if [[ -n "$ip" ]]; then + echo "$ip" + return 0 + fi + + echo "127.0.0.1" +} + +# 安全配置防火墙:精准仅开放代理端口,杜绝关闭防火墙或全盘清空规则 +open_firewall_port() { + local port="$1" + local protocol="${2:-tcp}" + [[ -z "$port" ]] && return 0 + + log_info "正在配置防火墙放行端口: ${port}/${protocol}..." + + # 1. 检测 UFW + if command -v ufw >/dev/null 2>&1 && ufw status 2>/dev/null | grep -qw "active"; then + ufw allow "${port}/${protocol}" comment "sing-box" >/dev/null 2>&1 + log_success "UFW 已放行端口 ${port}/${protocol}" + return 0 + fi + + # 2. 检测 Firewalld + if command -v firewall-cmd >/dev/null 2>&1 && systemctl is-active --quiet firewalld 2>/dev/null; then + firewall-cmd --permanent --add-port="${port}/${protocol}" >/dev/null 2>&1 + firewall-cmd --reload >/dev/null 2>&1 + log_success "Firewalld 已放行端口 ${port}/${protocol}" + return 0 + fi + + # 3. iptables 兜底安全追加(不重置现有规则链) + if command -v iptables >/dev/null 2>&1; then + if ! iptables -C INPUT -p "${protocol}" --dport "${port}" -j ACCEPT 2>/dev/null; then + iptables -I INPUT -p "${protocol}" --dport "${port}" -j ACCEPT 2>/dev/null + log_success "iptables 已安全追加放行规则: ${port}/${protocol}" + fi + fi +} + +# 卸载或更换端口时安全移除端口规则 +close_firewall_port() { + local port="$1" + local protocol="${2:-tcp}" + [[ -z "$port" ]] && return 0 + + log_info "正在清理防火墙放行规则: ${port}/${protocol}..." + + if command -v ufw >/dev/null 2>&1 && ufw status 2>/dev/null | grep -qw "active"; then + ufw delete allow "${port}/${protocol}" >/dev/null 2>&1 || true + fi + + if command -v firewall-cmd >/dev/null 2>&1 && systemctl is-active --quiet firewalld 2>/dev/null; then + firewall-cmd --permanent --remove-port="${port}/${protocol}" >/dev/null 2>&1 || true + firewall-cmd --reload >/dev/null 2>&1 || true + fi + + if command -v iptables >/dev/null 2>&1; then + iptables -D INPUT -p "${protocol}" --dport "${port}" -j ACCEPT 2>/dev/null || true + fi +} diff --git a/sb.sh b/sb.sh new file mode 100644 index 0000000..50fe10a --- /dev/null +++ b/sb.sh @@ -0,0 +1,333 @@ +#!/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)" + +# 加载各核心子模块 +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 -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