#!/bin/bash #======================================== # OpenClash 自动安装脚本 # 版本: 1.0 # 作者: Assistant # 说明: 自动安装 OpenClash 及其依赖 #======================================== # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # 版本定义 OPENCLASH_VERSION="0.47.001" OPENCLASH_URL="https://github.com/vernesong/OpenClash/releases/download/v${OPENCLASH_VERSION}/luci-app-openclash_${OPENCLASH_VERSION}_all.ipk" # 日志函数 log_info() { echo -e "${GREEN}[INFO]${NC} $1" } log_error() { echo -e "${RED}[ERROR]${NC} $1" } log_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } # 检查root权限 check_root() { if [ $(id -u) != "0" ]; then log_error "请使用 root 权限运行此脚本" exit 1 fi } # 检查网络连接 check_network() { log_info "检查网络连接..." if ! ping -c 1 -W 2 github.com > /dev/null 2>&1; then log_error "无法连接到 GitHub,请检查网络连接" exit 1 fi log_info "网络连接正常" } # 检查存储空间 check_storage() { log_info "检查存储空间..." AVAILABLE=$(df /tmp | awk 'NR==2 {print $4}') if [ "$AVAILABLE" -lt 10240 ]; then log_warn "/tmp 可用空间不足 10MB,可能会导致安装失败" read -p "是否继续?(y/n): " -n 1 -r echo if [[ ! $REPLY =~ ^[Yy]$ ]]; then exit 1 fi fi log_info "存储空间检查通过" } # 更新软件包列表 update_packages() { log_info "更新软件包列表..." if ! opkg update > /dev/null 2>&1; then log_error "更新软件包列表失败" exit 1 fi log_info "软件包列表更新完成" } # 安装依赖包 install_dependencies() { log_info "开始安装依赖包..." # 依赖包列表 DEPENDENCIES=( "luci" "luci-base" "iptables" "dnsmasq-full" "coreutils" "coreutils-nohup" "bash" "curl" "jsonfilter" "ca-certificates" "ipset" "ip-full" "iptables-mod-tproxy" "kmod-tun" "luci-compat" ) # 逐个安装依赖 for pkg in "${DEPENDENCIES[@]}"; do if opkg list-installed | grep -q "^$pkg "; then log_info "$pkg 已安装,跳过" else log_info "正在安装 $pkg..." if ! opkg install "$pkg" > /dev/null 2>&1; then log_warn "$pkg 安装失败,尝试强制安装..." opkg install "$pkg" --force-depends > /dev/null 2>&1 fi fi done log_info "依赖包安装完成" } # 下载 OpenClash download_openclash() { log_info "开始下载 OpenClash v${OPENCLASH_VERSION}..." # 切换到 /tmp 目录 cd /tmp # 删除旧的安装包(如果存在) rm -f luci-app-openclash*.ipk # 下载安装包 if command -v wget > /dev/null 2>&1; then wget -q --show-progress "$OPENCLASH_URL" -O "luci-app-openclash_${OPENCLASH_VERSION}_all.ipk" elif command -v curl > /dev/null 2>&1; then curl -L -# "$OPENCLASH_URL" -o "luci-app-openclash_${OPENCLASH_VERSION}_all.ipk" else log_error "wget 和 curl 都不可用,无法下载" exit 1 fi if [ ! -f "luci-app-openclash_${OPENCLASH_VERSION}_all.ipk" ]; then log_error "下载失败,请检查网络或版本号" exit 1 fi log_info "OpenClash 下载完成" } # 安装 OpenClash install_openclash() { log_info "开始安装 OpenClash..." # 检查是否已安装 if opkg list-installed | grep -q "luci-app-openclash"; then log_warn "检测到已安装 OpenClash,将进行升级" opkg remove luci-app-openclash > /dev/null 2>&1 fi # 安装 if opkg install "/tmp/luci-app-openclash_${OPENCLASH_VERSION}_all.ipk" > /dev/null 2>&1; then log_info "OpenClash 安装成功" else log_warn "正常安装失败,尝试强制安装..." if opkg install "/tmp/luci-app-openclash_${OPENCLASH_VERSION}_all.ipk" --force-depends > /dev/null 2>&1; then log_info "OpenClash 强制安装成功" else log_error "OpenClash 安装失败" exit 1 fi fi } # 下载内核(可选) download_core() { log_info "是否需要自动下载 Clash 内核?" read -p "下载内核?(y/n): " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then log_info "检测系统架构..." ARCH=$(uname -m) case "$ARCH" in x86_64|amd64) CORE_URL="https://github.com/vernesong/OpenClash/releases/download/Clash/clash-linux-amd64.tar.gz" ;; aarch64|arm64) CORE_URL="https://github.com/vernesong/OpenClash/releases/download/Clash/clash-linux-arm64.tar.gz" ;; armv7l|armv7) CORE_URL="https://github.com/vernesong/OpenClash/releases/download/Clash/clash-linux-armv7.tar.gz" ;; *) log_warn "未识别的架构: $ARCH,请手动下载内核" return ;; esac log_info "下载对应架构 ($ARCH) 的内核..." mkdir -p /etc/openclash/core cd /etc/openclash/core if command -v wget > /dev/null 2>&1; then wget -q --show-progress "$CORE_URL" -O clash.tar.gz else curl -L -# "$CORE_URL" -o clash.tar.gz fi if [ -f clash.tar.gz ]; then tar -xzf clash.tar.gz chmod +x clash* 2>/dev/null rm -f clash.tar.gz log_info "内核下载并安装完成" else log_error "内核下载失败" fi fi } # 清理临时文件 cleanup() { log_info "清理临时文件..." rm -f /tmp/luci-app-openclash*.ipk } # 完成提示 finish() { echo log_info "===========================================" log_info "安装完成!" log_info "===========================================" echo # 检查安装的组件 if opkg list-installed | grep -q "luci-app-openclash"; then log_info "OpenClash 已安装:" echo -e "${YELLOW} 路径: 服务 -> OpenClash${NC}" fi if opkg list-installed | grep -q "luci-app-frpc"; then log_info "FRP 客户端已安装:" echo -e "${YELLOW} 路径: 服务 -> FRP 内网穿透${NC}" fi echo log_info "请执行以下操作:" echo -e "${YELLOW}1. 刷新 LuCI 页面${NC}" echo -e "${YELLOW}2. 配置相应的服务${NC}" echo log_info "卸载命令:" echo -e "${YELLOW} OpenClash: opkg remove luci-app-openclash${NC}" echo -e "${YELLOW} FRP: opkg remove luci-app-frpc${NC}" echo } # 主函数 main() { echo echo -e "${BLUE}==========================================" echo -e " OpenClash + FRP 自动安装脚本 v1.1" echo -e "==========================================${NC}" echo # 执行安装步骤 check_root check_network check_storage update_packages install_dependencies download_openclash install_openclash download_core install_frpc cleanup finish } # 捕获错误 trap 'log_error "脚本执行失败"; exit 1' ERR # 执行主函数 main