#!/bin/sh # BroV network core — install / update as root services (run by hand, once per update): # sudo sh scripts/netcore/install.sh # # Layout after install (everything root-owned, nothing a user process can change): # /Library/Application Support/BroV/mihomo the core, checked against the release SHA256 # /Library/Application Support/BroV/netctl.py narrow helper BroV talks to # /Library/Application Support/BroV/netcore/ config, gen.py, keys, API secret (0700) # /Library/LaunchDaemons/local.maksar.brov.netd.plist the core, at boot, restarted on crash # /Library/LaunchDaemons/local.maksar.brov.netctl.plist the helper (socket /var/run/brov-netctl.sock, # only your user may connect) # First run migrates keys from ~/Library/Application Support/NotchBuddy/netcore and then # deletes that user-writable copy (it is what made root trust user files). # # Undo: sudo sh scripts/netcore/uninstall.sh set -e [ "$(id -u)" -eq 0 ] || { echo "Запусти через sudo: sudo sh $0"; exit 1; } USER_NAME="${SUDO_USER:?запусти через sudo из своей учётной записи}" USER_UID=$(id -u "$USER_NAME") USER_HOME=$(dscl . -read "/Users/$USER_NAME" NFSHomeDirectory | awk '{print $2}') HERE=$(cd "$(dirname "$0")" && pwd) ROOT="/Library/Application Support/BroV" CORE="$ROOT/netcore" OLD="$USER_HOME/Library/Application Support/NotchBuddy/netcore" BIN="$ROOT/mihomo" CORE_LABEL="local.maksar.brov.netd" CTL_LABEL="local.maksar.brov.netctl" MIHOMO_VERSION="v1.19.32" MIHOMO_GZ_SHA="3312a6780652c622890fd4357c6a853bbf865464fd047ac7b7f52dab8de18652" MIHOMO_BIN_SHA="94a386ec0149080deadd86b1f667363bde3c70f7489dba3258e52c56fc9a6d66" if pgrep -qx AmneziaVPN; then echo "Приложение AmneziaVPN запущено — закрой его (только приложение, служба не мешает)." exit 1 fi umask 077 install -d -m 755 -o root -g wheel "$ROOT" install -d -m 700 -o root -g wheel "$CORE" "$CORE/keys" "$CORE/src" "$CORE/providers" install -d -m 755 -o root -g wheel /Library/Logs/BroV # 1. The core binary: keep the installed one if it matches, else fetch and verify. if [ "$(shasum -a 256 "$BIN" 2>/dev/null | cut -d' ' -f1)" = "$MIHOMO_BIN_SHA" ]; then echo "✓ mihomo $MIHOMO_VERSION на месте, контрольная сумма совпадает" else echo "→ Скачиваю mihomo $MIHOMO_VERSION с GitHub и проверяю SHA256" TMP=$(mktemp -d) curl -fsSL -o "$TMP/m.gz" "https://github.com/MetaCubeX/mihomo/releases/download/$MIHOMO_VERSION/mihomo-darwin-arm64-$MIHOMO_VERSION.gz" [ "$(shasum -a 256 "$TMP/m.gz" | cut -d' ' -f1)" = "$MIHOMO_GZ_SHA" ] || { echo "✗ архив не совпал с официальной суммой"; rm -rf "$TMP"; exit 1; } gunzip -c "$TMP/m.gz" > "$TMP/mihomo" install -m 755 -o root -g wheel "$TMP/mihomo" "$BIN" rm -rf "$TMP" fi # 2. Helper scripts from the repo (no secrets in them). install -m 700 -o root -g wheel "$HERE/gen.py" "$CORE/gen.py" install -m 755 -o root -g wheel "$HERE/netctl.py" "$ROOT/netctl.py" # 3. Migrate secrets from the old user folder — regular files only, never symlinks. copy_regular() { # src dst [ -f "$1" ] && [ ! -L "$1" ] && install -m 600 -o root -g wheel "$1" "$2" return 0 } if [ -d "$OLD" ] && [ ! -L "$OLD" ]; then echo "→ Переношу ключи и настройки в $CORE" for f in "$OLD"/keys/*.vpnkey; do copy_regular "$f" "$CORE/keys/$(basename "$f")"; done for f in "$OLD"/src/*; do copy_regular "$f" "$CORE/src/$(basename "$f")"; done [ -f "$CORE/api.secret" ] || copy_regular "$OLD/api.secret" "$CORE/api.secret" [ -f "$CORE/cache.db" ] || copy_regular "$OLD/cache.db" "$CORE/cache.db" copy_regular "$OLD/providers/vless.yaml" "$CORE/providers/vless.yaml" fi ls "$CORE"/keys/*.vpnkey >/dev/null 2>&1 || { echo "✗ нет ни одного ключа Амнезии в $CORE/keys"; exit 1; } for f in saga.conf planet9.conf vless.sub; do [ -f "$CORE/src/$f" ] || { echo "✗ нет $CORE/src/$f"; exit 1; } done chown -R root:wheel "$CORE" chmod -R go-rwx "$CORE" # 4. Build and check the config as root. echo "→ Собираю конфиг" (cd "$CORE" && /usr/bin/python3 gen.py) "$BIN" -t -d "$CORE" -f "$CORE/config.yaml" >/dev/null : > /Library/Logs/BroV/netcore.log chmod 600 /Library/Logs/BroV/netcore.log # 5. Services. write_plist() { # label, then program arguments label=$1; shift { echo '' echo '' echo '' echo " Label$label" echo ' ProgramArguments' for a in "$@"; do echo " $a"; done echo ' ' echo ' RunAtLoad' echo ' KeepAlive' echo ' ThrottleInterval5' echo " StandardOutPath/Library/Logs/BroV/$label.log" echo " StandardErrorPath/Library/Logs/BroV/$label.log" echo '' } > "/Library/LaunchDaemons/$label.plist" chown root:wheel "/Library/LaunchDaemons/$label.plist" chmod 644 "/Library/LaunchDaemons/$label.plist" plutil -lint "/Library/LaunchDaemons/$label.plist" >/dev/null } write_plist "$CORE_LABEL" "$BIN" -d "$CORE" -f "$CORE/config.yaml" write_plist "$CTL_LABEL" /usr/bin/python3 "$ROOT/netctl.py" "$USER_UID" rm -f /Library/Logs/BroV/netcore.log echo "→ Запускаю службы" for label in "$CORE_LABEL" "$CTL_LABEL"; do launchctl bootout "system/$label" 2>/dev/null || true done sleep 1 for label in "$CORE_LABEL" "$CTL_LABEL"; do launchctl bootstrap system "/Library/LaunchDaemons/$label.plist" 2>/dev/null || launchctl kickstart -k "system/$label" done i=0 until [ -S /var/run/brov-netctl.sock ] || [ $i -ge 20 ]; do sleep 0.5; i=$((i+1)); done if launchctl print "system/$CORE_LABEL" | grep -q 'state = running' && [ -S /var/run/brov-netctl.sock ]; then echo "✓ Ядро и помощник работают." else echo "⚠ Что-то не поднялось. Логи: /Library/Logs/BroV/" exit 1 fi # 6. Remove the old user-writable copy (keys, secret, binary) — root no longer reads it. if [ -d "$OLD" ] && [ ! -L "$OLD" ]; then rm -rf "$OLD" echo "✓ Старая копия ключей в ~/Library/Application Support/NotchBuddy/netcore удалена" fi rm -f "$USER_HOME/Library/Application Support/NotchBuddy/netcore.json" echo "Готово. Управление — глобус 🌐 в чёлке BroV."