diff --git a/README.md b/README.md index 7c29883..ce991de 100644 --- a/README.md +++ b/README.md @@ -2,28 +2,6 @@ ## 常用脚本 -- vps_init -```sh -curl -sS -O https://gitea.tohub.top/Share/vps/raw/branch/main/init/vps_init.sh && chmod +x vps_init.sh && ./vps_init.sh -``` - -- v2raya -```sh -curl -sS -O https://gitea.tohub.top/Share/vps/raw/branch/main/v2raya/v2raya.sh && chmod +x v2raya.sh && ./v2raya.sh -``` - -- xray-manager -```sh -curl -sS -O https://gitea.tohub.top/Share/vps/raw/branch/main/init/xray-manager.sh && chmod +x xray-manager.sh && ./xray-manager.sh -``` - -- ddns-go -```sh -curl -sS -O https://gitea.tohub.top/Share/vps/raw/branch/main/init/ddns-go.sh && chmod +x ddns-go.sh && ./ddns-go.sh -``` - -## 其他脚本 - - sysUpdate ```sh curl -sS -O https://gitea.tohub.top/Share/vps/raw/branch/main/init/01-sysUpdate.sh && chmod +x 01-sysUpdate.sh && ./01-sysUpdate.sh @@ -40,3 +18,74 @@ curl -sS -O https://gitea.tohub.top/Share/vps/raw/branch/main/init/03-docker.sh ``` +## 安装 + +- 01-Nginx +```sh +bash <(curl -fsSL https://gitea.tohub.top/Share/vps/raw/branch/main/install/01-Nginx.sh) +``` + +- 02-NginxProxy +```sh +bash <(curl -fsSL https://gitea.tohub.top/Share/vps/raw/branch/main/install/02-NginxProxy.sh) +``` + +- 03-X-UI.sh +```sh +bash <(curl -fsSL https://gitea.tohub.top/Share/vps/raw/branch/main/install/03-X-UI.sh) +``` + +- 04-FRP.sh +```sh +bash <(curl -fsSL https://gitea.tohub.top/Share/vps/raw/branch/main/install/04-FRP.sh) +``` + +- 05-ZeroTier.sh +```sh +bash <(curl -fsSL https://gitea.tohub.top/Share/vps/raw/branch/main/install/05-ZeroTier.sh) +``` + +- 06-Rustdesk.sh +```sh +bash <(curl -fsSL https://gitea.tohub.top/Share/vps/raw/branch/main/install/06-Rustdesk.sh) +``` + +- 07-Alist.sh +```sh +bash <(curl -fsSL https://gitea.tohub.top/Share/vps/raw/branch/main/install/07-Alist.sh) +``` + +- 08-Duplicati.sh +```sh +bash <(curl -fsSL https://gitea.tohub.top/Share/vps/raw/branch/main/install/08-Duplicati.sh) +``` + +- 09-Syncthing.sh +```sh +bash <(curl -fsSL https://gitea.tohub.top/Share/vps/raw/branch/main/install/09-Syncthing.sh) +``` + +- 10-Vaultwarden.sh +```sh +bash <(curl -fsSL https://gitea.tohub.top/Share/vps/raw/branch/main/install/10-Vaultwarden.sh) +``` + +- 11-EasyImage.sh +```sh +bash <(curl -fsSL https://gitea.tohub.top/Share/vps/raw/branch/main/install/11-EasyImage.sh) +``` + +- 12-Wordpress.sh +```sh +bash <(curl -fsSL https://gitea.tohub.top/Share/vps/raw/branch/main/install/12-Wordpress.sh) +``` + +- 13-Nextcloud.sh +```sh +bash <(curl -fsSL https://gitea.tohub.top/Share/vps/raw/branch/main/install/13-Nextcloud.sh) +``` + +- 14-Joplin.sh +```sh +bash <(curl -fsSL https://gitea.tohub.top/Share/vps/raw/branch/main/install/14-Joplin.sh) +``` \ No newline at end of file diff --git a/init/ddns-go.sh b/init/ddns-go.sh deleted file mode 100644 index 8075ec1..0000000 --- a/init/ddns-go.sh +++ /dev/null @@ -1,782 +0,0 @@ -#!/bin/bash -# ddns-go 自动安装脚本 -# 使用方法: chmod +x ddns-go.sh && ./ddns-go.sh -# curl -sS -O https://gitea.tohub.top/Share/vps/raw/branch/main/init/ddns-go.sh && chmod +x ddns-go.sh && ./ddns-go.sh - -# 彩色输出 -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[0;33m' -BLUE='\033[0;34m' -CYAN='\033[0;36m' -NC='\033[0m' # No Color - -# 全局变量 -DDNS_VERSION="" # 当前指定的 ddns-go 版本 -DDNS_PATH="/root/ddns" -SCRIPT_VERSION="1.0.0" - -# 日志函数 -log_info() { - echo -e "${GREEN}[信息]${NC} $1" -} - -log_warn() { - echo -e "${YELLOW}[警告]${NC} $1" -} - -log_error() { - echo -e "${RED}[错误]${NC} $1" -} - -# 获取最新版本号 -get_latest_version() { - local version="" - - # 方法1:利用GitHub重定向特性获取最新版本 - local redirect_url=$(curl -s -L -o /dev/null -w '%{url_effective}' https://github.com/jeessy2/ddns-go/releases/latest 2>/dev/null) - version=$(echo "$redirect_url" | grep -o 'tag/v[0-9.]*' | cut -d/ -f2 2>/dev/null) - - # 如果获取失败,尝试备用方法 - if [[ -z "$version" ]]; then - # 方法2: 通过API获取 - version=$(curl -s https://api.github.com/repos/jeessy2/ddns-go/releases/latest | grep -o '"tag_name": "v[0-9.]*"' | cut -d'"' -f4 2>/dev/null) - fi - - # 如果还是失败,返回默认版本 - if [[ -z "$version" ]]; then - version="v6.9.1" # 默认版本 - fi - - # 直接返回版本号,不打印任何日志 - echo "$version" -} - -# 检测系统架构 -detect_arch() { - # 获取架构 - local arch=$(uname -m) - local arch_type="" - - # 转换架构名称为ddns-go使用的格式 - case "$arch" in - x86_64) - arch_type="linux_x86_64" - ;; - i386|i686) - arch_type="linux_x86" - ;; - aarch64|arm64) - arch_type="linux_arm64" - ;; - armv7*|armv6*) - arch_type="linux_armv7" - ;; - armv8*) - arch_type="linux_arm64" - ;; - *) - log_warn "未知架构: $arch,将尝试使用x86_64版本" - arch_type="linux_x86_64" - ;; - esac - - # 直接返回结果而不是写入临时文件 - echo "$arch_type" -} - -# 获取IP地址信息 -get_ip_info() { - local ipv4=$(curl -s ipv4.ip.sb) - local ipv6=$(curl -s ipv6.ip.sb 2>/dev/null || echo "无") - - echo "$ipv4|$ipv6" -} - -# 配置防火墙 - 仅处理 UFW -configure_firewall() { - local port=$1 - log_info "配置防火墙" - - # 检查是否安装了 ufw - if command -v ufw &>/dev/null; then - # 检查ufw是否启用 - local ufw_status=$(ufw status | grep -o "Status: active" 2>/dev/null) - - if [[ -z "$ufw_status" ]]; then - log_warn "UFW 防火墙未启用,可能需要手动配置防火墙规则" - log_info "您可以运行 'sudo ufw enable' 启用 UFW 防火墙" - return 0 - fi - - # 检查端口是否已经开放 - if ufw status | grep -q "$port/tcp"; then - log_info "端口 $port 已经开放,跳过" - return 0 - fi - - # 开放端口 - echo -n "配置 UFW 防火墙,开放端口 $port... " - if ufw allow "$port/tcp" &>/dev/null; then - echo -e "${GREEN}完成${NC}" - log_info "已在 UFW 防火墙开放端口: $port" - else - echo -e "${RED}失败${NC}" - log_warn "无法开放端口 $port" - fi - else - log_warn "未检测到 UFW 防火墙,跳过防火墙配置" - log_info "如需管理防火墙规则,请安装 UFW: sudo apt install ufw" - fi - - return 0 -} - -# 关闭防火墙端口 - 仅处理 UFW -close_firewall_port() { - local port=$1 - log_info "关闭防火墙端口" - - # 检查是否安装了 ufw - if command -v ufw &>/dev/null; then - # 检查ufw是否启用 - local ufw_status=$(ufw status | grep -o "Status: active" 2>/dev/null) - - if [[ -z "$ufw_status" ]]; then - log_warn "UFW 防火墙未启用,跳过防火墙配置" - return 0 - fi - - # 检查端口是否已开放在UFW中 - if ! ufw status | grep -q "$port/tcp"; then - log_info "端口 $port 未在 UFW 中开放,跳过" - return 0 - fi - - # 关闭端口 - echo -n "关闭 UFW 防火墙端口 $port... " - if ufw delete allow "$port/tcp" &>/dev/null; then - echo -e "${GREEN}完成${NC}" - log_info "已关闭 UFW 防火墙端口: $port" - else - echo -e "${RED}失败${NC}" - log_warn "无法关闭端口 $port" - fi - else - log_warn "未检测到 UFW 防火墙,跳过防火墙配置" - fi - - return 0 -} - -# 安装 ddns-go -install_ddns_go() { - clear - echo "==================================================" - echo -e "${GREEN}开始安装 ddns-go${NC}" - echo "==================================================" - - log_info "开始安装 ddns-go..." - - # 询问用户是否自定义端口 - local web_port="9876" # 默认端口 - read -rp "是否自定义web访问端口? [y/N] " custom_port - if [[ "$custom_port" =~ ^[yY]$ ]]; then - while true; do - read -rp "请输入端口号 (1-65535): " web_port - if [[ "$web_port" =~ ^[0-9]+$ ]] && [ "$web_port" -ge 1 ] && [ "$web_port" -le 65535 ]; then - log_info "将使用端口: $web_port" - break - else - log_error "无效的端口号,请输入1-65535之间的数字" - fi - done - else - log_info "将使用默认端口: $web_port" - fi - - # 更新软件包 - log_info "更新软件包..." - apt update -y && apt upgrade -y - - # 安装必要工具 - log_info "安装必要工具..." - apt install -y wget curl sudo vim git - - # 创建安装目录 - mkdir -p $DDNS_PATH - - # 1. 获取版本 - 先获取所有必要变量,不输出日志 - local version="" - if [[ -n "$DDNS_VERSION" ]]; then - version="$DDNS_VERSION" - else - version=$(get_latest_version) - fi - - # 2. 移除版本号前的 'v' - local version_num=${version#v} - - # 3. 检测系统架构 - 使用改进后的函数,直接返回结果 - local arch_suffix=$(detect_arch) - - # 4. 构建下载URL - 使用纯文本变量 - local download_file="ddns-go_${version_num}_${arch_suffix}.tar.gz" - local download_path="${DDNS_PATH}/${download_file}" - local download_url="https://github.com/jeessy2/ddns-go/releases/download/${version}/${download_file}" - - # 5. 现在安全地输出日志 - log_info "获取到最新版本:$version" - log_info "检测到系统架构: $(uname -m) (使用: $arch_suffix)" - log_info "下载链接: $download_url" - - # 6. 下载文件 - 统一使用curl下载 - log_info "正在下载 ddns-go..." - - if curl -s -L -o "$download_path" "$download_url"; then - log_info "下载成功" - else - log_error "下载失败,请检查网络连接" - read -rp "按回车键返回主菜单..." temp - show_menu - return 1 - fi - - # 7. 解压文件 - log_info "正在解压文件..." - if tar -zxf "$download_path" -C $DDNS_PATH; then - log_info "解压成功" - else - log_error "解压失败" - read -rp "按回车键返回主菜单..." temp - show_menu - return 1 - fi - - # 8. 设置权限 - chmod +x $DDNS_PATH/ddns-go - - # 9. 验证可执行文件 - log_info "验证 ddns-go 二进制文件..." - if [ ! -f $DDNS_PATH/ddns-go ]; then - log_error "未找到 ddns-go 可执行文件" - read -rp "按回车键返回主菜单..." temp - show_menu - return 1 - fi - - # 10. 测试运行 - if ! $DDNS_PATH/ddns-go -h > /dev/null 2>&1; then - log_error "ddns-go 可执行文件无法运行,可能是架构不匹配" - log_info "尝试检查更多架构版本..." - - # 清理之前的文件 - rm -rf $DDNS_PATH/* - - # 尝试其他架构版本 - local try_arch_list=("linux_arm64" "linux_armv7" "linux_x86" "linux_x86_64") - local success=false - - for try_arch in "${try_arch_list[@]}"; do - if [ "$try_arch" != "$arch_suffix" ]; then - log_info "尝试 $try_arch 架构版本..." - - # 构建下载信息 - local try_file="ddns-go_${version_num}_${try_arch}.tar.gz" - local try_path="${DDNS_PATH}/${try_file}" - local try_url="https://github.com/jeessy2/ddns-go/releases/download/${version}/${try_file}" - - # 下载并解压 - 统一使用curl - if curl -s -L -o "$try_path" "$try_url" && - tar -zxf "$try_path" -C $DDNS_PATH && - chmod +x $DDNS_PATH/ddns-go; then - - # 测试是否可运行 - if $DDNS_PATH/ddns-go -h > /dev/null 2>&1; then - log_info "$try_arch 架构版本可以运行" - success=true - break - else - log_warn "$try_arch 架构版本不兼容" - fi - else - log_warn "$try_arch 架构版本下载或解压失败" - fi - fi - done - - # 如果所有架构都尝试失败 - if [ "$success" = false ]; then - log_error "无法找到合适的版本,安装失败" - read -rp "按回车键返回主菜单..." temp - show_menu - return 1 - fi - fi - - # 11. 安装服务 - log_info "安装系统服务..." - cd $DDNS_PATH - ./ddns-go -s install -l 0.0.0.0:$web_port - - # 12. 验证服务 - if systemctl status ddns-go > /dev/null 2>&1; then - log_info "ddns-go 服务已成功安装并运行" - else - log_warn "ddns-go 服务可能未正确启动,请手动检查: systemctl status ddns-go" - fi - - # 13. 获取IP信息 - local ip_info=$(get_ip_info) - local ipv4=$(echo "$ip_info" | cut -d'|' -f1) - - # 14. 配置防火墙 - configure_firewall $web_port - - log_info "ddns-go 安装完成!" - echo "==================================================" - echo -e "${GREEN}安装成功!${NC}" - echo -e "${CYAN}Web管理界面访问地址: http://$ipv4:$web_port${NC}" - echo -e "请在浏览器中打开上述地址进行配置" - echo "==================================================" - - # 清理下载文件 - rm -f "$download_path" - - read -rp "按回车键返回主菜单..." temp - show_menu -} - -# 卸载服务 -uninstall_ddns_go() { - clear - echo "==================================================" - echo -e "${RED}开始卸载 ddns-go${NC}" - echo "==================================================" - - # 确认卸载 - echo -e "${YELLOW}警告: 这将卸载 ddns-go 并删除相关文件${NC}" - read -rp "是否继续? [Y/n] " confirm - if [[ "$confirm" =~ ^[nN]$ ]]; then - log_info "卸载已取消" - read -rp "按回车键返回主菜单..." temp - show_menu - return 0 - fi - - log_info "正在卸载 ddns-go 服务..." - - # 获取端口信息用于关闭防火墙 - local port="" - if [ -d "$DDNS_PATH" ] && [ -f "$DDNS_PATH/config.yaml" ]; then - port=$(grep -o 'listen: 0.0.0.0:[0-9]*' "$DDNS_PATH/config.yaml" 2>/dev/null | grep -o '[0-9]*$' | head -n 1) - fi - - if [[ -z "$port" ]]; then - port=$(systemctl status ddns-go 2>/dev/null | grep -o '\-l 0.0.0.0:[0-9]*' | grep -o '[0-9]*$' | head -n 1) - fi - - if [ -d "$DDNS_PATH" ]; then - cd $DDNS_PATH - if [ -f "./ddns-go" ]; then - ./ddns-go -s uninstall - log_info "服务已卸载" - else - log_error "找不到 ddns-go 可执行文件" - fi - - # 询问是否删除文件 - read -rp "是否删除所有 ddns-go 文件? [Y/n] " delete_confirm - if [[ ! "$delete_confirm" =~ ^[nN]$ ]]; then - rm -rf $DDNS_PATH - log_info "所有文件已删除" - else - log_info "文件已保留" - fi - else - log_error "找不到 ddns-go 安装目录" - fi - - # 关闭防火墙端口 - if [[ -n "$port" ]]; then - close_firewall_port $port - fi - - log_info "ddns-go 卸载完成!" - read -rp "按回车键返回主菜单..." temp - show_menu -} - -# 更新 ddns-go -update_ddns_go() { - clear - echo "==================================================" - echo -e "${YELLOW}更新 ddns-go${NC}" - echo "==================================================" - - # 检查是否已安装 - if [ ! -d "$DDNS_PATH" ] || [ ! -f "$DDNS_PATH/ddns-go" ]; then - log_error "ddns-go 未安装,请先安装" - read -rp "按回车键返回主菜单..." temp - show_menu - return 0 - fi - - # 获取当前版本 - local current_version="" - current_version=$($DDNS_PATH/ddns-go -v 2>&1 | grep -o 'v[0-9.]*' | head -n 1) - - if [[ -z "$current_version" ]]; then - log_warn "无法获取当前版本信息" - current_version="未知" - fi - - log_info "当前版本: $current_version" - - # 获取最新版本 - local latest_version=$(get_latest_version) - log_info "最新版本: $latest_version" - - # 比较版本 - if [[ "$current_version" == "$latest_version" ]]; then - log_info "已经是最新版本" - read -rp "是否强制更新? [y/N] " force_update - if [[ ! "$force_update" =~ ^[yY]$ ]]; then - log_info "更新已取消" - read -rp "按回车键返回主菜单..." temp - show_menu - return 0 - fi - fi - - # 备份配置 - local config_backup="$DDNS_PATH/config.yaml.bak" - if [ -f "$DDNS_PATH/config.yaml" ]; then - log_info "备份配置文件..." - cp "$DDNS_PATH/config.yaml" "$config_backup" - fi - - # 停止服务 - log_info "停止 ddns-go 服务..." - cd $DDNS_PATH - ./ddns-go -s uninstall - - # 下载新版本 - log_info "下载新版本..." - - # 检测系统架构 - 使用改进后的函数,直接返回结果 - local arch_suffix=$(detect_arch) - local version_num=${latest_version#v} - - # 构建下载URL - local download_file="ddns-go_${version_num}_${arch_suffix}.tar.gz" - local download_path="${DDNS_PATH}/${download_file}" - local download_url="https://github.com/jeessy2/ddns-go/releases/download/${latest_version}/${download_file}" - - log_info "下载链接: $download_url" - - # 删除原来的二进制文件 - rm -f $DDNS_PATH/ddns-go - - # 下载文件 - 统一使用curl下载 - if curl -s -L -o "$download_path" "$download_url"; then - log_info "下载成功" - else - log_error "下载失败,请检查网络连接" - log_warn "将恢复服务" - if [ -f "$config_backup" ]; then - cp "$config_backup" "$DDNS_PATH/config.yaml" - fi - cd $DDNS_PATH - ./ddns-go -s install -l 0.0.0.0:9876 - read -rp "按回车键返回主菜单..." temp - show_menu - return 1 - fi - - # 解压文件 - log_info "解压新版本..." - if tar -zxf "$download_path" -C $DDNS_PATH; then - log_info "解压成功" - else - log_error "解压失败" - log_warn "将恢复服务" - if [ -f "$config_backup" ]; then - cp "$config_backup" "$DDNS_PATH/config.yaml" - fi - cd $DDNS_PATH - ./ddns-go -s install -l 0.0.0.0:9876 - read -rp "按回车键返回主菜单..." temp - show_menu - return 1 - fi - - # 设置权限 - chmod +x $DDNS_PATH/ddns-go - - # 恢复配置 - if [ -f "$config_backup" ]; then - log_info "恢复配置文件..." - cp "$config_backup" "$DDNS_PATH/config.yaml" - fi - - # 获取当前配置的端口 - local port="9876" - if [ -f "$DDNS_PATH/config.yaml" ]; then - local config_port=$(grep -o 'listen: 0.0.0.0:[0-9]*' "$DDNS_PATH/config.yaml" 2>/dev/null | grep -o '[0-9]*$' | head -n 1) - if [[ -n "$config_port" ]]; then - port="$config_port" - fi - fi - - # 安装服务 - log_info "重新安装服务..." - cd $DDNS_PATH - ./ddns-go -s install -l 0.0.0.0:$port - - # 验证更新 - local new_version=$($DDNS_PATH/ddns-go -v 2>&1 | grep -o 'v[0-9.]*' | head -n 1) - if [[ -z "$new_version" ]]; then - new_version="未知" - fi - log_info "更新完成,当前版本: $new_version" - - # 清理下载文件 - rm -f "$download_path" - - read -rp "按回车键返回主菜单..." temp - show_menu -} - -# 查看状态 -check_status() { - clear - echo "==================================================" - echo -e "${BLUE}ddns-go 状态检查${NC}" - echo "==================================================" - - # 检查是否安装 - if [ ! -d "$DDNS_PATH" ] || [ ! -f "$DDNS_PATH/ddns-go" ]; then - echo -e "${RED}ddns-go 未安装${NC}" - read -rp "按回车键返回主菜单..." temp - show_menu - return 0 - fi - - # 检查版本 - local version=$($DDNS_PATH/ddns-go -v 2>&1 | grep -o 'v[0-9.]*' | head -n 1) - if [[ -z "$version" ]]; then - version="未知" - fi - echo -e "ddns-go 版本: ${GREEN}$version${NC}" - - # 检查服务状态 - echo -n "服务状态: " - if systemctl is-active ddns-go &>/dev/null; then - echo -e "${GREEN}运行中${NC}" - else - echo -e "${RED}未运行${NC}" - fi - - echo -n "自启动状态: " - if systemctl is-enabled ddns-go &>/dev/null; then - echo -e "${GREEN}已启用${NC}" - else - echo -e "${RED}未启用${NC}" - fi - - # 检查配置文件 - echo -n "配置文件: " - if [ -f "$DDNS_PATH/config.yaml" ]; then - echo -e "${GREEN}存在${NC}" - else - echo -e "${RED}不存在${NC}" - fi - - # 获取内存和 CPU 使用情况 - echo "资源使用情况:" - ps -aux | grep ddns-go | grep -v grep | awk '{print "内存使用: " $4 "%, CPU使用: " $3 "%"}' - - # 获取端口信息 - echo -n "端口状态: " - local port=$(grep -o 'listen: 0.0.0.0:[0-9]*' "$DDNS_PATH/config.yaml" 2>/dev/null | grep -o '[0-9]*$' | head -n 1) - if [[ -z "$port" ]]; then - port=$(systemctl status ddns-go 2>/dev/null | grep -o '\-l 0.0.0.0:[0-9]*' | grep -o '[0-9]*$' | head -n 1) - fi - - if [[ -n "$port" ]]; then - if command -v ss &>/dev/null; then - if ss -tuln | grep -q ":$port "; then - echo -e "${GREEN}端口 $port 已开放${NC}" - else - echo -e "${RED}端口 $port 未开放${NC}" - fi - elif command -v netstat &>/dev/null; then - if netstat -tuln | grep -q ":$port "; then - echo -e "${GREEN}端口 $port 已开放${NC}" - else - echo -e "${RED}端口 $port 未开放${NC}" - fi - else - echo -e "${YELLOW}无法检查端口状态${NC}" - fi - else - echo -e "${YELLOW}未找到端口信息${NC}" - fi - - # 检查DNS解析记录 - echo -e "\n上次DNS更新信息:" - if [ -f "$DDNS_PATH/config.yaml" ]; then - grep -A 10 'ipv4' "$DDNS_PATH/config.yaml" | head -n 10 - else - echo "未找到配置文件,无法获取DNS更新信息" - fi - - # 显示日志 - echo -e "\n最近日志:" - if command -v journalctl &>/dev/null; then - journalctl -u ddns-go --no-pager -n 10 - else - echo "找不到日志信息" - fi - - read -rp "按回车键返回主菜单..." temp - show_menu -} - -# 重启服务 -restart_service() { - clear - echo "==================================================" - echo -e "${GREEN}重启 ddns-go 服务${NC}" - echo "==================================================" - - # 检查是否已安装 - if [ ! -d "$DDNS_PATH" ] || [ ! -f "$DDNS_PATH/ddns-go" ]; then - log_error "ddns-go 未安装,请先安装" - read -rp "按回车键返回主菜单..." temp - show_menu - return 0 - fi - - log_info "正在重启 ddns-go 服务..." - - # 尝试使用systemctl重启 - if systemctl restart ddns-go; then - log_info "服务已重启" - else - log_warn "systemctl重启失败,尝试手动重启..." - cd $DDNS_PATH - ./ddns-go -s uninstall - sleep 1 - - # 获取当前配置的端口 - local web_port="9876" - if [ -f "$DDNS_PATH/config.yaml" ]; then - local config_port=$(grep -o 'listen: 0.0.0.0:[0-9]*' "$DDNS_PATH/config.yaml" 2>/dev/null | grep -o '[0-9]*$' | head -n 1) - if [[ -n "$config_port" ]]; then - web_port="$config_port" - fi - fi - - ./ddns-go -s install -l 0.0.0.0:$web_port - log_info "服务已手动重启" - fi - - # 获取IP信息 - local ip_info=$(get_ip_info) - local ipv4=$(echo "$ip_info" | cut -d'|' -f1) - - log_info "服务已重启,Web管理界面: http://$ipv4:$web_port" - - read -rp "按回车键返回主菜单..." temp - show_menu -} - -# 显示帮助 -show_help() { - echo "ddns-go 管理脚本 v${SCRIPT_VERSION}" - echo "用法: $0 [选项]" - echo "" - echo "选项:" - echo " install 直接安装 ddns-go" - echo " uninstall 直接卸载 ddns-go" - echo " restart 重启 ddns-go 服务" - echo " status 查看 ddns-go 状态" - echo " update 更新 ddns-go" - echo " ip 显示当前公网IP地址" - echo " help 显示此帮助信息" - echo "" - echo "无参数运行脚本将显示交互式菜单" -} - -# 菜单函数 -show_menu() { - clear - echo "==================================================" - echo -e "${CYAN}ddns-go 管理脚本 v${SCRIPT_VERSION}${NC}" - echo "==================================================" - echo -e "1) ${GREEN}安装 ddns-go${NC}" - echo -e "2) ${RED}卸载 ddns-go${NC}" - echo -e "3) ${YELLOW}更新 ddns-go${NC}" - echo -e "4) ${BLUE}查看 ddns-go 状态${NC}" - echo -e "5) ${GREEN}重启 ddns-go 服务${NC}" - echo -e "0) ${RED}退出${NC}" - echo "==================================================" - echo "" - read -rp "请输入选项 [0-5]: " choice - - case $choice in - 1) install_ddns_go ;; - 2) uninstall_ddns_go ;; - 3) update_ddns_go ;; - 4) check_status ;; - 5) restart_service ;; - 0) exit 0 ;; - *) log_error "无效选项" && sleep 2 && show_menu ;; - esac -} - -# 主函数 -main() { - # 处理命令行参数 - if [[ $# -gt 0 ]]; then - case "$1" in - -h|--help|help) - show_help - exit 0 - ;; - install) - install_ddns_go - exit 0 - ;; - uninstall) - uninstall_ddns_go - exit 0 - ;; - restart) - restart_service - exit 0 - ;; - status) - check_status - exit 0 - ;; - update) - update_ddns_go - exit 0 - ;; - *) - log_error "未知参数: $1" - show_help - exit 1 - ;; - esac - fi - - # 无参数则显示菜单 - show_menu -} - -# 执行主函数 -main "$@" diff --git a/init/vps_init.sh b/init/vps_init.sh deleted file mode 100644 index 5ef178d..0000000 --- a/init/vps_init.sh +++ /dev/null @@ -1,675 +0,0 @@ -#!/bin/bash -# -# VPS初始化一键脚本 -# 整合了系统更新、登录安全设置、系统清理、Docker安装、防火墙设置、时区设置、 -# 内存优化、Fail2ban安装和BBR加速 -# 使用方法: chmod +x vps_init.sh && ./vps_init.sh -# curl -sS -O https://gitea.tohub.top/Share/vps/raw/branch/main/init/vps_init.sh && chmod +x vps_init.sh && ./vps_init.sh - -# =========================================== -# 用户设置区域 - 根据需要修改 -# =========================================== -NEW_PASSWORD="d!Fssw97SoALHa" # root用户新密码 -NEW_SSH_PORT="4399" # SSH新端口号 -TIMEZONE="Asia/Shanghai" # 时区设置 -SWAP_SIZE=1024 # 交换分区大小(MB) -# =========================================== - -# 颜色定义 -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[0;33m' -BLUE='\033[0;34m' -NC='\033[0m' # 恢复默认颜色 - -# 确保脚本以root权限运行 -if [ "$(id -u)" -ne 0 ]; then - echo -e "${RED}错误: 必须以root用户运行此脚本!${NC}" - exit 1 -fi - -# 显示欢迎信息 -echo -e "${GREEN}=============================================${NC}" -echo -e "${BLUE} VPS初始化一键脚本开始执行 ${NC}" -echo -e "${GREEN}=============================================${NC}" -echo "" - -# =========================================== -# 交互式设置选项 -# =========================================== -echo -e "${BLUE}进行交互式设置...${NC}" - -# 询问是否修改SSH端口 -echo -e "${YELLOW}1. 是否修改SSH端口? 当前设置为: ${NEW_SSH_PORT}${NC}" -while true; do - read -p "修改SSH端口? (y/n, 默认n): " CHANGE_SSH_PORT - # 设置默认值为否,用户按Enter就不修改 - CHANGE_SSH_PORT=${CHANGE_SSH_PORT:-n} - if [[ "$CHANGE_SSH_PORT" =~ ^[Yy]$ ]] || [[ "$CHANGE_SSH_PORT" =~ ^[Nn]$ ]]; then - break - else - echo -e "${RED}无效的输入,请输入 y 或 n${NC}" - fi -done - -if [[ "$CHANGE_SSH_PORT" =~ ^[Yy]$ ]]; then - echo -e "${GREEN}SSH端口将被修改为: ${NEW_SSH_PORT}${NC}" -else - echo -e "${GREEN}保持SSH端口不变: $NEW_SSH_PORT${NC}" -fi - -# 询问是否修改密码 -echo -e "${YELLOW}2. 是否修改root密码?${NC}" -while true; do - read -p "修改root密码? (y/n, 默认n): " CHANGE_PASSWORD - # 设置默认值为否,用户按Enter就不修改 - CHANGE_PASSWORD=${CHANGE_PASSWORD:-n} - if [[ "$CHANGE_PASSWORD" =~ ^[Yy]$ ]] || [[ "$CHANGE_PASSWORD" =~ ^[Nn]$ ]]; then - break - else - echo -e "${RED}无效的输入,请输入 y 或 n${NC}" - fi -done - -if [[ "$CHANGE_PASSWORD" =~ ^[Yy]$ ]]; then - echo -e "${GREEN}root密码将被修改为系统预设值${NC}" -else - echo -e "${GREEN}保持root密码不变${NC}" -fi - -# 询问是否修改主机名 -echo -e "${YELLOW}3. 是否修改主机名?${NC}" -while true; do - read -p "修改主机名? (y/n, 默认n): " CHANGE_HOSTNAME - # 设置默认值为否,用户按Enter就不修改 - CHANGE_HOSTNAME=${CHANGE_HOSTNAME:-n} - if [[ "$CHANGE_HOSTNAME" =~ ^[Yy]$ ]] || [[ "$CHANGE_HOSTNAME" =~ ^[Nn]$ ]]; then - break - else - echo -e "${RED}无效的输入,请输入 y 或 n${NC}" - fi -done - -if [[ "$CHANGE_HOSTNAME" =~ ^[Yy]$ ]]; then - # 显示当前主机名 - CURRENT_HOSTNAME=$(hostname) - echo -e "${YELLOW}当前主机名: ${CURRENT_HOSTNAME}${NC}" - - # 让用户输入新主机名 - read -p "请输入新的主机名: " NEW_HOSTNAME - if [ -n "$NEW_HOSTNAME" ]; then - CHANGE_HOSTNAME_FLAG=true - echo -e "${GREEN}主机名将被修改为: ${NEW_HOSTNAME}${NC}" - else - CHANGE_HOSTNAME_FLAG=false - echo -e "${RED}主机名不能为空,将保持不变${NC}" - fi -else - CHANGE_HOSTNAME_FLAG=false - echo -e "${GREEN}保持主机名不变${NC}" -fi - -echo -e "${BLUE}交互式设置完成${NC}" -echo "" - -# 记录开始时间 -START_TIME=$(date +%s) - -# 检查系统类型 -if [ -f /etc/debian_version ]; then - OS_TYPE="debian" - echo -e "${GREEN}检测到Debian/Ubuntu系统${NC}" -else - echo -e "${YELLOW}警告: 此脚本主要为Debian/Ubuntu系统设计${NC}" - echo -e "${YELLOW}部分功能可能在其他系统上不正常工作${NC}" - OS_TYPE="other" -fi - -# 创建日志文件 -LOG_FILE="/var/log/vps_init_$(date +%Y%m%d_%H%M%S).log" -touch $LOG_FILE -echo "VPS初始化脚本开始执行: $(date)" > $LOG_FILE - -# 定义日志函数 -log() { - echo -e "$1" | tee -a $LOG_FILE -} - -# 定义错误处理函数 -handle_error() { - local exit_code=$? - local line_no=$1 - if [ $exit_code -ne 0 ]; then - log "${RED}错误: 在第 $line_no 行发生错误,退出代码: $exit_code${NC}" - log "${RED}请检查日志文件: $LOG_FILE${NC}" - fi -} - -# 设置错误跟踪 -trap 'handle_error $LINENO' ERR - -# =========================================== -# 1. 系统更新 -# =========================================== -log "${BLUE}[1/10] 系统更新开始...${NC}" - -# 保存当前的sources.list作为备份 -if [ -f "/etc/apt/sources.list" ]; then - cp /etc/apt/sources.list /etc/apt/sources.list.bak - log "${GREEN}备份了软件源配置文件${NC}" -fi - -# 更新系统包 -if [ "$OS_TYPE" = "debian" ]; then - apt update -y || log "${RED}更新软件源失败${NC}" - DEBIAN_FRONTEND=noninteractive apt full-upgrade -y || log "${RED}系统升级失败${NC}" - apt install -y wget curl sudo vim git ufw net-tools htop iftop || log "${RED}安装基础软件包失败${NC}" - log "${GREEN}系统更新完成,安装了常用工具${NC}" -else - log "${YELLOW}非Debian系统,跳过标准更新流程${NC}" -fi - -# =========================================== -# 2. 主机名设置(如果用户选择了修改) -# =========================================== -if [ "$CHANGE_HOSTNAME_FLAG" = true ]; then - log "${BLUE}[2/10] 设置主机名...${NC}" - - # 备份当前主机名配置 - cp /etc/hostname /etc/hostname.bak - cp /etc/hosts /etc/hosts.bak - - # 修改主机名 - echo "$NEW_HOSTNAME" > /etc/hostname - hostname "$NEW_HOSTNAME" - - # 更新hosts文件 - sed -i "s/127.0.1.1.*/127.0.1.1\t$NEW_HOSTNAME/g" /etc/hosts - - # 检查是否修改成功 - CURRENT_HOSTNAME=$(hostname) - if [ "$CURRENT_HOSTNAME" = "$NEW_HOSTNAME" ]; then - log "${GREEN}主机名已成功修改为: $NEW_HOSTNAME${NC}" - else - log "${RED}主机名修改失败,当前名称: $CURRENT_HOSTNAME${NC}" - fi - - log "${GREEN}主机名设置完成${NC}" -else - log "${YELLOW}[2/10] 跳过主机名设置...${NC}" -fi - -# =========================================== -# 3. 登录安全设置 -# =========================================== -log "${BLUE}[3/10] 设置登录安全...${NC}" - -# 根据用户选择修改root密码 -if [[ "$CHANGE_PASSWORD" =~ ^[Yy]$ ]]; then - echo "root:$NEW_PASSWORD" | chpasswd - if [ $? -eq 0 ]; then - log "${GREEN}Root密码修改成功${NC}" - else - log "${RED}Root密码修改失败${NC}" - fi -else - log "${YELLOW}根据用户选择,保持root密码不变${NC}" -fi - -# 根据用户选择修改SSH端口 -if [[ "$CHANGE_SSH_PORT" =~ ^[Yy]$ ]]; then - # 备份SSH配置文件 - cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak - log "${GREEN}SSH配置已备份${NC}" - - # 修改SSH配置 - sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_config - sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication yes/g' /etc/ssh/sshd_config - sed -i 's/#Port/Port/' /etc/ssh/sshd_config - sed -i "s/Port [0-9]\+/Port $NEW_SSH_PORT/g" /etc/ssh/sshd_config - - # 读取修改后的SSH端口以确认更改 - NEW_PORT_CONFIGURED=$(grep -P "^Port\s+\d+" /etc/ssh/sshd_config | awk '{print $2}') - if [ "$NEW_PORT_CONFIGURED" = "$NEW_SSH_PORT" ]; then - log "${GREEN}SSH端口已修改为: $NEW_SSH_PORT${NC}" - else - log "${RED}SSH端口修改失败,当前设置: $NEW_PORT_CONFIGURED${NC}" - # 尝试使用另一种方法修改 - echo "Port $NEW_SSH_PORT" >> /etc/ssh/sshd_config - log "${YELLOW}尝试使用备选方法添加端口设置${NC}" - fi - - # 重启SSH服务 - systemctl restart sshd - if [ $? -eq 0 ]; then - log "${GREEN}SSH服务重启成功${NC}" - else - log "${RED}SSH服务重启失败${NC}" - # 尝试使用service命令 - service sshd restart || service ssh restart - fi - - # 检查SSH服务状态 - systemctl status sshd --no-pager || service sshd status || service ssh status - log "${GREEN}SSH配置更改完成${NC}" - log "${YELLOW}注意:新的SSH连接端口为 $NEW_SSH_PORT${NC}" -else - log "${YELLOW}根据用户选择,保持SSH端口不变${NC}" - - # 即使不修改端口,仍然应该确保其他SSH安全设置 - sed -i 's/^#\?PermitRootLogin.*/PermitRootLogin yes/g' /etc/ssh/sshd_config - sed -i 's/^#\?PasswordAuthentication.*/PasswordAuthentication yes/g' /etc/ssh/sshd_config - - log "${GREEN}SSH基本安全设置完成${NC}" -fi - -# =========================================== -# 4. 系统清理 -# =========================================== -log "${BLUE}[4/10] 系统清理开始...${NC}" - -# 清理不需要的软件包 -if [ "$OS_TYPE" = "debian" ]; then - apt autoremove --purge -y - apt clean -y - apt autoclean -y - apt remove --purge $(dpkg -l | awk '/^rc/ {print $2}') -y 2>/dev/null || log "${YELLOW}没有需要清理的软件包配置${NC}" - - # 清理日志 - journalctl --rotate - journalctl --vacuum-time=1d - journalctl --vacuum-size=50M - log "${GREEN}系统日志已清理${NC}" - - # 清理旧内核(保留当前运行的内核) - apt remove --purge $(dpkg -l | awk '/^ii linux-(image|headers)-[^ ]+/{print $2}' | grep -v $(uname -r | sed 's/-.*//') | xargs) -y 2>/dev/null || log "${YELLOW}没有可清理的旧内核${NC}" - - log "${GREEN}系统清理完成${NC}" -else - log "${YELLOW}非Debian系统,跳过系统清理流程${NC}" -fi - -# =========================================== -# 5. Docker安装 -# =========================================== -log "${BLUE}[5/10] Docker安装开始...${NC}" - -# 检查Docker是否已安装 -if command -v docker &> /dev/null; then - log "${GREEN}Docker已经安装,版本信息:${NC}" - docker --version -else - # 安装Docker - if [ "$OS_TYPE" = "debian" ]; then - # 使用官方安装脚本 - curl -fsSL https://get.docker.com -o get-docker.sh - sh get-docker.sh - rm get-docker.sh - systemctl enable docker - - # 安装Docker Compose - if ! command -v docker-compose &> /dev/null; then - curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose - chmod +x /usr/local/bin/docker-compose - log "${GREEN}Docker Compose 安装完成${NC}" - fi - - log "${GREEN}Docker安装完成,版本信息:${NC}" - docker --version - docker-compose --version - else - log "${YELLOW}非Debian系统,请手动安装Docker${NC}" - fi -fi - -# =========================================== -# 6. 防火墙设置 -# =========================================== -log "${BLUE}[6/10] 防火墙设置开始...${NC}" - -# 安装UFW -if [ "$OS_TYPE" = "debian" ]; then - apt update -y && apt install -y ufw net-tools lsof - - # 确保防火墙默认策略 - ufw default deny incoming - ufw default allow outgoing - - # 获取当前SSH端口(如果有多个SSH端口,获取所有) - CURRENT_SSH_PORT=$(grep -P "^Port\s+\d+" /etc/ssh/sshd_config | awk '{print $2}') - if [ -z "$CURRENT_SSH_PORT" ]; then - # 如果没找到,使用默认端口22 - CURRENT_SSH_PORT="22" - fi - - # 总是添加新配置的SSH端口(防止被锁在系统之外) - log "${GREEN}允许SSH端口 $NEW_SSH_PORT${NC}" - ufw allow $NEW_SSH_PORT/tcp comment 'New SSH Port' - - # 如果当前SSH端口与新端口不同,添加当前SSH端口作为备份 - if [ "$CURRENT_SSH_PORT" != "$NEW_SSH_PORT" ]; then - log "${GREEN}允许当前SSH端口 $CURRENT_SSH_PORT (备份)${NC}" - ufw allow $CURRENT_SSH_PORT/tcp comment 'Current SSH Port (Backup)' - fi - - # 添加基本Web服务端口 - log "${GREEN}允许HTTP/HTTPS端口${NC}" - ufw allow 80/tcp comment 'HTTP' - ufw allow 443/tcp comment 'HTTPS' - - # 检测活跃的网络连接和正在监听的端口 - log "${YELLOW}检测当前活跃的服务端口...${NC}" - - # 使用netstat查找监听的TCP端口 - LISTENING_PORTS=$(netstat -tlnp 2>/dev/null | grep "LISTEN" | awk '{print $4}' | awk -F: '{print $NF}' | sort -n | uniq) - - # 使用lsof作为备选方法 - if [ -z "$LISTENING_PORTS" ]; then - LISTENING_PORTS=$(lsof -i -P -n | grep LISTEN | awk '{print $9}' | awk -F: '{print $NF}' | sort -n | uniq) - fi - - # 如果仍然为空,提示手动检查 - if [ -z "$LISTENING_PORTS" ]; then - log "${YELLOW}未检测到活跃端口,只开放SSH、HTTP和HTTPS端口${NC}" - else - log "${GREEN}检测到以下活跃端口:${NC}" - for PORT in $LISTENING_PORTS; do - # 跳过SSH端口(已经添加过),以及常见的本地服务端口 - if [[ "$PORT" != "$NEW_SSH_PORT" && "$PORT" != "$CURRENT_SSH_PORT" && - "$PORT" != "80" && "$PORT" != "443" && - "$PORT" -lt "65535" && "$PORT" -gt "1024" ]]; then - - # 尝试找出服务名称 - SERVICE=$(lsof -i:$PORT -sTCP:LISTEN | grep -v "COMMAND" | awk '{print $1}' | head -1) - if [ -z "$SERVICE" ]; then - SERVICE=$(netstat -tlnp 2>/dev/null | grep ":$PORT" | awk '{print $7}' | cut -d"/" -f2 | head -1) - fi - - if [ -n "$SERVICE" ]; then - COMMENT="Service: $SERVICE" - else - COMMENT="Unknown Service" - fi - - log "${GREEN}允许端口 $PORT/tcp ($COMMENT)${NC}" - ufw allow $PORT/tcp comment "$COMMENT" - fi - done - fi - - # 删除询问用户是否手动开放端口的部分 - log "${GREEN}已自动开放SSH、HTTP、HTTPS端口和检测到的活跃服务端口${NC}" - - # 启用防火墙 - if ! ufw status | grep -q "Status: active"; then - log "${YELLOW}启用UFW防火墙...${NC}" - echo "y" | ufw enable || log "${RED}UFW启用失败${NC}" - else - log "${GREEN}UFW防火墙已启用${NC}" - fi - - # 显示防火墙状态 - ufw status numbered | tee -a $LOG_FILE - log "${GREEN}防火墙设置完成,已使用最小化原则开放端口${NC}" -else - log "${YELLOW}非Debian系统,请手动配置防火墙${NC}" -fi - -# =========================================== -# 7. 时区设置 -# =========================================== -log "${BLUE}[7/10] 时区设置开始...${NC}" - -# 设置时区 -timedatectl set-timezone $TIMEZONE -if [ $? -eq 0 ]; then - CURRENT_TZ=$(timedatectl show --property=Timezone --value) - log "${GREEN}时区设置为: $CURRENT_TZ${NC}" -else - log "${RED}时区设置失败${NC}" -fi - -# =========================================== -# 8. 内存优化 - 添加交换空间 -# =========================================== -log "${BLUE}[8/10] 内存优化开始...${NC}" - -# 获取当前所有交换空间信息 -CURRENT_SWAP_TOTAL=$(free -m | grep "Swap:" | awk '{print $2}') -log "${YELLOW}当前系统交换空间总大小: ${CURRENT_SWAP_TOTAL}MB${NC}" - -# 检查是否存在交换空间且大小与设定值相同 -if [ "$CURRENT_SWAP_TOTAL" -eq "$SWAP_SIZE" ]; then - log "${GREEN}当前交换空间大小(${CURRENT_SWAP_TOTAL}MB)与设定值一致,无需修改${NC}" - # 显示交换空间信息 - free -h | tee -a $LOG_FILE -else - # 如果不存在交换空间或大小不同,则进行处理 - if [ "$CURRENT_SWAP_TOTAL" -gt "0" ]; then - log "${YELLOW}系统已有交换空间但大小不符(${CURRENT_SWAP_TOTAL}MB),准备清理现有交换空间...${NC}" - - # 获取所有交换设备 - SWAP_DEVICES=$(swapon --show=NAME --noheadings) - - # 清理所有活跃的交换空间 - for DEVICE in $SWAP_DEVICES; do - log "${YELLOW}关闭交换空间: $DEVICE${NC}" - swapoff "$DEVICE" - done - - # 从fstab中移除所有交换空间条目(保留备份) - cp /etc/fstab /etc/fstab.bak - log "${GREEN}备份了/etc/fstab文件${NC}" - sed -i '/swap/d' /etc/fstab - - # 删除交换文件 - if [ -f /swapfile ]; then - log "${YELLOW}删除现有交换文件...${NC}" - rm -f /swapfile - fi - - log "${GREEN}所有现有交换空间已清理${NC}" - else - log "${YELLOW}系统未配置交换空间,准备创建...${NC}" - fi - - # 创建新的交换文件 - log "${GREEN}创建${SWAP_SIZE}MB大小的交换文件...${NC}" - dd if=/dev/zero of=/swapfile bs=1M count=$SWAP_SIZE status=progress - chmod 600 /swapfile - mkswap /swapfile - swapon /swapfile - - # 设置开机自动挂载 - if ! grep -q "/swapfile" /etc/fstab; then - echo "/swapfile swap swap defaults 0 0" >> /etc/fstab - log "${GREEN}已添加到fstab,开机将自动挂载${NC}" - fi - - # 调整swappiness参数(控制系统对交换空间的使用倾向) - echo "vm.swappiness=10" > /etc/sysctl.d/99-swappiness.conf - sysctl -p /etc/sysctl.d/99-swappiness.conf - - # 显示交换空间信息 - log "${GREEN}交换分区配置完成,当前内存和交换空间状态:${NC}" - free -h | tee -a $LOG_FILE -fi - -# =========================================== -# 9. Fail2ban安装和配置 -# =========================================== -log "${BLUE}[9/10] Fail2ban安装开始...${NC}" - -if [ "$OS_TYPE" = "debian" ]; then - # 安装Fail2ban - apt update -y && apt install -y fail2ban - systemctl start fail2ban - systemctl enable fail2ban - - # 配置Fail2ban - cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local - - # 清理任何现有配置 - rm -rf /etc/fail2ban/jail.d/* 2>/dev/null || true - - # 创建SSH防护配置 - cat < /etc/fail2ban/jail.d/sshd.local -[sshd] -enabled = true -mode = normal -port = $NEW_SSH_PORT -logpath = %(sshd_log)s -backend = systemd -maxretry = 5 -bantime = 1h -findtime = 10m -EOF - - # 重启Fail2ban - log "${YELLOW}重启Fail2ban服务...${NC}" - systemctl restart fail2ban - - # 等待服务启动完成 - log "${YELLOW}等待Fail2ban服务完全启动...${NC}" - sleep 5 - - # 检查服务状态 - if systemctl is-active --quiet fail2ban; then - log "${GREEN}Fail2ban服务已成功启动${NC}" - - # 显示Fail2ban状态(使用错误处理避免脚本终止) - log "${YELLOW}获取Fail2ban状态信息...${NC}" - - # 尝试获取fail2ban状态,忽略可能的错误 - fail2ban-client status >/dev/null 2>&1 || log "${YELLOW}无法获取fail2ban综合状态,但这不影响功能${NC}" - - # 尝试获取sshd监狱状态 - if fail2ban-client status sshd >/dev/null 2>&1; then - log "${GREEN}SSH防护已成功配置${NC}" - # 只有在前面成功的情况下才显示详细信息 - fail2ban-client status sshd - else - log "${YELLOW}无法获取SSH监狱状态,这可能是因为服务刚刚启动或配置需要更多时间生效${NC}" - log "${YELLOW}如果在重启后仍有问题,请检查 /var/log/fail2ban.log${NC}" - fi - - # 显示服务状态 - systemctl status fail2ban --no-pager || true - else - log "${RED}Fail2ban服务启动失败,请检查错误日志${NC}" - log "${YELLOW}尝试查看Fail2ban日志获取错误详情:${NC}" - tail -n 20 /var/log/fail2ban.log 2>/dev/null || log "${RED}无法读取Fail2ban日志${NC}" - fi - - log "${GREEN}Fail2ban安装和配置完成${NC}" - log "${YELLOW}如果出现临时错误,服务器重启后通常会正常工作${NC}" -else - log "${YELLOW}非Debian系统,请手动安装Fail2ban${NC}" -fi - -# =========================================== -# 10. BBR加速配置 -# =========================================== -log "${BLUE}[10/10] BBR配置开始...${NC}" - -# 检查BBR是否已启用 -if sysctl net.ipv4.tcp_congestion_control | grep -q "bbr"; then - log "${GREEN}BBR已经启用${NC}" -else - log "${YELLOW}配置BBR...${NC}" - # 添加BBR配置 - echo "net.core.default_qdisc=fq" >> /etc/sysctl.conf - echo "net.ipv4.tcp_congestion_control=bbr" >> /etc/sysctl.conf - - # 应用设置 - sysctl -p - - # 验证设置 - if sysctl net.ipv4.tcp_congestion_control | grep -q "bbr"; then - log "${GREEN}BBR启用成功${NC}" - else - log "${RED}BBR启用失败${NC}" - fi -fi - -# 显示可用的拥塞控制算法 -log "${GREEN}当前系统支持的TCP拥塞控制算法:${NC}" -sysctl net.ipv4.tcp_available_congestion_control - -# 验证模块是否加载 -lsmod | grep bbr - -# =========================================== -# 完成处理 -# =========================================== -END_TIME=$(date +%s) -DURATION=$((END_TIME - START_TIME)) -MINUTES=$((DURATION / 60)) -SECONDS=$((DURATION % 60)) - -log "${GREEN}=======================================================${NC}" -log "${GREEN}VPS初始化完成!用时: ${MINUTES}分${SECONDS}秒${NC}" -log "${GREEN}=======================================================${NC}" -log "${YELLOW}重要提示:${NC}" - -# 根据用户选择显示相应的提示信息 -TIP_COUNT=1 - -# 如果用户选择了修改SSH端口,显示端口信息 -if [[ "$CHANGE_SSH_PORT" =~ ^[Yy]$ ]]; then - log "${YELLOW}$TIP_COUNT. SSH端口已更改为: ${NEW_SSH_PORT}${NC}" - TIP_COUNT=$((TIP_COUNT + 1)) -fi - -# 如果用户选择了修改root密码,显示密码信息 -if [[ "$CHANGE_PASSWORD" =~ ^[Yy]$ ]]; then - log "${YELLOW}$TIP_COUNT. root密码已更改为: ${NEW_PASSWORD}${NC}" - TIP_COUNT=$((TIP_COUNT + 1)) -fi - -# 如果用户选择了修改主机名,显示主机名信息 -if [ "$CHANGE_HOSTNAME_FLAG" = true ]; then - log "${YELLOW}$TIP_COUNT. 主机名已更改为: ${NEW_HOSTNAME}${NC}" - TIP_COUNT=$((TIP_COUNT + 1)) -fi - -# 始终显示防火墙和日志文件信息 -log "${YELLOW}$TIP_COUNT. 防火墙已启用,只开放了必要端口${NC}" -TIP_COUNT=$((TIP_COUNT + 1)) -log "${YELLOW}$TIP_COUNT. 日志文件保存在: ${LOG_FILE}${NC}" - -# 如果已启用BBR,显示BBR信息 -if sysctl net.ipv4.tcp_congestion_control 2>/dev/null | grep -q "bbr"; then - TIP_COUNT=$((TIP_COUNT + 1)) - log "${YELLOW}$TIP_COUNT. BBR加速已成功启用${NC}" -fi - -# 如果配置了交换空间,显示交换空间信息 -if [ "$CURRENT_SWAP_TOTAL" -gt "0" ]; then - TIP_COUNT=$((TIP_COUNT + 1)) - log "${YELLOW}$TIP_COUNT. 交换空间大小: $(free -m | grep "Swap:" | awk '{print $2}')MB${NC}" -fi - -log "${GREEN}=======================================================${NC}" -log "${BLUE}建议您现在重启服务器以应用所有更改${NC}" -log "${GREEN}=======================================================${NC}" - -# 提示用户是否立即重启 -while true; do - read -p "是否立即重启服务器?(y/n, 默认n): " REBOOT_NOW - # 设置默认值为否 - REBOOT_NOW=${REBOOT_NOW:-n} - if [[ "$REBOOT_NOW" =~ ^[Yy]$ ]] || [[ "$REBOOT_NOW" =~ ^[Nn]$ ]]; then - break - else - echo -e "${RED}无效的输入,请输入 y 或 n${NC}" - fi -done - -if [[ "$REBOOT_NOW" =~ ^[Yy]$ ]]; then - log "${GREEN}服务器将在5秒后重启...${NC}" - sleep 5 - reboot -else - log "${YELLOW}请稍后手动重启服务器以应用所有更改${NC}" -fi \ No newline at end of file diff --git a/init/xray-manager.sh b/init/xray-manager.sh deleted file mode 100644 index 95a6ea8..0000000 --- a/init/xray-manager.sh +++ /dev/null @@ -1,1935 +0,0 @@ - -# Xray 管理脚本 - 集成安装、卸载和管理功能 -# 专门支持 VLESS+REALITY 协议 -# 使用方法: chmod +x xray-manager.sh && ./xray-manager.sh -# curl -sS -O https://gitea.tohub.top/Share/vps/raw/branch/main/init/xray-manager.sh && chmod +x xray-manager.sh && ./xray-manager.sh - -# 全局变量 -XRAY_PATH="/usr/local/bin" -CONFIG_PATH="/usr/local/etc/xray" -REALITY_PORT="" # VLESS+REALITY 端口 -LOG_PATH="/var/log/xray" -LOG_FILE="/var/log/xray-manager.log" -SCRIPT_VERSION="1.0.0" -XRAY_VERSION="v25.3.6" # 当前固定的Xray版本 -UUID="" -PRIVATE_KEY="" -PUBLIC_KEY="" -CONFIG_BACKUP="" -SERVER_IP="" - -# 颜色定义 -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[0;33m' -BLUE='\033[0;34m' -CYAN='\033[0;36m' -NC='\033[0m' # No Color - -# 进度条函数 -show_progress() { - local pid=$1 - local delay=0.1 - local spinstr='|/-\' - local temp - local count=0 - local start_time=$(date +%s) - echo -n " " - - while ps -p $pid > /dev/null; do - temp=${spinstr#?} - printf "\r[%c] %s 已进行 %ds" "$spinstr" "$2" "$(($(date +%s) - start_time))" - spinstr=$temp${spinstr%"$temp"} - sleep $delay - count=$((count + 1)) - done - printf "\r\033[K" -} - -# 进度条显示函数 - 适用于apt操作 -apt_progress() { - local cmd="$1" - local msg="$2" - local logfile="$LOG_FILE.tmp" - - echo -e "${CYAN}开始 $msg...${NC}" - touch "$logfile" - ($cmd 2>&1 | tee -a "$LOG_FILE" > "$logfile") & - local pid=$! - - # 显示进度条 - local start_time=$(date +%s) - local dots="" - local status="" - local progress=0 - local last_line="" - local delay=0.2 - - while ps -p $pid > /dev/null; do - # 读取最后一行日志 - if [[ -f "$logfile" ]]; then - last_line=$(tail -n 1 "$logfile") - - # 尝试从输出中提取进度信息 - if [[ $last_line == *%* ]]; then - status="${last_line%%(*}" - progress="${last_line#*(}" - progress="${progress%%)*}" - printf "\r\033[K${CYAN}[$msg]${NC} %s %s " "$status" "$progress" - else - dots="${dots}." - if [[ ${#dots} -gt 5 ]]; then dots="."; fi - elapsed=$(($(date +%s) - start_time)) - printf "\r\033[K${CYAN}[$msg]${NC} 进行中%s (%ds)" "$dots" "$elapsed" - fi - fi - sleep $delay - done - - if wait $pid; then - printf "\r\033[K${GREEN}[$msg]${NC} 完成! 用时: %ds\n" "$(($(date +%s) - start_time))" - rm -f "$logfile" - return 0 - else - printf "\r\033[K${RED}[$msg]${NC} 失败! 查看日志: $LOG_FILE\n" - rm -f "$logfile" - return 1 - fi -} - -# 日志函数 -log_info() { - echo -e "${GREEN}[INFO]${NC} $1" | tee -a "$LOG_FILE" -} - -log_warn() { - echo -e "${YELLOW}[WARN]${NC} $1" | tee -a "$LOG_FILE" -} - -log_error() { - echo -e "${RED}[ERROR]${NC} $1" >&2 | tee -a "$LOG_FILE" -} - -log_debug() { - echo -e "${BLUE}[DEBUG]${NC} $1" | tee -a "$LOG_FILE" -} - -# 检查是否有 root 权限 -check_root() { - if [[ $EUID -ne 0 ]]; then - log_error "此脚本需要 root 权限运行" - exit 1 - fi -} - -# 检查系统环境 -check_system() { - # 显示系统信息 - echo "系统信息:" - echo "------------------------" - if [ -f /etc/os-release ]; then - cat /etc/os-release | grep "PRETTY_NAME" | cut -d= -f2- | tr -d '"' - fi - echo "内核版本: $(uname -r)" - echo "架构: $(uname -m)" - echo "------------------------" - - # 检查是否为 Debian/Ubuntu 系统 - if [[ ! -f /etc/debian_version && ! -f /etc/lsb-release ]]; then - log_warn "未检测到 Debian/Ubuntu 系统,脚本可能无法正常工作" - read -rp "是否继续? [y/N] " response - if [[ ! "$response" =~ ^[yY]$ ]]; then - exit 1 - fi - fi - - # 检查网络连接 - echo -n "检查网络连接... " - if ping -c 1 -W 2 github.com &>/dev/null; then - echo -e "${GREEN}连接正常${NC}" - else - echo -e "${YELLOW}无法连接到 GitHub${NC}" - log_warn "无法连接到 GitHub,请检查网络连接" - read -rp "是否继续? [y/N] " response - if [[ ! "$response" =~ ^[yY]$ ]]; then - exit 1 - fi - fi -} - -# 获取最新版本号 -get_latest_version() { - # 利用GitHub重定向特性获取最新版本 - local redirect_url=$(curl -s -L -o /dev/null -w '%{url_effective}' https://github.com/XTLS/Xray-core/releases/latest 2>/dev/null) - local version=$(echo "$redirect_url" | grep -o 'tag/v[0-9.]*' | cut -d/ -f2 2>/dev/null) - - # 如果获取失败,尝试备用方法 - if [[ -z "$version" ]]; then - # 方法2: 通过API获取 - version=$(curl -s https://api.github.com/repos/XTLS/Xray-core/releases/latest | grep -o '"tag_name": "v[0-9.]*"' | cut -d'"' -f4 2>/dev/null) - fi - - # 如果还是失败,返回当前全局版本 - if [[ -z "$version" ]]; then - version="$XRAY_VERSION" - else - # 更新全局变量 - XRAY_VERSION="$version" - fi - - echo "$version" -} - -# 备份函数 -backup_config() { - if [[ -d "$CONFIG_PATH" ]]; then - CONFIG_BACKUP="${CONFIG_PATH}_backup_$(date +%Y%m%d%H%M%S)" - log_info "备份现有配置到 $CONFIG_BACKUP" - cp -r "$CONFIG_PATH" "$CONFIG_BACKUP" || log_warn "配置备份失败" - - # 备份 Xray 信息文件 - if [[ -f "/root/xray_info.txt" ]]; then - cp "/root/xray_info.txt" "${CONFIG_BACKUP}/xray_info.txt.bak" || log_warn "Xray 信息文件备份失败" - fi - else - log_warn "找不到配置目录,跳过备份" - fi -} - -# 显示帮助信息 -show_help() { - echo "Xray 管理脚本 v${SCRIPT_VERSION}" - echo "用法: $0 [选项]" - echo "" - echo "选项:" - echo " -h, --help 显示此帮助信息" - echo " -i, --install 直接运行安装" - echo " -u, --uninstall 直接运行卸载" - echo " -s, --status 查看 Xray 状态" - echo " -up, --update 更新 Xray" - echo "" - echo "无参数运行脚本将显示交互式菜单" -} - -# 菜单函数 -show_menu() { - clear - echo "==================================================" - echo -e "${CYAN}Xray REALITY管理脚本 v${SCRIPT_VERSION}${NC}" - echo -e "${CYAN}(VLESS+REALITY 协议)${NC}" - echo "==================================================" - echo -e "1) ${GREEN}安装 Xray${NC}" - echo -e "2) ${RED}卸载 Xray${NC}" - echo -e "3) ${YELLOW}更新 Xray${NC}" - echo -e "4) ${BLUE}查看 Xray 状态${NC}" - echo -e "5) ${CYAN}查看 Xray 配置信息${NC}" - echo -e "6) ${GREEN}重启 Xray 服务${NC}" - echo -e "7) ${YELLOW}手动设置 Xray 版本号${NC}" - echo -e "0) ${RED}退出${NC}" - echo "==================================================" - echo "" - read -rp "请输入选项 [0-7]: " choice - - case $choice in - 1) install_xray ;; - 2) uninstall_xray ;; - 3) update_xray ;; - 4) check_status ;; - 5) show_config ;; - 6) restart_service ;; - 7) set_xray_version ;; - 0) exit 0 ;; - *) log_error "无效选项" && sleep 2 && show_menu ;; - esac -} - -# 设置Xray版本号 -set_xray_version() { - clear - echo "==================================================" - echo -e "${YELLOW}手动设置 Xray 版本号${NC}" - echo "==================================================" - - echo "当前Xray版本号: $XRAY_VERSION" - echo "" - echo "1) 自动获取最新版本" - echo "2) 手动输入版本号" - echo "0) 返回主菜单" - echo "" - - read -rp "请选择操作 [0-2]: " version_choice - - case $version_choice in - 1) - echo -n "正在获取最新版本... " - local latest_version=$(get_latest_version) - - if [[ "$latest_version" == "$XRAY_VERSION" && ! -z "$latest_version" ]]; then - echo -e "${GREEN}成功${NC}" - log_info "当前已是最新版本: $XRAY_VERSION" - elif [[ -z "$latest_version" || "$latest_version" == "v1.8.4" ]]; then - echo -e "${RED}失败${NC}" - log_error "无法自动获取最新版本" - else - echo -e "${GREEN}成功${NC}" - XRAY_VERSION="$latest_version" - log_info "Xray版本已自动更新为: $XRAY_VERSION" - fi - ;; - 2) - echo "请访问 https://github.com/XTLS/Xray-core/releases 查看可用版本" - read -rp "请输入新的版本号(例如 v25.3.6): " new_version - - if [[ -z "$new_version" ]]; then - log_error "版本号不能为空" - elif [[ ! "$new_version" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then - log_error "版本号格式不正确,请使用类似 v25.3.6 的格式" - else - XRAY_VERSION="$new_version" - log_info "Xray版本已更新为: $XRAY_VERSION" - fi - ;; - 0) - # 直接返回 - ;; - *) - log_error "无效选项" - ;; - esac - - read -rp "按回车键返回主菜单..." temp - show_menu -} - -# 安装依赖 -install_dependencies() { - log_info "安装必要依赖" - - # 更新软件包列表 - apt_progress "apt-get update" "更新软件包列表" || { - log_error "更新软件包列表失败" - return 1 - } - - # 安装必要工具 - local deps=(curl wget jq unzip) - for dep in "${deps[@]}"; do - if ! command -v "$dep" &>/dev/null; then - apt_progress "apt-get install -y $dep" "安装 $dep" || { - log_error "安装 $dep 失败" - return 1 - } - else - log_info "$dep 已安装,跳过" - fi - done - - # 检查安装结果 - local all_installed=true - for dep in "${deps[@]}"; do - if ! command -v "$dep" &>/dev/null; then - log_error "$dep 安装失败" - all_installed=false - fi - done - - if [ "$all_installed" = true ]; then - log_info "所有依赖安装完成" - return 0 - else - log_error "部分依赖安装失败" - return 1 - fi -} - -# 下载 Xray -download_xray() { - log_info "开始下载 Xray" - - # 检查Xray服务是否正在运行,如果是则停止 - if systemctl is-active xray &>/dev/null; then - log_info "检测到Xray服务正在运行,先停止服务" - echo -n "停止 Xray 服务... " - if systemctl stop xray &>/dev/null; then - echo -e "${GREEN}成功${NC}" - else - echo -e "${RED}失败${NC}" - log_warn "无法停止 Xray 服务,可能会影响安装" - fi - - # 等待进程完全停止 - echo -n "等待进程释放资源... " - sleep 2 - if pgrep -x "xray" > /dev/null; then - # 如果进程仍在运行,尝试强制终止 - pkill -9 -x "xray" &>/dev/null - sleep 1 - fi - echo -e "${GREEN}完成${NC}" - fi - - # 创建临时目录 - local tmp_dir="/tmp/xray_install" - mkdir -p "$tmp_dir" - - # 获取最新版本 - echo -n "获取 Xray 最新版本... " - local latest_version=$(get_latest_version) - echo -e "${GREEN}$latest_version${NC}" - - # 确定系统架构 - local arch - case $(uname -m) in - x86_64|amd64) arch="64" ;; - armv7l|armv8l) arch="arm32-v7a" ;; - aarch64) arch="arm64-v8a" ;; - *) arch="64" ;; # 默认使用64位版本 - esac - - # 构建下载URL - local download_url="https://github.com/XTLS/Xray-core/releases/download/$latest_version/Xray-linux-$arch.zip" - log_info "下载链接: $download_url" - - # 下载Xray - echo -n "下载 Xray... " - if wget -q --show-progress -O "$tmp_dir/xray.zip" "$download_url"; then - echo -e "${GREEN}成功${NC}" - else - echo -e "${RED}失败${NC}" - log_error "下载 Xray 失败" - return 1 - fi - - # 解压文件 - echo -n "解压 Xray... " - if unzip -q -o "$tmp_dir/xray.zip" -d "$tmp_dir"; then - echo -e "${GREEN}成功${NC}" - else - echo -e "${RED}失败${NC}" - log_error "解压 Xray 失败" - return 1 - fi - - # 创建目录 - mkdir -p "$XRAY_PATH" "$CONFIG_PATH" "$LOG_PATH" - - # 复制文件前确保目标文件不被占用 - if [[ -f "$XRAY_PATH/xray" ]]; then - # 如果文件存在,先尝试重命名它 - mv "$XRAY_PATH/xray" "$XRAY_PATH/xray.old" 2>/dev/null - fi - - # 复制文件 - echo -n "安装 Xray 核心文件... " - if cp "$tmp_dir/xray" "$XRAY_PATH/xray" && chmod +x "$XRAY_PATH/xray"; then - echo -e "${GREEN}成功${NC}" - # 删除旧文件 - rm -f "$XRAY_PATH/xray.old" 2>/dev/null - else - echo -e "${RED}失败${NC}" - log_error "安装 Xray 核心文件失败" - # 恢复旧文件 - if [[ -f "$XRAY_PATH/xray.old" ]]; then - mv "$XRAY_PATH/xray.old" "$XRAY_PATH/xray" 2>/dev/null - fi - return 1 - fi - - # 复制 geoip.dat 和 geosite.dat - echo -n "安装 GeoIP 和 GeoSite 数据... " - if cp "$tmp_dir/geoip.dat" "$XRAY_PATH/geoip.dat" && \ - cp "$tmp_dir/geosite.dat" "$XRAY_PATH/geosite.dat"; then - echo -e "${GREEN}成功${NC}" - else - echo -e "${RED}失败${NC}" - log_warn "安装 GeoIP 和 GeoSite 数据失败,将在配置时下载" - fi - - # 清理临时文件 - rm -rf "$tmp_dir" - - log_info "Xray $latest_version 安装完成" - return 0 -} - -# 生成随机 PORT 和 UUID -generate_random_values() { - log_info "生成随机配置值" - - # 询问用户是否指定端口 - if [[ -z "$REALITY_PORT" ]]; then - read -rp "是否指定端口? [y/N] " specify_port - if [[ "$specify_port" =~ ^[yY]$ ]]; then - # 用户选择指定端口 - while true; do - read -rp "请输入端口号 (1-65535): " REALITY_PORT - # 验证端口是否为有效数字 - if ! [[ "$REALITY_PORT" =~ ^[0-9]+$ ]] || [ "$REALITY_PORT" -lt 1 ] || [ "$REALITY_PORT" -gt 65535 ]; then - log_error "无效的端口号,请输入1-65535之间的数字" - continue - fi - - # 检查端口是否被占用 - if ss -tuln | grep -q ":$REALITY_PORT "; then - log_warn "端口 $REALITY_PORT 已被占用,请选择其他端口" - continue - fi - - log_info "将使用指定端口: $REALITY_PORT" - break - done - else - # 用户选择随机端口,继续原来的逻辑 - # 尝试找一个未被占用的端口 - local attempts=0 - while [[ "$attempts" -lt 10 ]]; do - REALITY_PORT=$(shuf -i 10000-60000 -n 1) - # 检查端口是否被占用 - if ! ss -tuln | grep -q ":$REALITY_PORT "; then - log_info "生成随机端口: $REALITY_PORT" - break - fi - attempts=$((attempts + 1)) - done - if [[ "$attempts" -eq 10 ]]; then - log_warn "无法找到未占用的端口,使用随机端口: $REALITY_PORT" - fi - fi - else - # 验证端口是否为有效数字 - if ! [[ "$REALITY_PORT" =~ ^[0-9]+$ ]]; then - log_warn "无效的端口: $REALITY_PORT,生成新的随机端口" - REALITY_PORT=$(shuf -i 10000-60000 -n 1) - fi - fi - - # 生成 UUID - if [[ -z "$UUID" ]]; then - # 检查xray命令是否可用 - if [[ -f "$XRAY_PATH/xray" && -x "$XRAY_PATH/xray" ]]; then - UUID=$($XRAY_PATH/xray uuid) - log_info "生成 UUID: $UUID" - else - # 如果xray不可用,使用uuidgen或者随机生成 - if command -v uuidgen &>/dev/null; then - UUID=$(uuidgen) - else - # 简单的UUID生成方法(不完全符合标准但足够使用) - UUID=$(cat /proc/sys/kernel/random/uuid 2>/dev/null || - (date +%s%N | sha256sum | head -c 32 | - sed 's/\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)/\1\2\3\4-\5\6-\7\8-/')) - fi - log_info "生成 UUID: $UUID" - fi - else - # 验证UUID格式 - if ! [[ "$UUID" =~ ^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$ ]]; then - log_warn "无效的 UUID 格式: $UUID,生成新的 UUID" - if [[ -f "$XRAY_PATH/xray" && -x "$XRAY_PATH/xray" ]]; then - UUID=$($XRAY_PATH/xray uuid) - else - UUID=$(cat /proc/sys/kernel/random/uuid 2>/dev/null || - (date +%s%N | sha256sum | head -c 32 | - sed 's/\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)/\1\2\3\4-\5\6-\7\8-/')) - fi - log_info "生成新的 UUID: $UUID" - fi - fi - - # 生成 REALITY 密钥对 - log_info "生成 REALITY 密钥对" - if [[ -z "$PRIVATE_KEY" || -z "$PUBLIC_KEY" ]]; then - local key_pair - if [[ -f "$XRAY_PATH/xray" && -x "$XRAY_PATH/xray" ]]; then - key_pair=$($XRAY_PATH/xray x25519) - PRIVATE_KEY=$(echo "$key_pair" | grep "Private" | awk '{print $3}') - PUBLIC_KEY=$(echo "$key_pair" | grep "Public" | awk '{print $3}') - else - log_warn "无法使用 xray 生成密钥对,将跳过密钥生成" - log_info "安装完成后,将自动生成密钥对" - fi - fi - - # 获取服务器IP - get_server_ip - - log_debug "私钥: $PRIVATE_KEY" - log_debug "公钥: $PUBLIC_KEY" -} - -# 获取服务器IP -get_server_ip() { - log_info "获取服务器IP地址" - - if [[ -n "$SERVER_IP" ]]; then - log_info "使用已设置的IP: $SERVER_IP" - return 0 - fi - - # 尝试首选方法获取公网IP - SERVER_IP=$(curl -s -m 5 https://api.ipify.org 2>/dev/null) - - # 验证获取到的IP是否为有效IPv4地址 - if [[ -n "$SERVER_IP" && "$SERVER_IP" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then - log_info "成功获取公网IP: $SERVER_IP" - return 0 - fi - - # 如果第一个方法失败,尝试备用方法 - local backup_services=("https://ifconfig.me" "https://ip.sb" "https://ipinfo.io/ip") - - for service in "${backup_services[@]}"; do - SERVER_IP=$(curl -s -m 3 "$service" 2>/dev/null) - if [[ -n "$SERVER_IP" && "$SERVER_IP" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then - log_info "成功从 $service 获取公网IP: $SERVER_IP" - return 0 - fi - done - - # 如果所有公网IP获取方式都失败,则使用本地IP - if command -v hostname &>/dev/null; then - SERVER_IP=$(hostname -I 2>/dev/null | awk '{print $1}') - fi - - # 如果hostname命令失败,尝试使用ip命令 - if [[ -z "$SERVER_IP" && -x "$(command -v ip)" ]]; then - SERVER_IP=$(ip -4 addr show scope global | grep -oP '(?<=inet\s)\d+(\.\d+){3}' | head -n 1) - fi - - # 如果还是失败,尝试使用ifconfig命令 - if [[ -z "$SERVER_IP" && -x "$(command -v ifconfig)" ]]; then - SERVER_IP=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1' | head -n 1) - fi - - if [[ -n "$SERVER_IP" ]]; then - log_warn "无法获取公网IP,使用本地IP: $SERVER_IP" - return 0 - else - log_error "无法获取任何有效IP地址,将使用127.0.0.1作为占位符" - SERVER_IP="127.0.0.1" - return 1 - fi -} - -# 配置 Xray - 修改为 VLESS+REALITY 并支持 TUN 模式 -configure_xray() { - log_info "配置 Xray" - - # 生成随机值 - generate_random_values - - # 创建配置目录 - mkdir -p "$CONFIG_PATH" - - # 创建示例目录 - mkdir -p "$CONFIG_PATH/examples" - - log_info "创建 VLESS+REALITY 配置文件(支持TUN模式)" - - # VLESS + REALITY 配置 (添加支持TUN模式的DNS和路由配置) - cat > "$CONFIG_PATH/config.json" << EOF -{ - "log": { - "loglevel": "warning", - "access": "$LOG_PATH/access.log", - "error": "$LOG_PATH/error.log" - }, - "inbounds": [ - { - "port": $REALITY_PORT, - "protocol": "vless", - "settings": { - "clients": [ - { - "id": "$UUID", - "flow": "xtls-rprx-vision" - } - ], - "decryption": "none" - }, - "streamSettings": { - "network": "tcp", - "security": "reality", - "realitySettings": { - "show": false, - "dest": "www.shopify.com:443", - "xver": 0, - "serverNames": [ - "shopify.com", - "www.shopify.com" - ], - "privateKey": "$PRIVATE_KEY", - "shortIds": [ - "", - "6ba85179e30d" - ] - } - }, - "sniffing": { - "enabled": true, - "destOverride": [ - "http", - "tls", - "quic" - ], - "routeOnly": false - } - } - ], - "outbounds": [ - { - "protocol": "freedom", - "tag": "direct" - }, - { - "protocol": "blackhole", - "tag": "block" - } - ], - "dns": { - "hosts": { - "dns.google": "8.8.8.8", - "proxy.example.com": "127.0.0.1" - }, - "servers": [ - { - "address": "1.1.1.1", - "domains": [ - "geosite:geolocation-!cn" - ], - "expectIPs": [ - "geoip:!cn" - ] - }, - { - "address": "223.5.5.5", - "domains": [ - "geosite:cn" - ], - "expectIPs": [ - "geoip:cn" - ] - }, - "8.8.8.8", - "https://dns.google/dns-query" - ] - }, - "routing": { - "domainStrategy": "AsIs", - "rules": [ - { - "type": "field", - "outboundTag": "block", - "domain": [ - "geosite:category-ads-all" - ] - }, - { - "type": "field", - "outboundTag": "direct", - "ip": [ - "geoip:private" - ] - }, - { - "type": "field", - "outboundTag": "direct", - "domain": [ - "geosite:private" - ] - }, - { - "type": "field", - "port": "443", - "network": "udp", - "outboundTag": "block" - }, - { - "type": "field", - "outboundTag": "direct", - "ip": [ - "geoip:cn" - ] - }, - { - "type": "field", - "outboundTag": "direct", - "domain": [ - "geosite:cn" - ] - } - ] - } -} -EOF - - if [[ -f "$CONFIG_PATH/config.json" ]]; then - log_info "配置文件创建成功" - else - log_error "配置文件创建失败" - return 1 - fi - - return 0 -} - -# 配置防火墙 - 简化只处理 REALITY 端口 -configure_firewall() { - log_info "配置防火墙" - - # 检测和关闭旧端口 - local old_ports=() - - # 从备份中查找旧端口 - if [[ -n "$CONFIG_BACKUP" && -f "$CONFIG_BACKUP/config.json" ]]; then - log_info "检测旧配置中的端口" - if command -v jq &>/dev/null; then - # 使用jq查找所有inbounds的端口 - local detected_ports=$(jq '.inbounds[].port' "$CONFIG_BACKUP/config.json" 2>/dev/null) - for port in $detected_ports; do - if [[ "$port" != "null" && -n "$port" ]]; then - old_ports+=("$port") - log_info "检测到旧端口: $port" - fi - done - else - # 使用grep查找端口 - local detected_ports=$(grep -o '"port": [0-9]*' "$CONFIG_BACKUP/config.json" | awk '{print $2}') - for port in $detected_ports; do - if [[ -n "$port" ]]; then - old_ports+=("$port") - log_info "检测到旧端口: $port" - fi - done - fi - fi - - # 如果找不到旧端口,也查找默认位置 - if [[ ${#old_ports[@]} -eq 0 && -f "$CONFIG_PATH/config.json" && "$CONFIG_PATH/config.json" != "$(readlink -f "$CONFIG_BACKUP/config.json")" ]]; then - if command -v jq &>/dev/null; then - # 使用jq查找所有inbounds的端口 - local detected_ports=$(jq '.inbounds[].port' "$CONFIG_PATH/config.json" 2>/dev/null) - for port in $detected_ports; do - if [[ "$port" != "null" && -n "$port" ]]; then - old_ports+=("$port") - log_info "检测到当前配置的端口: $port" - fi - done - else - # 使用grep查找端口 - local detected_ports=$(grep -o '"port": [0-9]*' "$CONFIG_PATH/config.json" | awk '{print $2}') - for port in $detected_ports; do - if [[ -n "$port" ]]; then - old_ports+=("$port") - log_info "检测到当前配置的端口: $port" - fi - done - fi - fi - - # 从旧端口列表中过滤掉当前端口 - local filtered_ports=() - for port in "${old_ports[@]}"; do - # 检查端口是否为有效数字 - if ! [[ "$port" =~ ^[0-9]+$ ]]; then - log_warn "无效的端口号: $port,已跳过" - continue - fi - - # 检查是否与当前端口相同 - if [[ "$port" -eq "$REALITY_PORT" ]]; then - log_info "端口 $port 与当前端口相同,已跳过" - continue - fi - - filtered_ports+=("$port") - done - old_ports=("${filtered_ports[@]}") - - # 检查是否安装了 ufw - if command -v ufw &>/dev/null; then - # 检查ufw是否启用 - local ufw_status=$(ufw status | grep -o "Status: active" 2>/dev/null) - - if [[ -z "$ufw_status" ]]; then - log_warn "UFW 防火墙未启用,可能需要手动配置防火墙规则" - log_info "您可以运行 'sudo ufw enable' 启用 UFW 防火墙" - return 0 - fi - - # 关闭旧端口 - if [[ ${#old_ports[@]} -gt 0 ]]; then - log_info "开始关闭旧端口" - local closed_ports=() - - for port in "${old_ports[@]}"; do - # 检查端口是否已开放在UFW中 - if ! ufw status | grep -q "$port/tcp"; then - log_info "端口 $port 未在 UFW 中开放,跳过" - continue - fi - - echo -n "关闭 UFW 防火墙端口 $port... " - if ufw delete allow "$port/tcp" &>/dev/null; then - echo -e "${GREEN}完成${NC}" - closed_ports+=("$port") - else - echo -e "${RED}失败${NC}" - log_warn "无法关闭端口 $port" - fi - done - - # 打印关闭的端口 - if [[ ${#closed_ports[@]} -gt 0 ]]; then - local closed_list=$(printf ", %s" "${closed_ports[@]}") - closed_list=${closed_list:2} # 移除开头的逗号和空格 - log_info "已关闭 UFW 防火墙中的旧端口: $closed_list" - else - log_info "没有需要关闭的旧端口" - fi - else - log_info "未检测到旧端口,跳过关闭端口步骤" - fi - - # 确定需要开放的端口 - local ports=("$REALITY_PORT") - - echo -n "配置 UFW 防火墙... " - local opened_ports=() - for port in "${ports[@]}"; do - # 检查端口是否为有效数字 - if ! [[ "$port" =~ ^[0-9]+$ ]]; then - log_warn "端口 '$port' 不是有效数字,已跳过" - continue - fi - - # 检查端口是否已经开放 - if ufw status | grep -q "$port/tcp"; then - log_info "端口 $port 已经开放,跳过" - opened_ports+=("$port") - continue - fi - - # 开放端口 - if ufw allow "$port/tcp" &>/dev/null; then - opened_ports+=("$port") - else - log_warn "无法开放端口 $port" - fi - done - echo -e "${GREEN}完成${NC}" - - # 打印开放的端口 - if [[ ${#opened_ports[@]} -gt 0 ]]; then - local port_list=$(printf ", %s" "${opened_ports[@]}") - port_list=${port_list:2} # 移除开头的逗号和空格 - log_info "已在 UFW 防火墙开放端口: $port_list" - else - log_warn "没有成功开放任何端口" - fi - else - log_warn "未检测到 UFW 防火墙,跳过防火墙配置" - log_info "如需管理防火墙规则,请安装 UFW: sudo apt install ufw" - fi - - return 0 -} - -# 生成客户端配置 - 更新为只提供 VLESS+REALITY -generate_client_info() { - log_info "生成客户端信息" - - # 确保IP地址已获取 - if [[ -z "$SERVER_IP" ]]; then - get_server_ip - fi - - # 生成 VLESS + REALITY 分享链接 - local share_link="vless://${UUID}@${SERVER_IP}:${REALITY_PORT}?security=reality&encryption=none&pbk=${PUBLIC_KEY}&fp=chrome&type=tcp&flow=xtls-rprx-vision&sni=www.shopify.com&sid=6ba85179e30d#Xray-Reality" - - # 保存客户端信息 - cat > /root/xray_info.txt << EOF -========================= Xray Reality 配置信息 ========================= -服务器地址: ${SERVER_IP} -端口: ${REALITY_PORT} -UUID: ${UUID} -协议: vless -传输协议: tcp -加密方式: none -流控: xtls-rprx-vision -安全: reality -公钥: ${PUBLIC_KEY} -私钥: ${PRIVATE_KEY} -SNI: www.shopify.com -指纹: chrome -短 ID: 6ba85179e30d -================================================================== - -分享链接: -${share_link} - -二维码链接: -https://api.qrserver.com/v1/create-qr-code/?size=300x300&data=${share_link} -================================================================== - -TUN模式支持: -REALITY 协议已配置支持 TUN 模式,客户端配置示例文件已生成: -1. REALITY-TUN配置: ${CONFIG_PATH}/examples/reality_tun_example.json - -将配置文件导入到支持TUN模式的客户端后: -1. 切换到"TUN模式"选项卡 -2. 点击"启用TUN模式" -3. 选择"系统代理"或"全局代理" -4. 重启客户端并允许管理员权限 - -================================================================== - -配置文件路径: ${CONFIG_PATH}/config.json -服务控制: -启动: systemctl start xray -停止: systemctl stop xray -重启: systemctl restart xray -状态: systemctl status xray -================================================================== -EOF - - # 生成 REALITY TUN 模式配置示例 - generate_reality_tun_config - - log_info "客户端信息已保存到 /root/xray_info.txt" - - # 打印信息 - cat /root/xray_info.txt - - log_info "安装完成!Xray REALITY 已成功部署" - return 0 -} - -# 新增:生成 REALITY TUN 模式配置 -generate_reality_tun_config() { - log_info "生成 REALITY TUN 模式配置示例" - - # 确保IP地址已设置 - if [[ -z "$SERVER_IP" ]]; then - get_server_ip - fi - - # 创建 TUN 配置示例目录 - local example_dir="$CONFIG_PATH/examples" - mkdir -p "$example_dir" - - # 生成客户端配置示例,用于TUN模式 - cat > "$example_dir/reality_tun_example.json" << EOF -{ - "log": { - "loglevel": "warning" - }, - "inbounds": [ - { - "tag": "socks", - "port": 10808, - "listen": "127.0.0.1", - "protocol": "socks", - "sniffing": { - "enabled": true, - "destOverride": [ - "http", - "tls" - ], - "routeOnly": false - }, - "settings": { - "auth": "noauth", - "udp": true, - "allowTransparent": false - } - }, - { - "tag": "tun", - "protocol": "tun", - "settings": { - "network": "all" - }, - "sniffing": { - "enabled": true, - "destOverride": [ - "http", - "tls" - ], - "routeOnly": false - } - } - ], - "tun": { - "enable": true, - "stack": "gvisor", - "mtu": 9000, - "strict_route": true - }, - "outbounds": [ - { - "tag": "proxy", - "protocol": "vless", - "settings": { - "vnext": [ - { - "address": "${SERVER_IP}", - "port": ${REALITY_PORT}, - "users": [ - { - "id": "${UUID}", - "flow": "xtls-rprx-vision", - "encryption": "none" - } - ] - } - ] - }, - "streamSettings": { - "network": "tcp", - "security": "reality", - "realitySettings": { - "show": false, - "fingerprint": "chrome", - "serverName": "www.shopify.com", - "publicKey": "${PUBLIC_KEY}", - "shortId": "6ba85179e30d" - } - } - }, - { - "tag": "direct", - "protocol": "freedom" - }, - { - "tag": "block", - "protocol": "blackhole" - } - ], - "dns": { - "hosts": { - "dns.google": "8.8.8.8", - "proxy.example.com": "127.0.0.1" - }, - "servers": [ - { - "address": "1.1.1.1", - "domains": [ - "geosite:geolocation-!cn" - ], - "expectIPs": [ - "geoip:!cn" - ] - }, - { - "address": "223.5.5.5", - "domains": [ - "geosite:cn" - ], - "expectIPs": [ - "geoip:cn" - ] - }, - "8.8.8.8", - "https://dns.google/dns-query" - ] - }, - "routing": { - "domainStrategy": "IPIfNonMatch", - "rules": [ - { - "type": "field", - "outboundTag": "proxy", - "domain": [ - "domain:google.com", - "domain:googleapis.cn", - "domain:gstatic.com" - ] - }, - { - "type": "field", - "outboundTag": "direct", - "domain": [ - "geosite:cn" - ] - }, - { - "type": "field", - "outboundTag": "direct", - "ip": [ - "geoip:private", - "geoip:cn" - ] - } - ] - } -} -EOF - - log_info "REALITY TUN 模式配置示例已保存到 $example_dir/reality_tun_example.json" - log_info "使用方法: 将配置导入到支持TUN模式的客户端,然后开启TUN模式" - - return 0 -} - -# 创建系统服务 -create_service() { - log_info "创建 Xray 系统服务" - - # 创建服务文件 - cat > /etc/systemd/system/xray.service << EOF -[Unit] -Description=Xray Service -Documentation=https://github.com/XTLS/Xray-core -After=network.target nss-lookup.target - -[Service] -User=root -CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE -AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE -NoNewPrivileges=true -ExecStart=$XRAY_PATH/xray run -config $CONFIG_PATH/config.json -Restart=on-failure -RestartPreventExitStatus=23 -LimitNPROC=10000 -LimitNOFILE=1000000 - -[Install] -WantedBy=multi-user.target -EOF - - # 重新加载 systemd 配置并启用服务 - systemctl daemon-reload - - echo -n "启用 Xray 服务... " - if systemctl enable xray &>/dev/null; then - echo -e "${GREEN}成功${NC}" - else - echo -e "${RED}失败${NC}" - log_error "无法启用 Xray 服务" - return 1 - fi - - echo -n "启动 Xray 服务... " - if systemctl start xray; then - echo -e "${GREEN}成功${NC}" - else - echo -e "${RED}失败${NC}" - log_error "无法启动 Xray 服务" - return 1 - fi - - return 0 -} - -# 安装完整流程 - 更新为直接安装 VLESS+REALITY -install_xray() { - clear - echo "==================================================" - echo -e "${GREEN}开始安装 Xray REALITY 协议${NC}" - echo "==================================================" - - # 检查是否为 root - check_root - - # 检查系统环境 - check_system - - # 备份现有配置 - backup_config - - # 安装依赖 - install_dependencies || { - log_error "安装依赖失败,退出安装" - return 1 - } - - # 下载和安装 Xray - download_xray || { - log_error "下载 Xray 失败,退出安装" - return 1 - } - - # 配置 Xray - configure_xray || { - log_error "配置 Xray 失败,退出安装" - return 1 - } - - # 创建系统服务 - create_service || { - log_error "创建系统服务失败,但会继续安装过程" - } - - # 配置防火墙 - configure_firewall - - # 生成客户端信息 - generate_client_info - - echo "" - log_info "Xray REALITY 协议安装成功!" - - read -rp "按回车键返回主菜单..." temp - show_menu -} - -# 停止 Xray 服务 -stop_xray_service() { - log_info "停止 Xray 服务" - - if systemctl is-active xray &>/dev/null; then - echo -n "正在停止 Xray 服务... " - if systemctl stop xray &>/dev/null; then - echo -e "${GREEN}成功${NC}" - else - echo -e "${RED}失败${NC}" - log_warn "无法停止 Xray 服务,将尝试继续卸载" - fi - else - log_info "Xray 服务未运行" - fi - - echo -n "禁用 Xray 服务自启动... " - if systemctl disable xray &>/dev/null; then - echo -e "${GREEN}成功${NC}" - else - echo -e "${YELLOW}失败${NC}" - log_warn "无法禁用 Xray 服务自启动,服务可能不存在" - fi -} - -# 读取并关闭防火墙端口 -close_firewall_port() { - log_info "尝试关闭之前开放的防火墙端口" - - # 检查是否安装了 ufw - if ! command -v ufw &>/dev/null; then - log_warn "未检测到 UFW 防火墙,跳过防火墙配置关闭" - return 0 - fi - - # 检查ufw是否启用 - local ufw_status=$(ufw status | grep -o "Status: active" 2>/dev/null) - if [[ -z "$ufw_status" ]]; then - log_warn "UFW 防火墙未启用,跳过防火墙规则关闭" - return 0 - fi - - # 尝试从配置或备份文件中读取端口 - local ports=() - - # 从当前配置中查找端口 - if [[ -f "$CONFIG_PATH/config.json" ]]; then - if command -v jq &>/dev/null; then - # 使用jq查找所有inbounds的端口 - local all_ports=$(jq '.inbounds[].port' "$CONFIG_PATH/config.json" 2>/dev/null) - for port in $all_ports; do - if [[ "$port" != "null" && -n "$port" ]]; then - ports+=("$port") - fi - done - else - # 使用grep查找端口 - local all_ports=$(grep -o '"port": [0-9]*' "$CONFIG_PATH/config.json" | awk '{print $2}') - for port in $all_ports; do - if [[ -n "$port" ]]; then - ports+=("$port") - fi - done - fi - fi - - # 如果找不到端口,从备份中查找 - if [[ ${#ports[@]} -eq 0 && -n "$CONFIG_BACKUP" && -f "$CONFIG_BACKUP/config.json" ]]; then - if command -v jq &>/dev/null; then - local all_ports=$(jq '.inbounds[].port' "$CONFIG_BACKUP/config.json" 2>/dev/null) - for port in $all_ports; do - if [[ "$port" != "null" && -n "$port" ]]; then - ports+=("$port") - fi - done - else - local all_ports=$(grep -o '"port": [0-9]*' "$CONFIG_BACKUP/config.json" | awk '{print $2}') - for port in $all_ports; do - if [[ -n "$port" ]]; then - ports+=("$port") - fi - done - fi - fi - - # 如果还是找不到端口,尝试使用全局变量 - if [[ ${#ports[@]} -eq 0 ]]; then - if [[ -n "$REALITY_PORT" && "$REALITY_PORT" =~ ^[0-9]+$ ]]; then - ports+=("$REALITY_PORT") - fi - fi - - # 去除重复的端口 - if [[ ${#ports[@]} -gt 0 ]]; then - local unique_ports=() - local port_list="" - for port in "${ports[@]}"; do - # 检查端口是否为有效数字 - if ! [[ "$port" =~ ^[0-9]+$ ]]; then - log_warn "端口 '$port' 不是有效数字,已跳过" - continue - fi - - # 检查端口是否已在列表中 - if [[ "$port_list" != *",$port,"* ]]; then - unique_ports+=("$port") - port_list="$port_list,$port," - fi - done - ports=("${unique_ports[@]}") - fi - - # 如果找到了端口,关闭防火墙规则 - if [[ ${#ports[@]} -gt 0 ]]; then - local port_list=$(printf ", %s" "${ports[@]}") - port_list=${port_list:2} # 移除开头的逗号和空格 - log_info "找到端口: $port_list,尝试关闭 UFW 防火墙规则" - - local closed_ports=() - for port in "${ports[@]}"; do - # 检查端口是否已开放在UFW中 - if ! ufw status | grep -q "$port/tcp"; then - log_info "端口 $port 未在 UFW 中开放,跳过" - continue - fi - - echo -n "关闭 UFW 防火墙端口 $port... " - if ufw delete allow "$port/tcp" &>/dev/null; then - echo -e "${GREEN}完成${NC}" - closed_ports+=("$port") - else - echo -e "${RED}失败${NC}" - log_warn "无法关闭端口 $port" - fi - done - - # 打印关闭的端口 - if [[ ${#closed_ports[@]} -gt 0 ]]; then - local closed_list=$(printf ", %s" "${closed_ports[@]}") - closed_list=${closed_list:2} # 移除开头的逗号和空格 - log_info "已关闭 UFW 防火墙中的端口: $closed_list" - else - log_warn "没有关闭任何端口" - fi - else - log_warn "无法确定之前使用的端口,跳过防火墙规则关闭" - fi -} - -# 删除 Xray 文件 -remove_xray_files() { - log_info "删除 Xray 文件" - - # 删除二进制文件 - echo -n "删除 Xray 核心文件... " - if rm -f "$XRAY_PATH/xray" "$XRAY_PATH/geoip.dat" "$XRAY_PATH/geosite.dat"; then - echo -e "${GREEN}成功${NC}" - else - echo -e "${YELLOW}部分文件未能删除${NC}" - log_warn "部分 Xray 核心文件可能未能完全删除" - fi - - # 删除配置目录(不删除备份) - echo -n "删除 Xray 配置目录... " - if [[ -d "$CONFIG_PATH" ]]; then - if rm -rf "$CONFIG_PATH"; then - echo -e "${GREEN}成功${NC}" - else - echo -e "${RED}失败${NC}" - log_warn "无法删除配置目录 $CONFIG_PATH" - fi - else - echo -e "${YELLOW}配置目录不存在${NC}" - fi - - # 删除日志目录 - echo -n "删除 Xray 日志目录... " - if [[ -d "$LOG_PATH" ]]; then - if rm -rf "$LOG_PATH"; then - echo -e "${GREEN}成功${NC}" - else - echo -e "${RED}失败${NC}" - log_warn "无法删除日志目录 $LOG_PATH" - fi - else - echo -e "${YELLOW}日志目录不存在${NC}" - fi - - # 删除服务文件 - echo -n "删除 Xray 服务文件... " - if rm -f /etc/systemd/system/xray.service; then - echo -e "${GREEN}成功${NC}" - systemctl daemon-reload - else - echo -e "${YELLOW}服务文件不存在或无法删除${NC}" - fi - - return 0 -} - -# 完整卸载流程 -uninstall_xray() { - clear - echo "==================================================" - echo -e "${RED}开始卸载 Xray${NC}" - echo "==================================================" - - # 确认卸载 - echo -e "${YELLOW}警告: 这将卸载 Xray 并删除相关文件${NC}" - read -rp "是否继续? [y/N] " confirm - if [[ ! "$confirm" =~ ^[yY]$ ]]; then - log_info "卸载已取消" - read -rp "按回车键返回主菜单..." temp - show_menu - return 0 - fi - - # 检查 root 权限 - check_root - - # 备份配置 - backup_config - - # 停止服务 - stop_xray_service - - # 关闭防火墙端口 - close_firewall_port - - # 删除文件 - remove_xray_files - - echo "" - log_info "Xray 卸载完成" - - # 直接删除备份文件,不询问用户 - if [[ -n "$CONFIG_BACKUP" && -d "$CONFIG_BACKUP" ]]; then - rm -rf "$CONFIG_BACKUP" - log_info "备份文件已删除" - fi - - read -rp "按回车键返回主菜单..." temp - show_menu -} - -# 检查 Xray 状态 -check_status() { - clear - echo "==================================================" - echo -e "${BLUE}Xray 状态检查${NC}" - echo "==================================================" - - # 检查是否安装 - if [[ ! -f "$XRAY_PATH/xray" ]]; then - echo -e "${RED}Xray 未安装${NC}" - read -rp "按回车键返回主菜单..." temp - show_menu - return 0 - fi - - # 检查版本 - echo -n "Xray 版本: " - $XRAY_PATH/xray version | head -n 1 - - # 检查服务状态 - echo -n "服务状态: " - if systemctl is-active xray &>/dev/null; then - echo -e "${GREEN}运行中${NC}" - else - echo -e "${RED}未运行${NC}" - fi - - echo -n "自启动状态: " - if systemctl is-enabled xray &>/dev/null; then - echo -e "${GREEN}已启用${NC}" - else - echo -e "${RED}未启用${NC}" - fi - - # 获取内存和 CPU 使用情况 - echo "资源使用情况:" - ps -aux | grep xray | grep -v grep | awk '{print "内存使用: " $4 "%, CPU使用: " $3 "%"}' - - # 检查端口 - if [[ -f "$CONFIG_PATH/config.json" ]]; then - local current_port="" - if command -v jq &>/dev/null; then - current_port=$(jq '.inbounds[0].port' "$CONFIG_PATH/config.json" 2>/dev/null) - else - current_port=$(grep -o '"port": [0-9]*' "$CONFIG_PATH/config.json" | head -1 | awk '{print $2}') - fi - - if [[ -n "$current_port" && "$current_port" != "null" ]]; then - echo -n "端口 $current_port 状态: " - if command -v ss &>/dev/null; then - if ss -tuln | grep -q ":$current_port "; then - echo -e "${GREEN}已开放${NC}" - else - echo -e "${RED}未开放${NC}" - fi - elif command -v netstat &>/dev/null; then - if netstat -tuln | grep -q ":$current_port "; then - echo -e "${GREEN}已开放${NC}" - else - echo -e "${RED}未开放${NC}" - fi - else - echo -e "${YELLOW}无法检查${NC}" - fi - - # 显示链接数 - echo "当前连接:" - if command -v ss &>/dev/null; then - ss -tn | grep ":$current_port" | wc -l | awk '{print "活跃连接数: " $1}' - elif command -v netstat &>/dev/null; then - netstat -tn | grep ":$current_port" | wc -l | awk '{print "活跃连接数: " $1}' - else - echo "无法获取连接信息" - fi - fi - fi - - echo -e "\n最近的日志:" - if [[ -f "$LOG_PATH/error.log" ]]; then - tail -n 10 "$LOG_PATH/error.log" - else - echo "找不到错误日志文件" - fi - - read -rp "按回车键返回主菜单..." temp - show_menu -} - -# 显示配置信息 -show_config() { - clear - echo "==================================================" - echo -e "${CYAN}Xray 配置信息${NC}" - echo "==================================================" - - # 检查是否已安装 - if [[ ! -f "$XRAY_PATH/xray" ]]; then - echo -e "${RED}Xray 未安装${NC}" - read -rp "按回车键返回主菜单..." temp - show_menu - return 0 - fi - - # 显示配置文件内容 - if [[ -f "$CONFIG_PATH/config.json" ]]; then - if command -v jq &>/dev/null; then - echo "配置信息 (美化格式):" - jq . "$CONFIG_PATH/config.json" - else - echo "配置文件内容:" - cat "$CONFIG_PATH/config.json" - fi - else - echo -e "${RED}找不到配置文件${NC}" - fi - - # 显示客户端信息 - if [[ -f "/root/xray_info.txt" ]]; then - echo -e "\n客户端信息:" - cat /root/xray_info.txt - else - echo -e "\n${RED}找不到客户端信息文件${NC}" - fi - - read -rp "按回车键返回主菜单..." temp - show_menu -} - -# 重启 Xray 服务 -restart_service() { - clear - echo "==================================================" - echo -e "${GREEN}重启 Xray 服务${NC}" - echo "==================================================" - - # 检查是否已安装 - if [[ ! -f "$XRAY_PATH/xray" ]]; then - echo -e "${RED}Xray 未安装${NC}" - read -rp "按回车键返回主菜单..." temp - show_menu - return 0 - fi - - echo -n "重启 Xray 服务... " - if systemctl restart xray; then - echo -e "${GREEN}成功${NC}" - log_info "Xray 服务已重启" - else - echo -e "${RED}失败${NC}" - log_error "无法重启 Xray 服务" - fi - - # 检查服务状态 - echo -n "Xray 服务状态: " - if systemctl is-active xray &>/dev/null; then - echo -e "${GREEN}运行中${NC}" - else - echo -e "${RED}未运行${NC}" - fi - - read -rp "按回车键返回主菜单..." temp - show_menu -} - -# 更新 Xray -update_xray() { - clear - echo "==================================================" - echo -e "${YELLOW}更新 Xray${NC}" - echo "==================================================" - - # 检查是否已安装 - if [[ ! -f "$XRAY_PATH/xray" ]]; then - echo -e "${RED}Xray 未安装,请先安装${NC}" - read -rp "按回车键返回主菜单..." temp - show_menu - return 0 - fi - - # 获取当前版本 - local current_version - current_version=$($XRAY_PATH/xray version | head -n 1 | cut -d ' ' -f 2) - echo "当前版本: $current_version" - - # 获取最新版本 - echo -n "获取最新版本... " - local latest_version=$(get_latest_version) - echo -e "${GREEN}$latest_version${NC}" - - # 比较版本 - if [[ "$current_version" == "$latest_version" ]]; then - echo -e "${GREEN}已经是最新版本${NC}" - read -rp "是否强制更新? [y/N] " confirm - if [[ ! "$confirm" =~ ^[yY]$ ]]; then - log_info "更新已取消" - read -rp "按回车键返回主菜单..." temp - show_menu - return 0 - fi - fi - - # 备份配置 - backup_config - - # 停止服务 - echo -n "停止 Xray 服务... " - if systemctl stop xray &>/dev/null; then - echo -e "${GREEN}成功${NC}" - else - echo -e "${RED}失败${NC}" - log_warn "无法停止 Xray 服务,将尝试继续更新" - fi - - # 下载新版本 - log_info "开始下载新版本" - - # 创建临时目录 - local tmp_dir="/tmp/xray_update" - mkdir -p "$tmp_dir" - - # 确定系统架构 - local arch - case $(uname -m) in - x86_64|amd64) arch="64" ;; - armv7l|armv8l) arch="arm32-v7a" ;; - aarch64) arch="arm64-v8a" ;; - *) arch="64" ;; # 默认使用64位版本 - esac - - # 构建下载URL - local download_url="https://github.com/XTLS/Xray-core/releases/download/$latest_version/Xray-linux-$arch.zip" - log_info "下载链接: $download_url" - - # 下载Xray - echo -n "下载 Xray... " - if wget -q --show-progress -O "$tmp_dir/xray.zip" "$download_url"; then - echo -e "${GREEN}成功${NC}" - else - echo -e "${RED}失败${NC}" - log_error "下载 Xray 失败" - read -rp "按回车键返回主菜单..." temp - show_menu - return 1 - fi - - # 解压文件 - echo -n "解压 Xray... " - if unzip -q -o "$tmp_dir/xray.zip" -d "$tmp_dir"; then - echo -e "${GREEN}成功${NC}" - else - echo -e "${RED}失败${NC}" - log_error "解压 Xray 失败" - read -rp "按回车键返回主菜单..." temp - show_menu - return 1 - fi - - # 备份旧的二进制文件 - mv "$XRAY_PATH/xray" "$XRAY_PATH/xray.old" 2>/dev/null - - # 复制新文件 - echo -n "更新 Xray 核心文件... " - if cp "$tmp_dir/xray" "$XRAY_PATH/xray" && chmod +x "$XRAY_PATH/xray"; then - echo -e "${GREEN}成功${NC}" - else - echo -e "${RED}失败${NC}" - log_error "更新 Xray 核心文件失败" - - # 恢复旧文件 - if [[ -f "$XRAY_PATH/xray.old" ]]; then - mv "$XRAY_PATH/xray.old" "$XRAY_PATH/xray" - log_warn "已恢复为旧版本" - fi - - read -rp "按回车键返回主菜单..." temp - show_menu - return 1 - fi - - # 更新 geoip.dat 和 geosite.dat - echo -n "更新 GeoIP 和 GeoSite 数据... " - if cp "$tmp_dir/geoip.dat" "$XRAY_PATH/geoip.dat" && \ - cp "$tmp_dir/geosite.dat" "$XRAY_PATH/geosite.dat"; then - echo -e "${GREEN}成功${NC}" - else - echo -e "${YELLOW}失败${NC}" - log_warn "更新 GeoIP 和 GeoSite 数据失败,但不影响核心功能" - fi - - # 删除旧备份和临时文件 - rm -f "$XRAY_PATH/xray.old" - rm -rf "$tmp_dir" - - # 启动服务 - echo -n "启动 Xray 服务... " - if systemctl start xray; then - echo -e "${GREEN}成功${NC}" - else - echo -e "${RED}失败${NC}" - log_error "启动 Xray 服务失败,请检查配置" - systemctl status xray - read -rp "按回车键返回主菜单..." temp - show_menu - return 1 - fi - - # 检查更新后的版本 - local new_version - new_version=$($XRAY_PATH/xray version | head -n 1 | cut -d ' ' -f 2) - - log_info "Xray 更新完成,版本: $new_version" - - read -rp "按回车键返回主菜单..." temp - show_menu -} - -# 更新脚本版本信息 -update_script_version() { - clear - echo "==================================================" - echo -e "${GREEN}更新脚本版本信息${NC}" - echo "==================================================" - - # 显示当前脚本版本 - echo "当前脚本版本: $SCRIPT_VERSION" - - # 获取最新脚本版本 - echo -n "获取最新脚本版本... " - local latest_version - latest_version=$(curl -s https://raw.githubusercontent.com/XTLS/Xray-core/main/xray-manager.sh | grep -o 'SCRIPT_VERSION="[^"]*"' | cut -d'"' -f2) - - if [[ -z "$latest_version" ]]; then - echo -e "${RED}失败${NC}" - log_error "无法获取最新脚本版本信息" - read -rp "是否继续更新? [y/N] " confirm - if [[ ! "$confirm" =~ ^[yY]$ ]]; then - log_info "更新已取消" - read -rp "按回车键返回主菜单..." temp - show_menu - return 0 - fi - latest_version="1.0.0" # 设置一个固定版本作为备用 - log_info "将使用固定版本: $latest_version" - else - echo -e "${GREEN}$latest_version${NC}" - - # 比较版本 - if [[ "$SCRIPT_VERSION" == "$latest_version" ]]; then - echo -e "${GREEN}已经是最新版本${NC}" - read -rp "是否强制更新? [y/N] " confirm - if [[ ! "$confirm" =~ ^[yY]$ ]]; then - log_info "更新已取消" - read -rp "按回车键返回主菜单..." temp - show_menu - return 0 - fi - fi - fi - - # 更新脚本版本 - echo -n "更新脚本版本... " - sed -i "s/SCRIPT_VERSION=\"[^\"]*\"/SCRIPT_VERSION=\"$latest_version\"/" "$0" - echo -e "${GREEN}成功${NC}" - - log_info "脚本版本已更新为 $latest_version" - - read -rp "按回车键返回主菜单..." temp - show_menu -} - -# 主函数 -main() { - # 处理命令行参数 - if [[ $# -gt 0 ]]; then - case "$1" in - -h|--help) - show_help - exit 0 - ;; - -i|--install) - check_root - install_xray - exit 0 - ;; - -u|--uninstall) - check_root - uninstall_xray - exit 0 - ;; - -s|--status) - check_root - check_status - exit 0 - ;; - -up|--update) - check_root - update_xray - exit 0 - ;; - *) - log_error "未知参数: $1" - show_help - exit 1 - ;; - esac - fi - - # 无参数则显示菜单 - check_root - show_menu -} - -# 执行主函数 -main "$@" \ No newline at end of file diff --git a/v2raya/v2raya.sh b/v2raya/v2raya.sh deleted file mode 100644 index 8662f6b..0000000 --- a/v2raya/v2raya.sh +++ /dev/null @@ -1,453 +0,0 @@ -#!/bin/bash -# V2rayA 自动安装/卸载脚本 -# 使用方法: chmod +x v2raya.sh && ./v2raya.sh -# curl -sS -O https://gitea.tohub.top/Share/vps/raw/branch/main/v2raya/v2raya.sh && chmod +x v2raya.sh && ./v2raya.sh - -# 彩色输出 -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[0;33m' -BLUE='\033[0;34m' -CYAN='\033[0;36m' -NC='\033[0m' # No Color - -# 配置变量 -INSTALL_DIR="/root/data/docker_data/v2raya" -BASE_URL="https://gitea.tohub.top/Share/vps/raw/branch/main/v2raya" -XRAY_VERSION="25.8.3" -V2RAYA_VERSION="2.2.7.4" - -# 默认账号信息 -DEFAULT_USER="admin@gmail.com" -DEFAULT_PASS="gmail.com" - -# 打印信息函数 -print_info() { - echo -e "${BLUE}[INFO]${NC} $1" -} - -print_success() { - echo -e "${GREEN}[SUCCESS]${NC} $1" -} - -print_warning() { - echo -e "${YELLOW}[WARNING]${NC} $1" -} - -print_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -# 检查是否以 root 权限运行 -check_root() { - if [[ $EUID -ne 0 ]]; then - print_error "此脚本需要 root 权限运行" - print_info "请使用: sudo $0" - exit 1 - fi -} - -# 检测系统架构 -detect_arch() { - local arch=$(dpkg --print-architecture) - if [[ "$arch" == "amd64" ]] || [[ "$arch" == "arm64" ]]; then - echo "$arch" - else - print_error "不支持的系统架构: $arch" - print_info "仅支持 amd64 和 arm64" - exit 1 - fi -} - -# 转换架构名称(用于 V2rayA 文件命名) -get_v2raya_arch() { - local arch=$1 - if [[ "$arch" == "amd64" ]]; then - echo "x64" - else - echo "$arch" - fi -} - -# 创建安装目录 -create_install_dir() { - if [[ ! -d "$INSTALL_DIR" ]]; then - print_info "创建安装目录: $INSTALL_DIR" - mkdir -p "$INSTALL_DIR" - if [[ $? -ne 0 ]]; then - print_error "创建目录失败" - exit 1 - fi - fi -} - -# 下载文件 -download_file() { - local url=$1 - local output=$2 - - print_info "正在下载: $url" - - # 如果存在旧的不完整文件,先删除 - if [[ -f "$output" ]]; then - rm -f "$output" - fi - - if command -v wget &> /dev/null; then - wget -q --show-progress "$url" -O "$output" - elif command -v curl &> /dev/null; then - curl -# -L "$url" -o "$output" - else - print_error "未找到 wget 或 curl,请先安装" - exit 1 - fi - - # 检查下载是否成功 - if [[ $? -eq 0 ]] && [[ -f "$output" ]] && [[ -s "$output" ]]; then - print_success "下载完成: $output" - return 0 - else - print_error "下载失败: $url" - rm -f "$output" - return 1 - fi -} - -# 下载安装包 -download_packages() { - local arch=$(detect_arch) - local v2raya_arch=$(get_v2raya_arch "$arch") - print_info "检测到系统架构: $arch" - - create_install_dir - - local xray_file="xray_${XRAY_VERSION}_${arch}.deb" - local v2raya_file="v2raya_${v2raya_arch}_${V2RAYA_VERSION}.deb" - local download_failed=0 - - # 下载 Xray - if [[ ! -f "$INSTALL_DIR/$xray_file" ]]; then - if ! download_file "$BASE_URL/$xray_file" "$INSTALL_DIR/$xray_file"; then - download_failed=1 - fi - else - print_warning "文件已存在,跳过下载: $xray_file" - fi - - # 下载 V2rayA - if [[ ! -f "$INSTALL_DIR/$v2raya_file" ]]; then - if ! download_file "$BASE_URL/$v2raya_file" "$INSTALL_DIR/$v2raya_file"; then - download_failed=1 - fi - else - print_warning "文件已存在,跳过下载: $v2raya_file" - fi - - return $download_failed -} - -# 验证文件是否有效 -verify_deb_file() { - local file=$1 - - if [[ ! -f "$file" ]]; then - return 1 - fi - - if [[ ! -s "$file" ]]; then - print_warning "文件为空: $file" - return 1 - fi - - # 检查 file 命令是否存在 - if command -v file &> /dev/null; then - if ! file "$file" | grep -q "Debian"; then - print_warning "文件不是有效的 deb 包: $file" - return 1 - fi - else - # 如果没有 file 命令,简单检查文件扩展名和大小 - if [[ ! "$file" =~ \.deb$ ]]; then - print_warning "文件扩展名不正确: $file" - return 1 - fi - # 检查文件大小是否合理(至少 1KB) - local size=$(stat -c%s "$file" 2>/dev/null || stat -f%z "$file" 2>/dev/null) - if [[ $size -lt 1024 ]]; then - print_warning "文件大小异常: $file (${size} bytes)" - return 1 - fi - fi - - return 0 -} - -# 安装 V2rayA -install_v2raya() { - local arch=$(detect_arch) - local v2raya_arch=$(get_v2raya_arch "$arch") - local xray_file="$INSTALL_DIR/xray_${XRAY_VERSION}_${arch}.deb" - local v2raya_file="$INSTALL_DIR/v2raya_${v2raya_arch}_${V2RAYA_VERSION}.deb" - - # 检查文件是否存在 - if [[ ! -f "$xray_file" ]] || [[ ! -f "$v2raya_file" ]]; then - print_warning "安装包不存在,开始下载..." - if ! download_packages; then - print_error "下载失败,无法继续安装" - print_info "请检查网络连接或下载地址是否正确" - return 1 - fi - fi - - # 验证文件完整性 - print_info "验证安装包完整性..." - if ! verify_deb_file "$xray_file"; then - print_error "Xray 安装包验证失败,请重新下载" - rm -f "$xray_file" - return 1 - fi - - if ! verify_deb_file "$v2raya_file"; then - print_error "V2rayA 安装包验证失败,请重新下载" - rm -f "$v2raya_file" - return 1 - fi - print_success "安装包验证通过" - - print_info "开始安装 Xray..." - chmod 644 "$xray_file" - if dpkg -i "$xray_file" 2>&1 | tee /tmp/xray_install.log; then - apt --fix-broken install -y - print_success "Xray 安装成功" - else - print_error "Xray 安装失败" - print_info "错误日志已保存到: /tmp/xray_install.log" - return 1 - fi - - print_info "开始安装 V2rayA..." - chmod 644 "$v2raya_file" - if dpkg -i "$v2raya_file" 2>&1 | tee /tmp/v2raya_install.log; then - apt --fix-broken install -y - print_success "V2rayA 安装成功" - else - print_error "V2rayA 安装失败" - print_info "错误日志已保存到: /tmp/v2raya_install.log" - return 1 - fi - - # 启动服务 - print_info "启动 V2rayA 服务..." - systemctl start v2raya.service - - if [[ $? -eq 0 ]]; then - print_success "V2rayA 服务启动成功" - else - print_error "V2rayA 服务启动失败" - print_info "请运行 'systemctl status v2raya.service' 查看详情" - return 1 - fi - - # 设置开机自启 - print_info "设置开机自启..." - systemctl enable v2raya.service - print_success "已设置开机自启" - - # 配置防火墙 - echo "" - print_info "配置防火墙规则..." - if command -v ufw &> /dev/null; then - ufw allow 2017 >/dev/null 2>&1 - print_success "已开放端口 2017" - print_info "防火墙状态:" - ufw status | grep -E "Status:|2017" | sed 's/^/ /' - else - print_warning "未检测到 ufw 防火墙,请手动配置防火墙规则" - fi - - # 显示登录信息 - echo "" - print_success "============================================" - print_success "V2rayA 安装完成!" - print_success "============================================" - print_info "访问地址: http://localhost:2017" - print_info "默认账号: ${CYAN}$DEFAULT_USER${NC}" - print_info "默认密码: ${CYAN}$DEFAULT_PASS${NC}" - print_success "============================================" - echo "" -} - -# 卸载 V2rayA -uninstall_v2raya() { - local arch=$(detect_arch) - local v2raya_arch=$(get_v2raya_arch "$arch") - local xray_file="$INSTALL_DIR/xray_${XRAY_VERSION}_${arch}.deb" - local v2raya_file="$INSTALL_DIR/v2raya_${v2raya_arch}_${V2RAYA_VERSION}.deb" - - print_warning "即将卸载 V2rayA 和 Xray" - read -p "是否继续?[y/N] " -n 1 -r - echo - - if [[ ! $REPLY =~ ^[Yy]$ ]]; then - print_info "已取消卸载" - return - fi - - # 停止服务 - print_info "停止 V2rayA 服务..." - systemctl stop v2raya.service 2>/dev/null - - # 禁用开机自启 - print_info "禁用开机自启..." - systemctl disable v2raya.service 2>/dev/null - - # 卸载软件包 - print_info "卸载 V2rayA..." - apt remove v2raya -y 2>/dev/null - - print_info "卸载 Xray..." - apt remove xray -y 2>/dev/null - - # 清理依赖 - print_info "清理不需要的依赖..." - apt autoremove -y - - # 询问是否删除配置文件 - read -p "是否删除配置文件?[y/N] " -n 1 -r - echo - - if [[ $REPLY =~ ^[Yy]$ ]]; then - print_info "删除配置文件..." - rm -rf /etc/v2raya 2>/dev/null - apt purge xray v2raya -y 2>/dev/null - fi - - # 自动删除安装包目录 - echo "" - print_info "清理安装包目录: $INSTALL_DIR" - if [[ -d "$INSTALL_DIR" ]]; then - rm -rf "$INSTALL_DIR" - print_success "已删除: $INSTALL_DIR" - else - print_warning "目录不存在: $INSTALL_DIR" - fi - - # 验证卸载 - echo "" - if dpkg -l | grep -E 'v2raya|xray' &> /dev/null; then - print_warning "部分组件可能未完全卸载" - dpkg -l | grep -E 'v2raya|xray' - else - print_success "V2rayA 和 Xray 已完全卸载" - fi -} - -# 检查安装状态 -check_status() { - local arch=$(detect_arch) - local v2raya_arch=$(get_v2raya_arch "$arch") - local xray_file="$INSTALL_DIR/xray_${XRAY_VERSION}_${arch}.deb" - local v2raya_file="$INSTALL_DIR/v2raya_${v2raya_arch}_${V2RAYA_VERSION}.deb" - - echo "" - print_info "============================================" - print_info "检查 V2rayA 状态" - print_info "============================================" - - # 检查软件安装状态 - if dpkg -l | grep -q v2raya; then - print_success "V2rayA 已安装" - - if systemctl is-active --quiet v2raya.service; then - print_success "V2rayA 服务运行中" - else - print_warning "V2rayA 服务未运行" - fi - - if systemctl is-enabled --quiet v2raya.service; then - print_success "开机自启已启用" - else - print_warning "开机自启未启用" - fi - else - print_warning "V2rayA 未安装" - fi - - if dpkg -l | grep -q xray; then - print_success "Xray 已安装" - else - print_warning "Xray 未安装" - fi - - # 检查安装包状态 - echo "" - print_info "安装包状态:" - if [[ -f "$xray_file" ]]; then - local size=$(du -h "$xray_file" | cut -f1) - print_info " Xray: ${CYAN}已下载${NC} (${size})" - else - print_warning " Xray: 未下载" - fi - - if [[ -f "$v2raya_file" ]]; then - local size=$(du -h "$v2raya_file" | cut -f1) - print_info " V2rayA: ${CYAN}已下载${NC} (${size})" - else - print_warning " V2rayA: 未下载" - fi - - print_info "============================================" - echo "" -} - -# 主菜单 -show_menu() { - clear - echo -e "${CYAN}" - echo "============================================" - echo " V2rayA 自动安装/卸载脚本" - echo "============================================" - echo -e "${NC}" - echo -e "${GREEN}1.${NC} 安装 V2rayA" - echo -e "${GREEN}2.${NC} 卸载 V2rayA" - echo -e "${GREEN}3.${NC} 检查状态" - echo -e "${GREEN}0.${NC} 退出" - echo "" - echo -e "${CYAN}============================================${NC}" -} - -# 主程序 -main() { - check_root - - while true; do - show_menu - read -p "请选择操作 [0-3]: " choice - - case $choice in - 1) - install_v2raya - read -p "按任意键继续..." -n 1 - ;; - 2) - uninstall_v2raya - read -p "按任意键继续..." -n 1 - ;; - 3) - check_status - read -p "按任意键继续..." -n 1 - ;; - 0) - print_info "退出脚本" - exit 0 - ;; - *) - print_error "无效的选择,请重新输入" - sleep 2 - ;; - esac - done -} - -# 运行主程序 -main \ No newline at end of file diff --git a/v2raya/v2raya_arm64_2.2.7.4.deb b/v2raya/v2raya_arm64_2.2.7.4.deb deleted file mode 100644 index d3a7d17..0000000 Binary files a/v2raya/v2raya_arm64_2.2.7.4.deb and /dev/null differ diff --git a/v2raya/v2raya_x64_2.2.7.4.deb b/v2raya/v2raya_x64_2.2.7.4.deb deleted file mode 100644 index 6669ada..0000000 Binary files a/v2raya/v2raya_x64_2.2.7.4.deb and /dev/null differ diff --git a/v2raya/v2raya_x86_2.2.7.4.deb b/v2raya/v2raya_x86_2.2.7.4.deb deleted file mode 100644 index 658da4f..0000000 Binary files a/v2raya/v2raya_x86_2.2.7.4.deb and /dev/null differ diff --git a/v2raya/xray_25.8.3_amd64.deb b/v2raya/xray_25.8.3_amd64.deb deleted file mode 100644 index c950603..0000000 Binary files a/v2raya/xray_25.8.3_amd64.deb and /dev/null differ diff --git a/v2raya/xray_25.8.3_arm64.deb b/v2raya/xray_25.8.3_arm64.deb deleted file mode 100644 index a173758..0000000 Binary files a/v2raya/xray_25.8.3_arm64.deb and /dev/null differ