mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-02 22:53:56 +08:00
🎁 Sync 2026-07-31 00:21:49
This commit is contained in:
1 parent
f6c3fbbbbe
commit
c71b32c9fb
204 files changed
+187145
-10038
No files matched your search
@@ -0,0 +1,220 @@
|
||||
#!/bin/sh
|
||||
# Установщик Re:HomeProxy для OpenWrt (в одном скрипте: APK / opkg / 23.05 legacy)
|
||||
# https://github.com/1andrevich/homeproxy-hiddify
|
||||
#
|
||||
# Вручную ставится только LuCI-приложение + ключ подписи, а ядро, ByeDPI и Zapret
|
||||
# устанавливаются через собственный бэкенд приложения (core_mgmt.uc + rpcd-объект
|
||||
# luci.homeproxy) — поэтому определение архитектуры, компактные сборки под малую
|
||||
# флеш-память, проверка подписи и резерв через зеркало GitHub работают той же
|
||||
# проверенной логикой, что и графический интерфейс.
|
||||
#
|
||||
# Установка (одной строкой — ввод читается из /dev/tty, пайп остаётся интерактивным):
|
||||
# wget -qO- https://raw.githubusercontent.com/1andrevich/homeproxy-hiddify/master/install.sh | sh
|
||||
# Либо в два шага:
|
||||
# wget -O /tmp/install.sh https://raw.githubusercontent.com/1andrevich/homeproxy-hiddify/master/install.sh
|
||||
# sh /tmp/install.sh
|
||||
#
|
||||
# При заблокированном/замедленном GitHub можно указать зеркало:
|
||||
# GH_MIRROR=https://my.mirror sh install.sh
|
||||
# (зеркало также пишется в uci, чтобы делегированные загрузки тоже его использовали).
|
||||
# Внимание: `sh <(wget -O- ...)` на OpenWrt НЕ работает — в busybox ash нет
|
||||
# process substitution; используйте форму с пайпом выше.
|
||||
|
||||
G='\033[0;32m'; R='\033[0;31m'; Y='\033[0;33m'; C='\033[0;36m'; N='\033[0m'
|
||||
ok() { echo -e "${G}$1${N}"; }
|
||||
info() { echo -e "${C}$1${N}"; }
|
||||
warn() { echo -e "${Y}$1${N}"; }
|
||||
die() { echo -e "${R}$1${N}"; exit 1; }
|
||||
ask() { printf "${C}%s${N} " "$1"; read -r REPLY </dev/tty 2>/dev/null || REPLY=""; }
|
||||
is_yes() { case "$1" in y|Y|yes|YES|да|Да|д|Д) return 0;; *) return 1;; esac; }
|
||||
|
||||
# --- Разбор JSON (на устройстве нет jq): достать строковое поле / проверить result:true
|
||||
jget() { printf '%s\n' "$1" | sed -n "s/.*\"$2\"[[:space:]]*:[[:space:]]*\"\([^\"]*\)\".*/\1/p" | head -1; }
|
||||
jtrue() { printf '%s' "$1" | grep -qE "\"result\"[[:space:]]*:[[:space:]]*true"; }
|
||||
jerr() { printf '%s\n' "$1" | grep -qE "\"error\""; }
|
||||
jfalse(){ printf '%s' "$1" | grep -qE "\"$2\"[[:space:]]*:[[:space:]]*false"; }
|
||||
|
||||
# --- Загрузка «сначала GitHub, при сбое — зеркало» для первого хопа (app + ключ),
|
||||
# пока ещё нет собственного gh_fetch приложения. dl <url> <файл>
|
||||
dl() {
|
||||
wget -qO "$2" --timeout=20 "$1" 2>/dev/null && [ -s "$2" ] && return 0
|
||||
if [ -n "$GH_MIRROR" ]; then
|
||||
m=$(echo "$1" | sed "s#https://github.com#${GH_MIRROR}#")
|
||||
wget -qO "$2" --timeout=20 "$m" 2>/dev/null && [ -s "$2" ] && return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
api() { wget -qO- --timeout=20 "$1" 2>/dev/null; } # GitHub API (без зеркала)
|
||||
|
||||
echo
|
||||
ok "===== Установщик Re:HomeProxy ====="
|
||||
|
||||
# ---------------------------------------------------------------- 0. окружение
|
||||
[ "$(id -u)" = 0 ] || die "Запустите от root."
|
||||
[ -r /etc/openwrt_release ] || die "Это не OpenWrt (нет /etc/openwrt_release)."
|
||||
. /etc/openwrt_release 2>/dev/null
|
||||
ARCH="$DISTRIB_ARCH"; VER="$DISTRIB_RELEASE"
|
||||
[ -n "$ARCH" ] || die "Не удалось определить архитектуру пакетов (DISTRIB_ARCH)."
|
||||
if command -v apk >/dev/null 2>&1; then PM=apk; EXT=apk
|
||||
elif command -v opkg >/dev/null 2>&1; then PM=opkg; EXT=ipk
|
||||
else die "Не найден поддерживаемый менеджер пакетов (apk/opkg)."; fi
|
||||
case "$VER" in
|
||||
23.05*) LEGACY=1 ;;
|
||||
24.10*|25.*|*SNAPSHOT*) LEGACY=0 ;;
|
||||
22.*|21.*|19.*) die "OpenWrt $VER слишком старая — нужна 23.05 или новее." ;;
|
||||
*) LEGACY=0; warn "Непроверенная версия OpenWrt $VER — продолжаю." ;;
|
||||
esac
|
||||
SUFFIX="_all"; [ "$LEGACY" = 1 ] && SUFFIX="_all-legacy"
|
||||
info "Версия: OpenWrt $VER | Архитектура: $ARCH | Менеджер пакетов: $PM | legacy=$LEGACY"
|
||||
|
||||
# ----------------------------------------------------------- 1. LuCI-приложение + ключ
|
||||
ok "[1/5] Устанавливаю LuCI-приложение Re:HomeProxy..."
|
||||
if [ "$PM" = apk ]; then
|
||||
if [ ! -f /etc/apk/keys/homeproxy-hiddify.pub ]; then
|
||||
dl "https://github.com/1andrevich/homeproxy-hiddify/releases/latest/download/homeproxy-hiddify.pub" /tmp/hp.pub \
|
||||
&& cp /tmp/hp.pub /etc/apk/keys/ && rm -f /tmp/hp.pub && ok " ключ подписи добавлен в доверенные" \
|
||||
|| warn " не удалось скачать ключ подписи — поставлю без проверки подписи"
|
||||
fi
|
||||
fi
|
||||
APPURL=$(api 'https://api.github.com/repos/1andrevich/homeproxy-hiddify/releases' \
|
||||
| grep -o "https://github\.com/[^\"]*luci-app-re-homeproxy[^\"]*${SUFFIX}\.${EXT}" | head -1)
|
||||
[ -n "$APPURL" ] || die "Не нашёл пакет luci-app-re-homeproxy${SUFFIX}.${EXT} (GitHub заблокирован? попробуйте GH_MIRROR=...)."
|
||||
dl "$APPURL" /tmp/app.$EXT || die "Не удалось скачать приложение (попробуйте GH_MIRROR=...)."
|
||||
if [ "$PM" = apk ]; then
|
||||
apk add /tmp/app.$EXT 2>/dev/null || apk add --allow-untrusted /tmp/app.$EXT || die "apk add завершился ошибкой."
|
||||
else
|
||||
opkg update >/dev/null 2>&1; opkg install /tmp/app.$EXT || die "opkg install завершился ошибкой."
|
||||
fi
|
||||
rm -f /tmp/app.$EXT
|
||||
ok " приложение установлено."
|
||||
|
||||
# Русский язык интерфейса (по умолчанию — да)
|
||||
ask " Установить пакет русского языка? [Y/n] (по умолчанию Y):"
|
||||
case "$REPLY" in
|
||||
n|N|no|NO|нет|Нет|н|Н) ;; # отказ — пропускаем
|
||||
*)
|
||||
info " ставлю русский язык LuCI..."
|
||||
# базовый перевод интерфейса LuCI (из фида, best-effort)
|
||||
if [ "$PM" = apk ]; then apk add luci-i18n-base-ru >/dev/null 2>&1; else opkg install luci-i18n-base-ru >/dev/null 2>&1; fi
|
||||
# перевод самого приложения (из релиза homeproxy)
|
||||
LURL=$(api 'https://api.github.com/repos/1andrevich/homeproxy-hiddify/releases' \
|
||||
| grep -o "https://github\.com/[^\"]*luci-i18n-homeproxy-ru[^\"]*\.${EXT}" | head -1)
|
||||
if [ -n "$LURL" ] && dl "$LURL" /tmp/i18n.$EXT; then
|
||||
if [ "$PM" = apk ]; then apk add /tmp/i18n.$EXT 2>/dev/null || apk add --allow-untrusted /tmp/i18n.$EXT; \
|
||||
else opkg install /tmp/i18n.$EXT; fi
|
||||
else warn " перевод приложения не найден — пропускаю"; fi
|
||||
rm -f /tmp/i18n.$EXT
|
||||
uci set luci.main.lang=ru; uci commit luci
|
||||
ok " русский язык установлен" ;;
|
||||
esac
|
||||
|
||||
# Прописываем зеркало в бэкенд, чтобы делегированные загрузки тоже его использовали
|
||||
if [ -n "$GH_MIRROR" ]; then uci set homeproxy.config.github_mirror="$GH_MIRROR"; uci commit homeproxy; fi
|
||||
|
||||
# rpcd нужно перезапустить, чтобы появились ubus-методы приложения (установка ByeDPI/Zapret)
|
||||
/etc/init.d/rpcd restart >/dev/null 2>&1; sleep 2
|
||||
CM=/usr/share/homeproxy/scripts/core_mgmt.uc
|
||||
[ -f "$CM" ] || die "core_mgmt.uc не найден после установки — прерываю."
|
||||
|
||||
# ------------------------------------------------------- 2. ядро прокси (обязательно)
|
||||
ok "[2/5] Ядро прокси (обязательно — выберите одно)"
|
||||
echo " 1) hiddify-core (по умолчанию; на малой флеш-памяти выберет компактную сборку)"
|
||||
echo " 2) sing-box-extended (AmneziaWG / WARP, самый широкий набор протоколов)"
|
||||
ask " Выбор [1/2] (по умолчанию 1):"
|
||||
case "$REPLY" in 2) CORE=singbox ;; *) CORE=hiddify ;; esac
|
||||
|
||||
PREP=$(ucode "$CM" prepare_install "$CORE")
|
||||
jerr "$PREP" && die " подготовка ядра не удалась: $(jget "$PREP" error)"
|
||||
DLURL=$(jget "$PREP" dl_url); TMP=$(jget "$PREP" tmp_path); PMG=$(jget "$PREP" pkg_manager)
|
||||
[ -n "$DLURL" ] && [ -n "$TMP" ] && [ -n "$PMG" ] || die " подготовка ядра не вернула данные для загрузки."
|
||||
info " скачиваю $CORE..."
|
||||
jtrue "$(ucode "$CM" download_pkg "$DLURL" "$TMP")" || die " не удалось скачать ядро (попробуйте GH_MIRROR=...)."
|
||||
jtrue "$(ucode "$CM" install_pkg "$CORE" "$TMP" "$PMG")" || die " установка ядра не удалась."
|
||||
jtrue "$(ucode "$CM" install_kmods "$PMG")" || warn " не удалось поставить kmod — без kmod-nft-tproxy/kmod-tun прокси не будет маршрутизировать."
|
||||
ok " $CORE установлен."
|
||||
|
||||
# --------------------------------------------------------------- 3. Zapret (опционально)
|
||||
ask "[3/5] Установить Zapret 2 (обход DPI на уровне пакетов — видео/QUIC, звонки)? [y/N]:"
|
||||
if is_yes "$REPLY"; then
|
||||
info " ставлю модуль ядра NFQUEUE..."
|
||||
if [ "$PM" = apk ]; then apk add kmod-nft-queue >/dev/null 2>&1; else opkg install kmod-nft-queue >/dev/null 2>&1; fi
|
||||
ZP=$(ubus call luci.homeproxy zapret_prepare_install 2>/dev/null)
|
||||
if [ -z "$ZP" ] || jerr "$ZP"; then warn " не удалось подготовить Zapret — пропускаю. ($(jget "$ZP" error))"
|
||||
else
|
||||
ZURL=$(jget "$ZP" dl_url); ZTMP=$(jget "$ZP" tmp_path); ZPMG=$(jget "$ZP" pkg_manager)
|
||||
if [ -n "$ZURL" ] && dl "$ZURL" "$ZTMP"; then
|
||||
RES=$(ubus call luci.homeproxy zapret_install_pkg "{\"tmp_path\":\"$ZTMP\",\"pkg_manager\":\"$ZPMG\"}" 2>/dev/null)
|
||||
if jtrue "$RES"; then
|
||||
ok " Zapret установлен."
|
||||
ZST=$(ubus call luci.homeproxy zapret_status 2>/dev/null)
|
||||
if jfalse "$ZST" kmod_ok; then
|
||||
warn " модуль NFQUEUE не загружен — Zapret не включаю (иначе сломается firewall). Включите вручную после kmod-nft-queue."
|
||||
else
|
||||
uci set homeproxy.config.zapret_enabled=1; uci commit homeproxy; ok " Zapret включён."
|
||||
fi
|
||||
else warn " установка Zapret не удалась."; fi
|
||||
else warn " не удалось скачать Zapret — пропускаю."; fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# --------------------------------------------------------------- 4. ByeDPI (опционально)
|
||||
ask "[4/5] Установить ByeDPI (обход DPI на уровне SOCKS, нужен curl)? [y/N]:"
|
||||
if is_yes "$REPLY"; then
|
||||
info " ставлю curl (его использует тестер стратегий ByeDPI)..."
|
||||
if [ "$PM" = apk ]; then apk add curl >/dev/null 2>&1; else opkg install curl >/dev/null 2>&1; fi
|
||||
BP=$(ubus call luci.homeproxy byedpi_prepare_install 2>/dev/null)
|
||||
if [ -z "$BP" ] || jerr "$BP"; then warn " не удалось подготовить ByeDPI — пропускаю. ($(jget "$BP" error))"
|
||||
else
|
||||
BURL=$(jget "$BP" dl_url); BTMP=$(jget "$BP" tmp_path); BPMG=$(jget "$BP" pkg_manager)
|
||||
if [ -n "$BURL" ] && dl "$BURL" "$BTMP"; then
|
||||
RES=$(ubus call luci.homeproxy byedpi_install_pkg "{\"tmp_path\":\"$BTMP\",\"pkg_manager\":\"$BPMG\"}" 2>/dev/null)
|
||||
if jtrue "$RES"; then
|
||||
ok " ByeDPI установлен."
|
||||
uci set homeproxy.config.byedpi_enabled=1; uci commit homeproxy; ok " ByeDPI включён."
|
||||
else warn " установка ByeDPI не удалась."; fi
|
||||
else warn " не удалось скачать ByeDPI — пропускаю."; fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# ------------------------------------------------- 5. режим маршрутизации (пресет)
|
||||
ask "[5/5] Настроить режим «Россия — раздельное туннелирование» (Re:filter через основной сервер)? [Д/н] (по умолчанию да):"
|
||||
case "$REPLY" in
|
||||
n|N|no|NO|нет|Нет|н|Н) ;; # отказ — оставляем как есть
|
||||
*)
|
||||
CURMODE=$(uci -q get homeproxy.config.routing_mode)
|
||||
if [ -z "$CURMODE" ]; then
|
||||
uci set homeproxy.config.routing_mode=proxy_banned_ru
|
||||
uci set homeproxy.config.proxy_calls=1
|
||||
uci set homeproxy.config.no_proxy_torrents=1
|
||||
uci set homeproxy.config.ipv6_support=0
|
||||
uci commit homeproxy
|
||||
CURMODE=proxy_banned_ru
|
||||
fi
|
||||
# Re:filter через основной пул — только если режим РФ и правил ещё нет
|
||||
if [ "$CURMODE" = proxy_banned_ru ] && ! uci show homeproxy 2>/dev/null | grep -q "=proxy_ru_rule$"; then
|
||||
SEC=$(uci add homeproxy proxy_ru_rule)
|
||||
uci set "homeproxy.$SEC.source=refilter"
|
||||
uci set "homeproxy.$SEC.node=main-out"
|
||||
uci set "homeproxy.$SEC.enabled=1"
|
||||
uci commit homeproxy
|
||||
ok " режим настроен: Re:filter через основной сервер"
|
||||
else
|
||||
info " режим/правила уже заданы — не меняю"
|
||||
fi ;;
|
||||
esac
|
||||
|
||||
# ------------------------------------------------------------------- 6. финал
|
||||
/etc/init.d/homeproxy enable >/dev/null 2>&1
|
||||
/etc/init.d/homeproxy start >/dev/null 2>&1
|
||||
|
||||
# LAN-адрес роутера для прямой ссылки на страницу LuCI (обрезаем /маску на 25.12+)
|
||||
LANIP=$(uci -q get network.lan.ipaddr | cut -d/ -f1)
|
||||
[ -n "$LANIP" ] || LANIP=$(ip -4 addr show br-lan 2>/dev/null | sed -n 's#.*inet \([0-9.]*\).*#\1#p' | head -1)
|
||||
[ -n "$LANIP" ] || LANIP="192.168.1.1"
|
||||
|
||||
echo
|
||||
ok "===== Готово ====="
|
||||
info "Откройте Re:HomeProxy в браузере:"
|
||||
URL="http://$LANIP/cgi-bin/luci/admin/services/homeproxy"
|
||||
# OSC 8: кликабельная ссылка в поддерживающих терминалах; в остальных просто виден URL
|
||||
printf '\033[0;36m \033]8;;%s\033\\%s\033]8;;\033\\\033[0m\n' "$URL" "$URL"
|
||||
Reference in new issue
Block a user