#!/usr/bin/env bash # ===================================================================== # 宝塔式一键安装 —— 零交互,装完即可用 IP 访问后台 # # 用法(用户只需这一行): # bash <(curl -fsSL https://svip.t7.hk/scdn/install.sh) # curl -fsSL https://svip.t7.hk/scdn/install.sh | bash # # 可选参数(一般不用传): # --domain xxx.com 绑定域名并自动申请 HTTPS 证书 # --email a@b.com 证书申请邮箱 # --panel-port 8000 面板端口 # --port 443 Reality 端口 # --user alice 首个用户名 # --master https://... 覆盖主程序下载地址 # ===================================================================== set -euo pipefail # 主程序下载地址(可用 --master 覆盖) MASTER="${MASTER:-https://svip.t7.hk/scdn}" GIT_REPO="${GIT_REPO:-}" INSTALL_DIR="${INSTALL_DIR:-/opt/scdn}" DOMAIN=""; EMAIL=""; PANEL_PORT=""; REALITY_PORT=""; FIRST_USER="default" LOCAL_SRC="" while [[ $# -gt 0 ]]; do case "$1" in --domain) DOMAIN="$2"; shift 2 ;; --email) EMAIL="$2"; shift 2 ;; --panel-port) PANEL_PORT="$2"; shift 2 ;; --port) REALITY_PORT="$2"; shift 2 ;; --user) FIRST_USER="$2"; shift 2 ;; --master) MASTER="$2"; shift 2 ;; --dir) INSTALL_DIR="$2"; shift 2 ;; -h|--help) sed -n '2,22p' "$0"; exit 0 ;; *) echo "未知参数: $1"; exit 1 ;; esac done C_G=$'\033[32m'; C_Y=$'\033[33m'; C_R=$'\033[31m'; C_B=$'\033[1m'; C_0=$'\033[0m' info() { echo -e "${C_G}[+]${C_0} $*"; } warn() { echo -e "${C_Y}[!]${C_0} $*"; } err() { echo -e "${C_R}[x]${C_0} $*"; exit 1; } line() { echo -e "${C_G}--------------------------------------------------${C_0}"; } [[ $EUID -eq 0 ]] || err "请用 root 运行:sudo bash $0" echo -e "${C_B}" echo " ┌──────────────────────────────────────────┐" echo " │ 代理服务 一键安装程序 │" echo " └──────────────────────────────────────────┘" echo -e "${C_0}" # ---------------------------------------------------------------- 环境 [[ -r /etc/os-release ]] || err "仅支持 Debian / Ubuntu 系列" . /etc/os-release [[ "${ID:-}" =~ (debian|ubuntu) ]] || warn "非 Debian/Ubuntu 系统(${ID:-unknown}),继续尝试" info "检测公网 IP" HOST_IP="$(curl -s -4 --max-time 8 https://api.ipify.org || true)" [[ -z "$HOST_IP" ]] && HOST_IP="$(curl -s -4 --max-time 8 https://ifconfig.me/ip || true)" [[ -z "$HOST_IP" ]] && HOST_IP="$(hostname -I 2>/dev/null | awk '{print $1}')" [[ -n "$HOST_IP" ]] || err "无法获取公网 IP" info "公网 IP:$HOST_IP" # ---------------------------------------------------------------- 取主程序 fetch_source() { # 1) 本地已有源码(离线安装) if [[ -f "$LOCAL_SRC/server/deploy.sh" ]]; then info "使用本地源码:$LOCAL_SRC" mkdir -p "$INSTALL_DIR" cp -a "$LOCAL_SRC/." "$INSTALL_DIR/" return fi # 2) 从备用服务器下载打包文件 info "从 $MASTER 下载主程序" if curl -fsSL --max-time 120 -o /tmp/scdn.tar.gz "$MASTER/scdn.tar.gz"; then mkdir -p "$INSTALL_DIR" tar -xzf /tmp/scdn.tar.gz -C "$INSTALL_DIR" rm -f /tmp/scdn.tar.gz [[ -f "$INSTALL_DIR/server/deploy.sh" ]] || err "下载包内容不正确" return fi # 3) 退化为 git clone [[ -n "$GIT_REPO" ]] || err "下载失败。请检查 MASTER 地址,或用 --master 指定正确地址" info "改用 git clone:$GIT_REPO" command -v git >/dev/null 2>&1 || { apt-get update -qq; apt-get install -y -qq git >/dev/null; } rm -rf "$INSTALL_DIR" git clone --depth=1 "$GIT_REPO" "$INSTALL_DIR" } fetch_source [[ -f "$INSTALL_DIR/server/deploy.sh" ]] || err "主程序不完整:缺少 server/deploy.sh" chmod +x "$INSTALL_DIR"/server/*.sh "$INSTALL_DIR"/install.sh 2>/dev/null || true # ---------------------------------------------------------------- 安装 info "开始安装(全程自动,无需干预)" cd "$INSTALL_DIR/server" export NONINTERACTIVE=1 export DOMAIN="$DOMAIN" export ACME_EMAIL="$EMAIL" export FIRST_USER="$FIRST_USER" [[ -n "$PANEL_PORT" ]] && export PANEL_PORT [[ -n "$REALITY_PORT" ]] && export REALITY_PORT DEPLOY_LOG=/tmp/scdn-deploy.log bash deploy.sh 2>&1 | tee "$DEPLOY_LOG" # ---------------------------------------------------------------- 结果 PORT="$(python3 -c " import json try: print(json.load(open('/opt/proxy/users.json'))['server'].get('panel_port',8000)) except Exception: print(8000) ")" SCHEME="$(python3 -c " import json try: print('https' if json.load(open('/opt/proxy/users.json'))['server'].get('tls') else 'http') except Exception: print('http') ")" HOSTNAME_SHOW="${DOMAIN:-$HOST_IP}" SUB="$(PROXY_BASE=/opt/proxy proxyctl suburl "$FIRST_USER" 2>/dev/null || echo '(执行 proxyctl list 查看)')" echo line echo -e "${C_B} 安装完成${C_0}" line echo " 面板地址 : ${SCHEME}://${HOSTNAME_SHOW}:${PORT}/admin/" echo " 用户门户 : ${SCHEME}://${HOSTNAME_SHOW}:${PORT}/" echo " 订阅地址 : ${SUB}" echo echo " 管理员账号 : admin" echo " 首个用户 : ${FIRST_USER}" echo -e " ${C_Y}账号密码见上方安装日志,或执行:proxyctl setpass / proxyctl setpass-user ${FIRST_USER}${C_0}" echo echo " 管理菜单 : scdn" if [[ -z "$DOMAIN" ]]; then echo echo -e " ${C_Y}当前未绑定域名,节点直接使用 IP。建议后续绑定:${C_0}" echo " proxyctl set-domain node.你的域名.com" fi line echo " 完整安装日志:$DEPLOY_LOG" line