#!/bin/bash # ============================================================== # Shadowsocks-Rust 一键安装脚本 (openEuler / CTyunOS 适配版) # ============================================================== set -euo pipefail # ==================== 配置区 ==================== # ① GitHub API(通过代理加速) GITHUB_API_LATEST="https://gh-proxy.org/https://api.github.com/repos/shadowsocks/shadowsocks-rust/releases/latest" # ② Shadowsocks-rust 下载基础 URL DOWNLOAD_BASE_URL="https://gh-proxy.org/https://github.com/shadowsocks/shadowsocks-rust/releases/download" # ③ 默认版本(API 获取失败时使用) DEFAULT_VER="v1.24.0" # ④ 端口与密码配置 SS_PORT=1445 SS_PASSWORD="QwjJSc3QqDiNZV17K2MqFQ==" SS_METHOD="chacha20-ietf-poly1305" # ==================== 输出样式 ==================== RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[0;33m' PLAIN='\033[0m' # ==================== 基础检查 ==================== if [ "$(id -u)" -ne 0 ]; then echo -e "${RED}必须使用 root 权限运行此脚本${PLAIN}" exit 1 fi echo -e "${GREEN}====================================================${PLAIN}" echo -e "${GREEN} Shadowsocks-Rust 一键安装脚本 (openEuler / CTyunOS 适配版) ${PLAIN}" echo -e "${GREEN}====================================================${PLAIN}" # ==================== [1/7] 安装依赖 ==================== echo -e "${YELLOW}[1/7] 更新系统并安装依赖 (适配 openEuler / CTyunOS)…${PLAIN}" if command -v dnf &>/dev/null; then echo "检测到包管理器: dnf (openEuler / CTyunOS)" dnf makecache -y || true # openEuler / CentOS 下 xz 工具包名为 xz(非 xz-utils),核心组件优先安装 dnf install -y wget curl tar xz openssl || yum install -y wget curl tar xz openssl # jq 与 qrencode 为辅助工具,如源中无此包不阻断安装 dnf install -y jq 2>/dev/null || yum install -y jq 2>/dev/null || true dnf install -y qrencode 2>/dev/null || yum install -y qrencode 2>/dev/null || true elif command -v yum &>/dev/null; then echo "检测到包管理器: yum (openEuler / CTyunOS / CentOS)" yum makecache || true yum install -y wget curl tar xz openssl yum install -y jq 2>/dev/null || true yum install -y qrencode 2>/dev/null || true elif command -v apt-get &>/dev/null; then echo "检测到包管理器: apt-get (Debian / Ubuntu)" apt-get update -y apt-get install -y wget curl tar xz-utils openssl || true apt-get install -y jq qrencode 2>/dev/null || true else echo -e "${YELLOW}未检测到标准包管理器,跳过依赖安装步骤${PLAIN}" fi # ==================== [2/7] 检测系统架构 ==================== echo -e "${YELLOW}[2/7] 检测系统架构…${PLAIN}" UNAME_ARCH=$(uname -m) case "$UNAME_ARCH" in x86_64) # 必须使用 musl 纯静态编译版本,彻底摆脱 openEuler / CTyunOS 的 GLIBC 版本限制 (避免 GLIBC_2.39 not found) ARCH="x86_64-unknown-linux-musl" ;; aarch64|arm64) ARCH="aarch64-unknown-linux-musl" ;; *) echo -e "${RED}不支持的系统架构:${UNAME_ARCH}${PLAIN}" exit 1 ;; esac echo -e "架构匹配:${GREEN}${UNAME_ARCH} -> ${ARCH}${PLAIN}" # ==================== [3/7] 下载并安装 Shadowsocks-rust ==================== echo -e "${YELLOW}[3/7] 获取并下载 Shadowsocks-rust…${PLAIN}" LATEST_VER="" if command -v jq &>/dev/null; then LATEST_VER=$(curl -s --connect-timeout 8 "${GITHUB_API_LATEST}" | jq -r .tag_name 2>/dev/null || true) fi if [ -z "$LATEST_VER" ] || [ "$LATEST_VER" = "null" ]; then echo -e "${YELLOW}API 获取最新版本失败,使用默认版本 ${DEFAULT_VER}${PLAIN}" LATEST_VER="${DEFAULT_VER}" fi echo -e "目标版本:${GREEN}${LATEST_VER}${PLAIN}" TMP_DIR=$(mktemp -d) DOWNLOAD_URL="${DOWNLOAD_BASE_URL}/${LATEST_VER}/shadowsocks-${LATEST_VER}.${ARCH}.tar.xz" CANDIDATE_URLS=( "${DOWNLOAD_URL}" "https://gh-proxy.com/github.com/shadowsocks/shadowsocks-rust/releases/download/${LATEST_VER}/shadowsocks-${LATEST_VER}.${ARCH}.tar.xz" "https://github.com/shadowsocks/shadowsocks-rust/releases/download/${LATEST_VER}/shadowsocks-${LATEST_VER}.${ARCH}.tar.xz" ) DOWNLOAD_OK=false for url in "${CANDIDATE_URLS[@]}"; do echo -e "尝试下载: ${YELLOW}${url}${PLAIN}" if wget --no-check-certificate -q -O "${TMP_DIR}/ss-rust.tar.xz" "$url" || curl -fsSL -o "${TMP_DIR}/ss-rust.tar.xz" "$url"; then if [ -s "${TMP_DIR}/ss-rust.tar.xz" ]; then DOWNLOAD_OK=true echo -e "${GREEN}下载成功${PLAIN}" break fi fi done if [ "$DOWNLOAD_OK" != "true" ]; then echo -e "${RED}下载 Shadowsocks-rust 失败,请检查网络连接!${PLAIN}" rm -rf "${TMP_DIR}" exit 1 fi echo "解压组件中…" tar -xf "${TMP_DIR}/ss-rust.tar.xz" -C "${TMP_DIR}" mkdir -p /usr/local/bin for bin in ssserver sslocal ssurl; do if [ -f "${TMP_DIR}/${bin}" ]; then mv -f "${TMP_DIR}/${bin}" /usr/local/bin/ chmod +x "/usr/local/bin/${bin}" fi done rm -rf "${TMP_DIR}" if ! command -v ssserver >/dev/null; then echo -e "${RED}安装失败:未在 /usr/local/bin 中找到 ssserver${PLAIN}" exit 1 fi # SELinux 标签恢复 (openEuler / CTyunOS 默认开启 SELinux) if command -v restorecon &>/dev/null; then restorecon -Rv /usr/local/bin/ssserver /usr/local/bin/sslocal /usr/local/bin/ssurl 2>/dev/null || true fi echo -e "${GREEN}Shadowsocks-rust 组件安装成功${PLAIN}" # ==================== [4/7] 写入配置文件 ==================== echo -e "${YELLOW}[4/7] 写入配置文件…${PLAIN}" mkdir -p /etc/shadowsocks-rust cat > /etc/shadowsocks-rust/config.json < /etc/systemd/system/shadowsocks-rust.service </dev/null || true systemctl enable shadowsocks-rust systemctl restart shadowsocks-rust sleep 2 if systemctl is-active --quiet shadowsocks-rust; then echo -e "${GREEN}Shadowsocks-Rust 服务启动成功并在后台正常运行${PLAIN}" else echo -e "${RED}警告:Shadowsocks-Rust 服务启动异常,正在输出状态日志:${PLAIN}" systemctl status shadowsocks-rust --no-pager -l || true fi # openEuler / CTyunOS 默认开启 firewalld,自动放行端口 if systemctl is-active --quiet firewalld 2>/dev/null; then echo "检测到 firewalld 正在运行,正在放行端口 ${SS_PORT}/tcp 与 ${SS_PORT}/udp..." firewall-cmd --zone=public --add-port=${SS_PORT}/tcp --permanent >/dev/null 2>&1 || true firewall-cmd --zone=public --add-port=${SS_PORT}/udp --permanent >/dev/null 2>&1 || true firewall-cmd --reload >/dev/null 2>&1 || true echo -e "${GREEN}防火墙已自动放行端口 ${SS_PORT}${PLAIN}" fi # ==================== [6/7] 检测与配置 BBR ==================== echo -e "${YELLOW}[6/7] 检测与配置 BBR 加速…${PLAIN}" # openEuler / CTyunOS 内核默认包含 tcp_bbr 模块,但需显式加载 modprobe tcp_bbr 2>/dev/null || true if sysctl net.ipv4.tcp_available_congestion_control 2>/dev/null | grep -q "bbr"; then echo -e "${GREEN}内核支持 BBR,正在配置优化参数...${PLAIN}" mkdir -p /etc/sysctl.d cat > /etc/sysctl.d/99-ss-bbr.conf </dev/null 2>&1 || sysctl -p /etc/sysctl.d/99-ss-bbr.conf >/dev/null 2>&1 || true # 确保 openEuler 开机自动加载 tcp_bbr 模块 mkdir -p /etc/modules-load.d echo "tcp_bbr" > /etc/modules-load.d/bbr.conf 2>/dev/null || true echo -e "${GREEN}BBR 已成功启用并设置开机自启${PLAIN}" else echo -e "${YELLOW}内核未检测到 BBR 模块支持,跳过 BBR 配置${PLAIN}" fi # ==================== [7/7] 输出连接信息 ==================== echo -e "${YELLOW}[7/7] 生成连接信息…${PLAIN}" # 获取公网 IP (多接口降级与超时控制) PUBLIC_IP=$(curl -s --connect-timeout 5 https://api.ipify.org || curl -s --connect-timeout 5 https://ifconfig.me || curl -s --connect-timeout 5 https://ip.sb || echo "your_server_ip") BASE64_STR=$(echo -n "${SS_METHOD}:${SS_PASSWORD}" | base64 -w 0 2>/dev/null || echo -n "${SS_METHOD}:${SS_PASSWORD}" | base64) SS_URL="ss://${BASE64_STR}@${PUBLIC_IP}:${SS_PORT}#SS-Rust-${SS_PORT}" echo -e "${GREEN}=============================================${PLAIN}" echo -e "服务器 IP : ${GREEN}${PUBLIC_IP}${PLAIN}" echo -e "端口 Port : ${GREEN}${SS_PORT}${PLAIN}" echo -e "密码 Pass : ${GREEN}${SS_PASSWORD}${PLAIN}" echo -e "加密方式 : ${GREEN}${SS_METHOD}${PLAIN}" echo echo -e "导入链接:" echo -e "${GREEN}${SS_URL}${PLAIN}" echo if command -v qrencode &>/dev/null; then echo -e "二维码:" qrencode -t ansiutf8 "${SS_URL}" || echo "二维码生成失败" fi echo -e "${GREEN}=============================================${PLAIN}" echo -e "配置文件: /etc/shadowsocks-rust/config.json" echo -e "服务状态: systemctl status shadowsocks-rust" echo -e "重启服务: systemctl restart shadowsocks-rust"