Files
2026-10-08 01:40:42 +03:00

154 lines
7.1 KiB
Bash

#!/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
# Extra WireGuard networks dropped into ~/.brov-secrets/wg/<name>.conf (e.g. home.conf):
# moved into the root folder, the user copy is removed.
for f in "$USER_HOME"/.brov-secrets/wg/*.conf; do
[ -f "$f" ] && [ ! -L "$f" ] || continue
install -m 600 -o root -g wheel "$f" "$CORE/src/$(basename "$f")" && rm -f "$f"
echo "✓ WireGuard $(basename "$f" .conf) перенесён в ядро"
done
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 '<?xml version="1.0" encoding="UTF-8"?>'
echo '<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">'
echo '<plist version="1.0"><dict>'
echo " <key>Label</key><string>$label</string>"
echo ' <key>ProgramArguments</key><array>'
for a in "$@"; do echo " <string>$a</string>"; done
echo ' </array>'
echo ' <key>RunAtLoad</key><true/>'
echo ' <key>KeepAlive</key><true/>'
echo ' <key>ThrottleInterval</key><integer>5</integer>'
echo " <key>StandardOutPath</key><string>/Library/Logs/BroV/$label.log</string>"
echo " <key>StandardErrorPath</key><string>/Library/Logs/BroV/$label.log</string>"
echo '</dict></plist>'
} > "/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
# Services take a moment to start: wait up to 10 s before judging.
running() {
launchctl print "system/$CORE_LABEL" 2>/dev/null | grep -q 'state = running' &&
launchctl print "system/$CTL_LABEL" 2>/dev/null | grep -q 'state = running' &&
[ -S /var/run/brov-netctl.sock ]
}
i=0
until running || [ $i -ge 20 ]; do sleep 0.5; i=$((i+1)); done
if running; 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."