From e74c0f584de16ba32a1b71241e67fc10bf8db45e Mon Sep 17 00:00:00 2001 From: mango Date: Sat, 14 Feb 2026 21:16:09 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=AE=8C=E6=95=B4=E9=87=8D=E5=86=99?= =?UTF-8?q?=EF=BC=8C=E7=94=A8python3=E7=94=9F=E6=88=90JSON=E9=81=BF?= =?UTF-8?q?=E5=85=8D=E5=8F=98=E9=87=8F=E6=B1=A1=E6=9F=93=EF=BC=8C=E7=AB=AF?= =?UTF-8?q?=E5=8F=A3=E5=AF=86=E7=A0=81=E5=8F=AF=E8=87=AA=E5=AE=9A=E4=B9=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ss-rust.sh | 451 +++++++++++++++++++++-------------------------------- 1 file changed, 176 insertions(+), 275 deletions(-) diff --git a/ss-rust.sh b/ss-rust.sh index 26d6d60..61640b4 100644 --- a/ss-rust.sh +++ b/ss-rust.sh @@ -15,6 +15,16 @@ info() { echo -e "${GREEN}[INFO]${NC} $1"; } warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; } +# ============ 全局变量 ============ +SERVER_IP="" +PORT_2022="" +KEY_2022="" +METHOD_2022="" +PORT_RAW="" +KEY_RAW="" +METHOD_RAW="" +NODE_MODE="" + # ============ 基础检测 ============ check_root() { [[ $EUID -ne 0 ]] && error "请使用 root 用户运行" @@ -35,9 +45,9 @@ get_pkg_manager() { install_deps() { info "安装依赖..." case $PKG in - apt) apt update -qq &>/dev/null; apt install -y -qq curl openssl xz-utils tar chrony &>/dev/null ;; - yum) yum install -y -q curl openssl xz tar chrony &>/dev/null ;; - apk) apk add --quiet curl openssl xz tar chrony &>/dev/null ;; + apt) apt update -qq &>/dev/null; apt install -y -qq curl openssl xz-utils tar chrony python3 &>/dev/null ;; + yum) yum install -y -q curl openssl xz tar chrony python3 &>/dev/null ;; + apk) apk add --quiet curl openssl xz tar chrony python3 &>/dev/null ;; esac } @@ -51,9 +61,10 @@ get_arch() { } get_ip() { - IP=$(curl -s4m5 ip.sb 2>/dev/null || curl -s4m5 ifconfig.me 2>/dev/null || curl -s4m5 ipinfo.io/ip 2>/dev/null) - [[ -z "$IP" ]] && error "无法获取公网IP" - echo "$IP" + local ip + ip=$(curl -s4m5 ip.sb 2>/dev/null || curl -s4m5 ifconfig.me 2>/dev/null || curl -s4m5 ipinfo.io/ip 2>/dev/null) + [[ -z "$ip" ]] && error "无法获取公网IP" + echo "$ip" } # ============ 时间同步 ============ @@ -72,65 +83,47 @@ sync_time() { # ============ 安装 ss-rust ============ install_ssrust() { info "安装 shadowsocks-rust..." - ARCH_NAME=$(get_arch) - - LATEST=$(curl -sLm10 https://api.github.com/repos/shadowsocks/shadowsocks-rust/releases/latest | grep tag_name | head -1 | grep -oP 'v[\d.]+') - [[ -z "$LATEST" ]] && LATEST="v1.24.0" - info "版本: $LATEST" - - URL="https://github.com/shadowsocks/shadowsocks-rust/releases/download/${LATEST}/shadowsocks-${LATEST}.${ARCH_NAME}.tar.xz" - + local arch_name + arch_name=$(get_arch) + + local latest + latest=$(curl -sLm10 https://api.github.com/repos/shadowsocks/shadowsocks-rust/releases/latest | grep tag_name | head -1 | grep -oP 'v[\d.]+') + [[ -z "$latest" ]] && latest="v1.24.0" + info "版本: $latest" + + local url="https://github.com/shadowsocks/shadowsocks-rust/releases/download/${latest}/shadowsocks-${latest}.${arch_name}.tar.xz" + cd /tmp - rm -f ss-rust-dl.tar.xz - curl -sL "$URL" -o ss-rust-dl.tar.xz - - # 验证下载 - FILE_SIZE=$(stat -c%s ss-rust-dl.tar.xz 2>/dev/null || stat -f%z ss-rust-dl.tar.xz 2>/dev/null) - [[ "$FILE_SIZE" -lt 100000 ]] && error "下载失败,文件太小 (${FILE_SIZE} bytes),可能是网络问题" - + rm -f ss-rust-dl.tar.xz ssserver sslocal ssurl ssmanager ssservice + curl -sL "$url" -o ss-rust-dl.tar.xz + + local fsize + fsize=$(stat -c%s ss-rust-dl.tar.xz 2>/dev/null || stat -f%z ss-rust-dl.tar.xz 2>/dev/null) + [[ "$fsize" -lt 100000 ]] && error "下载失败 (${fsize} bytes)" + file ss-rust-dl.tar.xz | grep -q "XZ" || error "下载的文件不是有效的 XZ 压缩包" - + tar xf ss-rust-dl.tar.xz || error "解压失败" - - [[ ! -f ssserver ]] && error "解压后找不到 ssserver 二进制文件" - + [[ ! -f ssserver ]] && error "找不到 ssserver" + cp -f ssserver /usr/local/bin/ cp -f sslocal /usr/local/bin/ 2>/dev/null || true - cp -f ssurl /usr/local/bin/ 2>/dev/null || true - chmod +x /usr/local/bin/ss* - - # 清理 + chmod +x /usr/local/bin/ssserver /usr/local/bin/sslocal 2>/dev/null + rm -f ss-rust-dl.tar.xz ssserver sslocal ssurl ssmanager ssservice - + /usr/local/bin/ssserver --version && info "shadowsocks-rust 安装完成" || error "安装验证失败" } -# ============ 询问端口和密码 ============ -ask_port_key() { - local label="$1" - local default_port="$2" - local default_key="$3" - - echo "" - echo -e "${GREEN}【${label}】${NC}" - read -p " 端口 (回车随机=${default_port}): " input_port - [[ -z "$input_port" ]] && input_port="$default_port" - read -p " 密码 (回车随机=${default_key}): " input_key - [[ -z "$input_key" ]] && input_key="$default_key" - - echo "$input_port $input_key" -} - -# ============ 节点选择 + 配置生成 ============ +# ============ 节点选择 + 端口密码 + 写配置 ============ select_and_configure() { SERVER_IP=$(get_ip) mkdir -p /etc/shadowsocks-rust - - # 清空所有变量 + + # 清空 PORT_2022="" ; KEY_2022="" ; METHOD_2022="" PORT_RAW="" ; KEY_RAW="" ; METHOD_RAW="" - NODE_MODE="" - + echo "" echo -e "${CYAN}════════════════════════════════════════${NC}" echo -e "${CYAN} 🔐 选择节点类型${NC}" @@ -140,100 +133,60 @@ select_and_configure() { echo -e " ${GREEN}2.${NC} SS-AES-128 (aes-128-gcm) — 传统协议,兼容性好" echo -e " ${GREEN}3.${NC} 双节点全装 (SS2022 + SS128)" echo "" - read -p "请选择 [1-3] (默认3): " node_choice + read -rp "请选择 [1-3] (默认3): " node_choice node_choice=${node_choice:-3} - - METHOD_2022="2022-blake3-aes-128-gcm" - METHOD_RAW="aes-128-gcm" - - case "${node_choice}" in - 1) - local dp=$((RANDOM % 10000 + 20000)) - local dk=$(openssl rand -base64 16) - local result=$(ask_port_key "SS2022-128" "$dp" "$dk") - PORT_2022=$(echo "$result" | awk '{print $1}') - KEY_2022=$(echo "$result" | awk '{print $2}') - NODE_MODE="ss2022" - - cat > /etc/shadowsocks-rust/config.json << EOF -{ - "servers": [ - { - "server": "0.0.0.0", - "server_port": ${PORT_2022}, - "method": "${METHOD_2022}", - "password": "${KEY_2022}", - "timeout": 300, - "fast_open": true - } - ] -} -EOF - METHOD_RAW="" - ;; - 2) - local dp=$((RANDOM % 10000 + 30000)) - local dk=$(openssl rand -base64 16) - local result=$(ask_port_key "SS-AES-128" "$dp" "$dk") - PORT_RAW=$(echo "$result" | awk '{print $1}') - KEY_RAW=$(echo "$result" | awk '{print $2}') - NODE_MODE="ss128" - - cat > /etc/shadowsocks-rust/config.json << EOF -{ - "servers": [ - { - "server": "0.0.0.0", - "server_port": ${PORT_RAW}, - "method": "${METHOD_RAW}", - "password": "${KEY_RAW}", - "timeout": 300, - "fast_open": true - } - ] -} -EOF - METHOD_2022="" - ;; - 3|*) - local dp1=$((RANDOM % 10000 + 20000)) - local dk1=$(openssl rand -base64 16) - local result1=$(ask_port_key "SS2022-128" "$dp1" "$dk1") - PORT_2022=$(echo "$result1" | awk '{print $1}') - KEY_2022=$(echo "$result1" | awk '{print $2}') - - local dp2=$((RANDOM % 10000 + 30000)) - local dk2=$(openssl rand -base64 16) - local result2=$(ask_port_key "SS-AES-128" "$dp2" "$dk2") - PORT_RAW=$(echo "$result2" | awk '{print $1}') - KEY_RAW=$(echo "$result2" | awk '{print $2}') - NODE_MODE="both" - - cat > /etc/shadowsocks-rust/config.json << EOF -{ - "servers": [ - { - "server": "0.0.0.0", - "server_port": ${PORT_2022}, - "method": "${METHOD_2022}", - "password": "${KEY_2022}", - "timeout": 300, - "fast_open": true - }, - { - "server": "0.0.0.0", - "server_port": ${PORT_RAW}, - "method": "${METHOD_RAW}", - "password": "${KEY_RAW}", - "timeout": 300, - "fast_open": true - } - ] -} -EOF - ;; - esac - + + if [[ "$node_choice" == "1" || "$node_choice" == "3" ]]; then + local dp=$((RANDOM % 10000 + 20000)) + local dk=$(openssl rand -base64 16) + echo "" + echo -e " ${GREEN}SS2022-128 配置:${NC}" + read -rp " 端口 [回车=${dp}]: " PORT_2022 + PORT_2022=${PORT_2022:-$dp} + read -rp " 密码 [回车=${dk}]: " KEY_2022 + KEY_2022=${KEY_2022:-$dk} + METHOD_2022="2022-blake3-aes-128-gcm" + fi + + if [[ "$node_choice" == "2" || "$node_choice" == "3" ]]; then + local dp2=$((RANDOM % 10000 + 30000)) + local dk2=$(openssl rand -base64 16) + echo "" + echo -e " ${GREEN}SS-AES-128 配置:${NC}" + read -rp " 端口 [回车=${dp2}]: " PORT_RAW + PORT_RAW=${PORT_RAW:-$dp2} + read -rp " 密码 [回车=${dk2}]: " KEY_RAW + KEY_RAW=${KEY_RAW:-$dk2} + METHOD_RAW="aes-128-gcm" + fi + + # 写 JSON 配置 + python3 -c " +import json +servers = [] +if '${PORT_2022}': + servers.append({ + 'server': '0.0.0.0', + 'server_port': int('${PORT_2022}'), + 'method': '${METHOD_2022}', + 'password': '${KEY_2022}', + 'timeout': 300, + 'fast_open': True + }) +if '${PORT_RAW}': + servers.append({ + 'server': '0.0.0.0', + 'server_port': int('${PORT_RAW}'), + 'method': '${METHOD_RAW}', + 'password': '${KEY_RAW}', + 'timeout': 300, + 'fast_open': True + }) +with open('/etc/shadowsocks-rust/config.json', 'w') as f: + json.dump({'servers': servers}, f, indent=4) +print('OK') +" || error "生成配置失败" + info "配置文件: /etc/shadowsocks-rust/config.json" } @@ -254,15 +207,14 @@ LimitNOFILE=65535 [Install] WantedBy=multi-user.target EOF - + systemctl daemon-reload systemctl enable --now ss-rust sleep 2 - + if systemctl is-active --quiet ss-rust; then info "ss-rust 服务启动成功" else - echo "" journalctl -u ss-rust -n 5 --no-pager error "ss-rust 服务启动失败" fi @@ -270,18 +222,16 @@ EOF # ============ 读取现有配置 ============ load_config() { - if [[ ! -f /etc/shadowsocks-rust/config.json ]]; then - return 1 - fi + [[ ! -f /etc/shadowsocks-rust/config.json ]] && return 1 SERVER_IP=$(get_ip) - - # 用 python3 或 grep 解析 - if command -v python3 &>/dev/null; then - eval $(python3 -c " + PORT_2022="" ; KEY_2022="" ; METHOD_2022="" + PORT_RAW="" ; KEY_RAW="" ; METHOD_RAW="" + + eval $(python3 -c " import json with open('/etc/shadowsocks-rust/config.json') as f: c = json.load(f) -for i,s in enumerate(c['servers']): +for s in c['servers']: m = s['method'] if '2022' in m: print(f'PORT_2022={s[\"server_port\"]}') @@ -291,80 +241,41 @@ for i,s in enumerate(c['servers']): print(f'PORT_RAW={s[\"server_port\"]}') print(f'KEY_RAW={s[\"password\"]}') print(f'METHOD_RAW={m}') -n = len(c['servers']) -if n == 1: - if '2022' in c['servers'][0]['method']: - print('NODE_MODE=ss2022') - else: - print('NODE_MODE=ss128') -else: - print('NODE_MODE=both') " 2>/dev/null) - fi return 0 } # ============ 生成订阅 ============ gen_subscribe() { load_config || return - SUB_DIR="/etc/shadowsocks-rust/subscribe" - mkdir -p "$SUB_DIR" - - SS_URIS="" - SURGE_PROXIES="" - CLASH_PROXIES="" - INFO_NODES="" - SURGE_NAMES="" - - if [[ -n "${PORT_2022:-}" ]]; then - URI_2022="ss://$(echo -n "${METHOD_2022}:${KEY_2022}" | base64 -w0)@${SERVER_IP}:${PORT_2022}#SS2022-128" - SS_URIS="${SS_URIS}${URI_2022}\n" - SURGE_PROXIES="${SURGE_PROXIES}SS2022-128 = ss, ${SERVER_IP}, ${PORT_2022}, encrypt-method=${METHOD_2022}, password=${KEY_2022}\n" - SURGE_NAMES="${SURGE_NAMES}SS2022-128, " - CLASH_PROXIES="${CLASH_PROXIES} - name: SS2022-128\n type: ss\n server: ${SERVER_IP}\n port: ${PORT_2022}\n cipher: ${METHOD_2022}\n password: \"${KEY_2022}\"\n\n" - INFO_NODES="${INFO_NODES}【SS2022-AES-128】新协议\n 地址: ${SERVER_IP}\n 端口: ${PORT_2022}\n 加密: ${METHOD_2022}\n 密码: ${KEY_2022}\n\n" - fi - - if [[ -n "${PORT_RAW:-}" ]]; then - URI_RAW="ss://$(echo -n "${METHOD_RAW}:${KEY_RAW}" | base64 -w0)@${SERVER_IP}:${PORT_RAW}#SS-AES-128" - SS_URIS="${SS_URIS}${URI_RAW}\n" - SURGE_PROXIES="${SURGE_PROXIES}SS-AES-128 = ss, ${SERVER_IP}, ${PORT_RAW}, encrypt-method=${METHOD_RAW}, password=${KEY_RAW}\n" - SURGE_NAMES="${SURGE_NAMES}SS-AES-128, " - CLASH_PROXIES="${CLASH_PROXIES} - name: SS-AES-128\n type: ss\n server: ${SERVER_IP}\n port: ${PORT_RAW}\n cipher: ${METHOD_RAW}\n password: \"${KEY_RAW}\"\n\n" - INFO_NODES="${INFO_NODES}【SS-AES-128】传统协议\n 地址: ${SERVER_IP}\n 端口: ${PORT_RAW}\n 加密: ${METHOD_RAW}\n 密码: ${KEY_RAW}\n\n" - fi - - # Base64 订阅 - echo -e "${SS_URIS}" | base64 -w0 > "$SUB_DIR/subscribe.txt" - - # Surge - cat > "$SUB_DIR/surge.conf" << EOF -# Surge SS 配置 | $(date '+%Y-%m-%d %H:%M:%S') | ${SERVER_IP} -[Proxy] -$(echo -e "${SURGE_PROXIES}") -[Proxy Group] -Proxy = select, $(echo "${SURGE_NAMES}DIRECT" | sed 's/, DIRECT$/, DIRECT/') -EOF - - # Clash - cat > "$SUB_DIR/clash.yaml" << EOF -# Clash SS 配置 | $(date '+%Y-%m-%d %H:%M:%S') -proxies: -$(echo -e "${CLASH_PROXIES}") -EOF - - # Info - cat > "$SUB_DIR/info.txt" << EOF -════════════════════════════════════════ - Shadowsocks-Rust 节点信息 - $(date '+%Y-%m-%d %H:%M:%S') | ${SERVER_IP} -════════════════════════════════════════ + local sub_dir="/etc/shadowsocks-rust/subscribe" + mkdir -p "$sub_dir" -$(echo -e "${INFO_NODES}") -【SS 链接】 -$(echo -e "${SS_URIS}") -════════════════════════════════════════ -EOF + local uris="" surge="" clash="" info_txt="" + + if [[ -n "$PORT_2022" ]]; then + local uri="ss://$(echo -n "${METHOD_2022}:${KEY_2022}" | base64 -w0)@${SERVER_IP}:${PORT_2022}#SS2022-128" + URI_2022="$uri" + uris="${uris}${uri}\n" + surge="${surge}SS2022-128 = ss, ${SERVER_IP}, ${PORT_2022}, encrypt-method=${METHOD_2022}, password=${KEY_2022}\n" + clash="${clash} - name: SS2022-128\n type: ss\n server: ${SERVER_IP}\n port: ${PORT_2022}\n cipher: ${METHOD_2022}\n password: \"${KEY_2022}\"\n\n" + info_txt="${info_txt}【SS2022-AES-128】新协议\n 地址: ${SERVER_IP}\n 端口: ${PORT_2022}\n 加密: ${METHOD_2022}\n 密码: ${KEY_2022}\n\n" + fi + + if [[ -n "$PORT_RAW" ]]; then + local uri="ss://$(echo -n "${METHOD_RAW}:${KEY_RAW}" | base64 -w0)@${SERVER_IP}:${PORT_RAW}#SS-AES-128" + URI_RAW="$uri" + uris="${uris}${uri}\n" + surge="${surge}SS-AES-128 = ss, ${SERVER_IP}, ${PORT_RAW}, encrypt-method=${METHOD_RAW}, password=${KEY_RAW}\n" + clash="${clash} - name: SS-AES-128\n type: ss\n server: ${SERVER_IP}\n port: ${PORT_RAW}\n cipher: ${METHOD_RAW}\n password: \"${KEY_RAW}\"\n\n" + info_txt="${info_txt}【SS-AES-128】传统协议\n 地址: ${SERVER_IP}\n 端口: ${PORT_RAW}\n 加密: ${METHOD_RAW}\n 密码: ${KEY_RAW}\n\n" + fi + + echo -e "$uris" | base64 -w0 > "$sub_dir/subscribe.txt" + + echo -e "# Surge SS | $(date '+%Y-%m-%d %H:%M:%S') | ${SERVER_IP}\n[Proxy]\n${surge}" > "$sub_dir/surge.conf" + echo -e "# Clash SS | $(date '+%Y-%m-%d %H:%M:%S')\nproxies:\n${clash}" > "$sub_dir/clash.yaml" + echo -e "═══ SS-Rust 节点 | $(date '+%Y-%m-%d %H:%M:%S') | ${SERVER_IP} ═══\n\n${info_txt}\n【SS 链接】\n${uris}" > "$sub_dir/info.txt" } # ============ 显示结果 ============ @@ -375,57 +286,51 @@ show_result() { echo -e "${CYAN} 🚀 Shadowsocks-Rust 安装完成${NC}" echo -e "${CYAN}════════════════════════════════════════${NC}" echo "" - - if [[ -n "${PORT_2022:-}" ]]; then - echo -e "${GREEN}【节点1】SS2022-AES-128 (新协议)${NC}" + + if [[ -n "$PORT_2022" ]]; then + echo -e "${GREEN}【SS2022-AES-128】新协议${NC}" echo -e " 地址: ${SERVER_IP}" echo -e " 端口: ${YELLOW}${PORT_2022}${NC}" echo -e " 加密: ${METHOD_2022}" echo -e " 密码: ${YELLOW}${KEY_2022}${NC}" echo "" fi - - if [[ -n "${PORT_RAW:-}" ]]; then - echo -e "${GREEN}【节点2】SS-AES-128 (传统协议)${NC}" + + if [[ -n "$PORT_RAW" ]]; then + echo -e "${GREEN}【SS-AES-128】传统协议${NC}" echo -e " 地址: ${SERVER_IP}" echo -e " 端口: ${YELLOW}${PORT_RAW}${NC}" echo -e " 加密: ${METHOD_RAW}" echo -e " 密码: ${YELLOW}${KEY_RAW}${NC}" echo "" fi - + echo -e "${CYAN}────────────────────────────────────────${NC}" echo -e "${GREEN}【Surge 格式】${NC}" - [[ -n "${PORT_2022:-}" ]] && echo -e " SS2022-128 = ss, ${SERVER_IP}, ${PORT_2022}, encrypt-method=${METHOD_2022}, password=${KEY_2022}" - [[ -n "${PORT_RAW:-}" ]] && echo -e " SS-AES-128 = ss, ${SERVER_IP}, ${PORT_RAW}, encrypt-method=${METHOD_RAW}, password=${KEY_RAW}" + [[ -n "$PORT_2022" ]] && echo " SS2022-128 = ss, ${SERVER_IP}, ${PORT_2022}, encrypt-method=${METHOD_2022}, password=${KEY_2022}" + [[ -n "$PORT_RAW" ]] && echo " SS-AES-128 = ss, ${SERVER_IP}, ${PORT_RAW}, encrypt-method=${METHOD_RAW}, password=${KEY_RAW}" echo "" - + echo -e "${CYAN}────────────────────────────────────────${NC}" echo -e "${GREEN}【SS 链接】${NC}" - [[ -n "${URI_2022:-}" ]] && echo -e " ${URI_2022}" - [[ -n "${URI_RAW:-}" ]] && echo -e " ${URI_RAW}" + [[ -n "${URI_2022:-}" ]] && echo " ${URI_2022}" + [[ -n "${URI_RAW:-}" ]] && echo " ${URI_RAW}" echo "" - + echo -e "${CYAN}────────────────────────────────────────${NC}" - echo -e "${GREEN}【文件位置】${NC}" - echo -e " 配置: /etc/shadowsocks-rust/config.json" - echo -e " 订阅: /etc/shadowsocks-rust/subscribe/subscribe.txt" - echo -e " Surge: /etc/shadowsocks-rust/subscribe/surge.conf" - echo -e " Clash: /etc/shadowsocks-rust/subscribe/clash.yaml" + echo -e "${GREEN}【文件】${NC}" + echo " 配置: /etc/shadowsocks-rust/config.json" + echo " 订阅: /etc/shadowsocks-rust/subscribe/" echo "" - echo -e "${CYAN}【管理】${NC} 再次运行本脚本即可进入管理菜单" + echo -e "${CYAN}【管理】${NC} 再次运行脚本进入管理菜单" echo -e "${CYAN}════════════════════════════════════════${NC}" } # ============ 查看配置 ============ show_config() { - load_config || error "未安装 shadowsocks-rust" + load_config || error "未安装" echo "" - echo -e "${CYAN}════════════════════════════════════════${NC}" - echo -e "${CYAN} 📋 当前配置${NC}" - echo -e "${CYAN}════════════════════════════════════════${NC}" - echo "" - echo -e "${GREEN}服务状态:${NC} $(systemctl is-active ss-rust 2>/dev/null || echo '未运行')" + echo -e "${CYAN} 📋 当前配置 | 状态: $(systemctl is-active ss-rust 2>/dev/null)${NC}" echo "" cat /etc/shadowsocks-rust/config.json echo "" @@ -434,15 +339,14 @@ show_config() { # ============ 修改端口 ============ change_port() { - load_config || error "未安装 shadowsocks-rust" + load_config || error "未安装" echo "" - echo -e "${GREEN}当前节点:${NC}" - [[ -n "${PORT_2022:-}" ]] && echo -e " 1) SS2022-128 | 端口 ${PORT_2022}" - [[ -n "${PORT_RAW:-}" ]] && echo -e " 2) SS-AES-128 | 端口 ${PORT_RAW}" + [[ -n "$PORT_2022" ]] && echo -e " 1) SS2022-128 | 端口 ${PORT_2022}" + [[ -n "$PORT_RAW" ]] && echo -e " 2) SS-AES-128 | 端口 ${PORT_RAW}" echo "" - read -p "输入节点编号: " pn - read -p "输入新端口: " new_port - + read -rp "节点编号: " pn + read -rp "新端口: " new_port + python3 -c " import json with open('/etc/shadowsocks-rust/config.json') as f: @@ -452,27 +356,24 @@ if 0 <= idx < len(c['servers']): c['servers'][idx]['server_port'] = int('${new_port}') with open('/etc/shadowsocks-rust/config.json','w') as f: json.dump(c, f, indent=4) -" 2>/dev/null - +" systemctl restart ss-rust gen_subscribe - info "端口已修改为 ${new_port},订阅已更新" + info "端口已改为 ${new_port}" } # ============ 重置密钥 ============ reset_keys() { - load_config || error "未安装 shadowsocks-rust" - + load_config || error "未安装" python3 -c " -import json, subprocess, base64, os +import json,base64,os with open('/etc/shadowsocks-rust/config.json') as f: c = json.load(f) for s in c['servers']: s['password'] = base64.b64encode(os.urandom(16)).decode() with open('/etc/shadowsocks-rust/config.json','w') as f: json.dump(c, f, indent=4) -" 2>/dev/null - +" systemctl restart ss-rust gen_subscribe info "密钥已重置" @@ -491,7 +392,7 @@ uninstall() { info "卸载完成" } -# ============ 完整安装流程 ============ +# ============ 安装流程 ============ do_install() { get_pkg_manager install_deps @@ -521,16 +422,16 @@ show_menu() { echo -e " ${RED}9.${NC} 卸载" echo -e " ${YELLOW}0.${NC} 退出" echo "" - read -p "请选择 [0-9]: " choice - + read -rp "请选择 [0-9]: " choice + case "$choice" in 1) do_install ;; 2) show_config ;; 3) change_port ;; 4) reset_keys ;; - 5) systemctl start ss-rust && info "服务已启动" ;; - 6) systemctl stop ss-rust && info "服务已停止" ;; - 7) systemctl restart ss-rust && info "服务已重启" ;; + 5) systemctl start ss-rust && info "已启动" ;; + 6) systemctl stop ss-rust && info "已停止" ;; + 7) systemctl restart ss-rust && info "已重启" ;; 8) journalctl -u ss-rust --no-pager -n 30 ;; 9) uninstall ;; 0) exit 0 ;; @@ -542,14 +443,14 @@ show_menu() { main() { check_root case "${1:-}" in - install) do_install ;; - uninstall|remove) uninstall ;; - show|config|info) show_config ;; - restart) systemctl restart ss-rust && info "服务已重启" ;; - start) systemctl start ss-rust && info "服务已启动" ;; - stop) systemctl stop ss-rust && info "服务已停止" ;; - log|logs) journalctl -u ss-rust --no-pager -n 30 ;; - reset) reset_keys ;; + install) do_install ;; + uninstall|remove) uninstall ;; + show|config|info) show_config ;; + restart) systemctl restart ss-rust && info "已重启" ;; + start) systemctl start ss-rust && info "已启动" ;; + stop) systemctl stop ss-rust && info "已停止" ;; + log|logs) journalctl -u ss-rust --no-pager -n 30 ;; + reset) reset_keys ;; *) if [[ -f /etc/shadowsocks-rust/config.json ]]; then show_menu