|
| 1 | +#!/bin/bash |
| 2 | + |
| 3 | +# Hiddify Core Universal Installer |
| 4 | +# Supports OpenWrt, Ubuntu, Debian, CentOS, and other Linux distributions. |
| 5 | + |
| 6 | +set -e |
| 7 | + |
| 8 | +RED='\033[0;31m' |
| 9 | +GREEN='\033[0;32m' |
| 10 | +BLUE='\033[0;34m' |
| 11 | +NC='\033[0m' |
| 12 | + |
| 13 | +echo -e "${BLUE}Hiddify Core Universal Installer${NC}" |
| 14 | + |
| 15 | +# Check for root |
| 16 | +if [ "$EUID" -ne 0 ]; then |
| 17 | + echo -e "${RED}Please run as root${NC}" |
| 18 | + exit 1 |
| 19 | +fi |
| 20 | + |
| 21 | +# Detect OS |
| 22 | +OS="linux" |
| 23 | +if [ -f /etc/openwrt_release ]; then |
| 24 | + OS="openwrt" |
| 25 | + echo -e "Detected OS: ${GREEN}OpenWrt${NC}" |
| 26 | +elif [ -f /etc/os-release ]; then |
| 27 | + . /etc/os-release |
| 28 | + OS_NAME=$ID |
| 29 | + echo -e "Detected OS: ${GREEN}$OS_NAME${NC}" |
| 30 | +else |
| 31 | + echo -e "Detected OS: ${GREEN}Generic Linux${NC}" |
| 32 | +fi |
| 33 | + |
| 34 | +# Detect Architecture |
| 35 | +ARCH_RAW=$(uname -m) |
| 36 | +case "$ARCH_RAW" in |
| 37 | + x86_64) ARCH="amd64" ;; |
| 38 | + i386|i686) ARCH="386" ;; |
| 39 | + aarch64) ARCH="arm64" ;; |
| 40 | + armv7*) ARCH="armv7" ;; |
| 41 | + armv6*) ARCH="armv6" ;; |
| 42 | + armv5*) ARCH="armv5" ;; |
| 43 | + mips64el) ARCH="mips64le" ;; |
| 44 | + mips64) ARCH="mips64" ;; |
| 45 | + mipsel) ARCH="mipsle" ;; |
| 46 | + mips) ARCH="mips" ;; |
| 47 | + riscv64) ARCH="riscv64" ;; |
| 48 | + ppc64le) ARCH="ppc64le" ;; |
| 49 | + s390x) ARCH="s390x" ;; |
| 50 | + *) echo -e "${RED}Unsupported architecture: $ARCH_RAW${NC}"; exit 1 ;; |
| 51 | +esac |
| 52 | + |
| 53 | +# Check for libc type (glibc vs musl) for Linux |
| 54 | +LIBC="" |
| 55 | +if [ "$OS" != "openwrt" ]; then |
| 56 | + if ldd --version 2>&1 | grep -iq musl; then |
| 57 | + LIBC="-musl" |
| 58 | + elif ldd --version 2>&1 | grep -iq glibc; then |
| 59 | + LIBC="-glibc" |
| 60 | + fi |
| 61 | +fi |
| 62 | + |
| 63 | +# Determine artifact name |
| 64 | +# Note: For OpenWrt, we usually prefer generic or musl. |
| 65 | +# For standard Linux, we use the specific libc variant if available, otherwise generic. |
| 66 | +ARTIFACT="hiddify-core-linux-${ARCH}${LIBC}.tar.gz" |
| 67 | + |
| 68 | +# Fetch latest version |
| 69 | +echo -e "Fetching latest version information..." |
| 70 | +REPO="hiddify/hiddify-core" |
| 71 | +LATEST_TAG=$(curl -s "https://api.github.com/repos/$REPO/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') |
| 72 | + |
| 73 | +if [ -z "$LATEST_TAG" ]; then |
| 74 | + echo -e "${RED}Failed to fetch latest version tag. Attempting fallback...${NC}" |
| 75 | + LATEST_TAG="v4.0.4" # Fallback |
| 76 | +fi |
| 77 | + |
| 78 | +DOWNLOAD_URL="https://github.com/$REPO/releases/download/$LATEST_TAG/$ARTIFACT" |
| 79 | + |
| 80 | +echo -e "Downloading ${BLUE}$ARTIFACT${NC} ($LATEST_TAG)..." |
| 81 | +WORKDIR=$(mktemp -d) |
| 82 | +curl -L "$DOWNLOAD_URL" -o "$WORKDIR/$ARTIFACT" || { |
| 83 | + # If specific libc variant fails, try generic |
| 84 | + if [ -n "$LIBC" ]; then |
| 85 | + echo -e "Libc-specific artifact not found, trying generic..." |
| 86 | + ARTIFACT="hiddify-core-linux-${ARCH}.tar.gz" |
| 87 | + DOWNLOAD_URL="https://github.com/$REPO/releases/download/$LATEST_TAG/$ARTIFACT" |
| 88 | + curl -L "$DOWNLOAD_URL" -o "$WORKDIR/$ARTIFACT" |
| 89 | + fi |
| 90 | +} |
| 91 | + |
| 92 | +# Install Binary |
| 93 | +echo -e "Installing binary to /usr/bin/hiddify-core..." |
| 94 | +tar -zxf "$WORKDIR/$ARTIFACT" -C "$WORKDIR" |
| 95 | +# Find the binary in the tarball (it might be in a subdir or renamed) |
| 96 | +BIN_PATH=$(find "$WORKDIR" -type f -name "hiddify*" -executable | head -n 1) |
| 97 | +mv "$BIN_PATH" /usr/bin/hiddify-core |
| 98 | +chmod +x /usr/bin/hiddify-core |
| 99 | + |
| 100 | +# Setup Config |
| 101 | +mkdir -p /etc/hiddify-core |
| 102 | +if [ ! -f /etc/hiddify-core/config.json ]; then |
| 103 | + echo -e "Creating default configuration..." |
| 104 | + cat <<EOF > /etc/hiddify-core/config.json |
| 105 | +{ |
| 106 | + "log": { "level": "info" }, |
| 107 | + "dns": { "servers": [{ "address": "tls://8.8.8.8" }] }, |
| 108 | + "inbounds": [{ "type": "shadowsocks", "listen": "::", "listen_port": 8080, "network": "tcp", "method": "2022-blake3-aes-128-gcm", "password": "Gn1JUS14bLUHgv1cWDDp4A==", "multiplex": { "enabled": true, "padding": true } }], |
| 109 | + "outbounds": [{ "type": "direct" }, { "type": "dns", "tag": "dns-out" }], |
| 110 | + "route": { "rules": [{ "port": 53, "outbound": "dns-out" }] } |
| 111 | +} |
| 112 | +EOF |
| 113 | +fi |
| 114 | + |
| 115 | +# Service Configuration |
| 116 | +if [ "$OS" = "openwrt" ]; then |
| 117 | + echo -e "Configuring ${GREEN}OpenWrt procd${NC} service..." |
| 118 | + |
| 119 | + # UCI Config |
| 120 | + if [ ! -f /etc/config/hiddify-core ]; then |
| 121 | + cat <<EOF > /etc/config/hiddify-core |
| 122 | +config hiddify-core 'main' |
| 123 | + option enabled '1' |
| 124 | + option conffile '/etc/hiddify-core/config.json' |
| 125 | + option workdir '/usr/share/hiddify-core' |
| 126 | + option log_stderr '1' |
| 127 | +EOF |
| 128 | + fi |
| 129 | + |
| 130 | + # Init Script |
| 131 | + cat <<'EOF' > /etc/init.d/hiddify-core |
| 132 | +#!/bin/sh /etc/rc.common |
| 133 | +USE_PROCD=1 |
| 134 | +START=99 |
| 135 | +PROG="/usr/bin/hiddify-core" |
| 136 | +start_service() { |
| 137 | + config_load "hiddify-core" |
| 138 | + local enabled conffile workdir log_stderr |
| 139 | + config_get_bool enabled "main" "enabled" "0" |
| 140 | + [ "$enabled" -eq "1" ] || return 0 |
| 141 | + config_get conffile "main" "conffile" "/etc/hiddify-core/config.json" |
| 142 | + config_get workdir "main" "workdir" "/usr/share/hiddify-core" |
| 143 | + config_get_bool log_stderr "main" "log_stderr" "1" |
| 144 | + mkdir -p "$workdir" |
| 145 | + procd_open_instance |
| 146 | + procd_set_param command "$PROG" run -c "$conffile" -D "$workdir" |
| 147 | + procd_set_param file "$conffile" |
| 148 | + procd_set_param stderr "$log_stderr" |
| 149 | + procd_set_param respawn |
| 150 | + procd_close_instance |
| 151 | +} |
| 152 | +EOF |
| 153 | + chmod +x /etc/init.d/hiddify-core |
| 154 | + /etc/init.d/hiddify-core enable |
| 155 | + /etc/init.d/hiddify-core restart |
| 156 | + |
| 157 | +else |
| 158 | + echo -e "Configuring ${GREEN}systemd${NC} service..." |
| 159 | + |
| 160 | + # Systemd Service |
| 161 | + cat <<EOF > /etc/systemd/system/hiddify-core.service |
| 162 | +[Unit] |
| 163 | +Description=hiddify-core service |
| 164 | +After=network.target nss-lookup.target network-online.target |
| 165 | +
|
| 166 | +[Service] |
| 167 | +Type=simple |
| 168 | +ExecStart=/usr/bin/hiddify-core -D /var/lib/hiddify-core run -c /etc/hiddify-core/config.json |
| 169 | +Restart=on-failure |
| 170 | +RestartSec=10s |
| 171 | +LimitNOFILE=infinity |
| 172 | +
|
| 173 | +[Install] |
| 174 | +WantedBy=multi-user.target |
| 175 | +EOF |
| 176 | + |
| 177 | + mkdir -p /var/lib/hiddify-core |
| 178 | + systemctl daemon-reload |
| 179 | + systemctl enable hiddify-core |
| 180 | + systemctl restart hiddify-core |
| 181 | +fi |
| 182 | + |
| 183 | +echo -e "${GREEN}Installation successful!${NC}" |
| 184 | +echo -e "Binary: /usr/bin/hiddify-core" |
| 185 | +echo -e "Config: /etc/hiddify-core/config.json" |
| 186 | +if [ "$OS" = "openwrt" ]; then |
| 187 | + echo -e "Service: /etc/init.d/hiddify-core" |
| 188 | +else |
| 189 | + echo -e "Service: systemctl status hiddify-core" |
| 190 | +fi |
| 191 | + |
| 192 | +rm -rf "$WORKDIR" |
0 commit comments