#!/bin/bash # mihomo 安装脚本 # 作者: su # 版本: v1.0.0 # 日期: 2024年11月14日 set -e -o pipefail # 定义颜色 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' # 无颜色 # 检测系统类型和架构 detect_system() { if [ -f /etc/alpine-release ]; then SYSTEM_TYPE="Alpine" elif command -v systemctl > /dev/null; then SYSTEM_TYPE="Debian" elif [ -f /etc/openwrt_release ]; then SYSTEM_TYPE="OpenWrt" elif [ -d /etc/init.d ]; then SYSTEM_TYPE="Init.d" else echo "不支持的初始化系统" exit 1 fi ARCH_RAW=$(uname -m) case "${ARCH_RAW}" in 'x86_64') ARCH='amd64';; 'x86' | 'i686' | 'i386') ARCH='386';; 'aarch64' | 'arm64') ARCH='arm64';; 'armv7l') ARCH='armv7';; 's390x') ARCH='s390x';; *) echo "Unsupported architecture: ${ARCH_RAW}"; exit 1;; esac if [ "$SYSTEM_TYPE" == "Debian" ]; then SYSTEM_VERSION=$(cat /etc/os-release | grep VERSION_ID | cut -d'=' -f2 | tr -d '"') elif [ "$SYSTEM_TYPE" == "Alpine" ]; then SYSTEM_VERSION=$(cat /etc/alpine-release) elif [ "$SYSTEM_TYPE" == "OpenWrt" ]; then SYSTEM_VERSION=$(cat /etc/openwrt_release | grep DISTRIB_RELEASE | cut -d'=' -f2) else SYSTEM_VERSION="Unknown" fi echo -e "${GREEN}当前系统为 ${SYSTEM_TYPE}-${SYSTEM_VERSION}_${ARCH_RAW}${NC}" } # 设置时区 set_timezone() { if [ "$SYSTEM_TYPE" == "Alpine" ]; then echo -e "${YELLOW}检测到 Alpine 系统,使用 cp 和 echo 设置时区${NC}" apk add --no-cache tzdata cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime echo "Asia/Shanghai" > /etc/timezone apk del tzdata else CURRENT_TIMEZONE=$(timedatectl show --property=Timezone --value) if [ "$CURRENT_TIMEZONE" != "Asia/Shanghai" ]; then echo -e "${YELLOW}设置时区为Asia/Shanghai${NC}" timedatectl set-timezone Asia/Shanghai fi fi } # 安装必要软件 install_software() { if [ "$SYSTEM_TYPE" == "Alpine" ]; then echo -e "${YELLOW}正在安装必要软件${NC}" apk add --no-cache curl nano grep gzip else echo -e "${YELLOW}正在安装必要软件${NC}" if command -v apt-get > /dev/null; then apt-get update apt-get install -y curl nano gzip elif command -v yum > /dev/null; then yum install -y curl nano gzip else echo -e "${RED}不支持的包管理器${NC}" exit 1 fi fi } # 检测并下载 mihomo 版本 download_mihomo() { VERSION=$(curl -sL "https://gh.llkk.cc/https://api.github.com/repos/MetaCubeX/mihomo/releases/latest" | grep -oP '"tag_name": "\K(.*)(?=")') if [ -z "$VERSION" ]; then echo -e "${RED}无法获取最新版本号${NC}" exit 1 fi echo -e "${GREEN}获取到的版本: ${VERSION}${NC}" DOWNLOAD_URL="https://gh.llkk.cc/https://github.com/MetaCubeX/mihomo/releases/download/${VERSION}/mihomo-linux-${ARCH}-${VERSION}.gz" echo "从 ${DOWNLOAD_URL} 下载 mihomo" curl -Lo mihomo.gz "${DOWNLOAD_URL}" echo -e "${YELLOW}Mihomo ${VERSION} 下载完成, 开始安装${NC}" gzip -d mihomo.gz chmod +x mihomo mv mihomo /usr/local/bin/ } # 删除已有服务 remove_existing_service() { if [ -f /etc/systemd/system/mihomo.service ] || [ -f /etc/init.d/mihomo ] || [ -f /etc/rc.d/mihomo ]; then read -p "检测到已有的 mihomo 服务,是否删除?(y/n): " choice case "$choice" in y|Y ) if [ -f /etc/systemd/system/mihomo.service ]; then systemctl stop mihomo systemctl disable mihomo rm -f /etc/systemd/system/mihomo.service systemctl daemon-reload fi if [ -f /etc/init.d/mihomo ]; then /etc/init.d/mihomo stop rm -f /etc/init.d/mihomo fi if [ -f /etc/rc.d/mihomo ]; then /etc/rc.d/mihomo stop rm -f /etc/rc.d/mihomo fi ;; n|N ) echo -e "${YELLOW}保留已有的 mihomo 服务,退出安装。${NC}" exit 0 ;; * ) echo -e "${RED}无效的选择,退出安装。${NC}" exit 1 ;; esac fi } # 配置 OpenRC 服务,Alpine 专用 configure_openrc() { echo "创建 OpenRC 服务文件" cat < /etc/init.d/mihomo #!/sbin/openrc-run command="/usr/local/bin/mihomo" command_args="-d /etc/mihomo" command_background=true pidfile="/var/run/mihomo.pid" name="Mihomo Service" depend() { need net } start_pre() { ebegin "等待 1 秒" sleep 1 eend \$? } EOF chmod +x /etc/init.d/mihomo rc-update add mihomo default rc-service mihomo start } # 配置 systemd 服务,Debian系 专用 configure_systemd() { echo "创建 systemd 服务文件" cat < /etc/systemd/system/mihomo.service [Unit] Description=mihomo Daemon, Another Clash Kernel. After=network.target NetworkManager.service systemd-networkd.service iwd.service [Service] Type=simple LimitNPROC=500 LimitNOFILE=1000000 CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE CAP_SYS_TIME CAP_SYS_PTRACE CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE AmbientCapabilities=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE CAP_SYS_TIME CAP_SYS_PTRACE CAP_DAC_READ_SEARCH CAP_DAC_OVERRIDE Restart=always ExecStartPre=/usr/bin/sleep 1s ExecStart=/usr/local/bin/mihomo -d /etc/mihomo ExecReload=/bin/kill -HUP \$MAINPID [Install] WantedBy=multi-user.target EOF systemctl daemon-reload systemctl start mihomo systemctl enable mihomo } # 配置 init.d 服务,OpenWrt 和 Init.d 专用 configure_initd() { echo "创建 init.d 服务文件" cat < /etc/init.d/mihomo #!/bin/sh ### BEGIN INIT INFO # Provides: mihomo # Required-Start: \$network # Required-Stop: \$network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Mihomo Service ### END INIT INFO start() { echo "Starting mihomo" /usr/bin/sleep 1 /usr/local/bin/mihomo -d /etc/mihomo & } stop() { echo "Stopping mihomo" pkill -f /usr/local/bin/mihomo } restart() { stop start } case "\$1" in start) start ;; stop) stop ;; restart) restart ;; *) echo "Usage: /etc/init.d/mihomo {start|stop|restart}" exit 1 ;; esac exit 0 EOF chmod +x /etc/init.d/mihomo update-rc.d mihomo defaults /etc/init.d/mihomo start } # 内置配置 BUILTIN_CONFIG=$(cat < /etc/mihomo/config.yaml ;; n|N ) echo -e "${YELLOW}不使用内置配置,请上传配置到/etc/mihomo/config.yaml${NC}" ;; * ) echo -e "${RED}无效的选择,退出安装。${NC}" exit 1 ;; esac } # 启用系统转发 enable_ip_forwarding() { echo 'net.ipv4.ip_forward = 1' | tee -a /etc/sysctl.conf echo 'net.ipv6.conf.all.forwarding = 1' | tee -a /etc/sysctl.conf sysctl -p if [ "$SYSTEM_TYPE" == "Alpine" ]; then rc-update add sysctl fi } # 主函数 main() { detect_system set_timezone install_software remove_existing_service download_mihomo ask_builtin_config # enable_ip_forwarding case "$SYSTEM_TYPE" in "Alpine") configure_openrc ;; "Debian") configure_systemd ;; "OpenWrt" | "Init.d") configure_initd ;; esac echo -e "${GREEN}脚本执行完毕。${NC}" } main