secondary-setup: fetch agent api.py (with /api/router-config); README turnkey

This commit is contained in:
phobos
2026-05-30 13:47:14 +03:00
parent 8113fb190a
commit d5313d3572
2 changed files with 26 additions and 94 deletions

View File

@@ -2,14 +2,29 @@
Веб-панель управления для [Phobos](https://git.zerrolabs.org/Ground-Zerro/Phobos) (обфусцированный WireGuard VPN).
## Быстрый старт
## Быстрый старт (turnkey — с чистого VPS, одной командой)
**Требование:** Phobos уже установлен на VPS ([инструкция](https://git.zerrolabs.org/Ground-Zerro/Phobos)).
Ставит ВСЁ со всеми зависимостями: wg-obfuscator, WireGuard, обфускатор-сервисы,
веб-панель, nginx, скрипты онбординга роутеров и сторож авто-восстановления.
Предустановленный Phobos НЕ требуется.
```bash
bash <(curl -fsSL https://raw.githubusercontent.com/andrey271192/PCA_Phobos/main/install.sh)
```
> Если репозиторий приватный — добавь `GH_TOKEN`:
> ```bash
> GH_TOKEN=ghp_xxx bash <(curl -fsSL -H "Authorization: token ghp_xxx" \
> https://raw.githubusercontent.com/andrey271192/PCA_Phobos/main/install.sh)
> ```
### Вторичный сервер (для failover/балансировки)
```bash
MAIN_SERVER=<ip_основного> MAIN_API_KEY=<API key из основного> \
bash <(curl -fsSL https://raw.githubusercontent.com/andrey271192/PCA_Phobos/main/server/secondary-setup.sh)
```
### С кастомными параметрами
```bash

View File

@@ -238,98 +238,15 @@ EOF
# ── 6. Mini-API ──
echo "[6/7] Setting up mini-API..."
cat > "$PHOBOS_DIR/server/api.py" << 'PYEOF'
#!/usr/bin/env python3
"""Phobos Secondary Server API — peer management + health."""
import json, os, subprocess
from flask import Flask, request, jsonify
app = Flask(__name__)
def load_env():
env = {}
with open("/opt/Phobos/server/server.env") as f:
for line in f:
if "=" in line and not line.startswith("#"):
k, v = line.strip().split("=", 1)
env[k] = v
return env
def check_api_key():
env = load_env()
key = request.headers.get("X-API-Key", "")
return key == env.get("MAIN_API_KEY", "")
@app.route("/api/health")
def health():
try:
wg = subprocess.check_output(["wg", "show", "wg0"], text=True, timeout=5)
peers = wg.count("peer:")
return jsonify({"status": "ok", "peers": peers})
except Exception as e:
return jsonify({"status": "error", "error": str(e)}), 500
@app.route("/api/peers", methods=["GET"])
def list_peers():
if not check_api_key():
return jsonify({"error": "unauthorized"}), 401
try:
out = subprocess.check_output(["wg", "show", "wg0", "allowed-ips"], text=True, timeout=5)
peers = {}
for line in out.strip().split("\n"):
if "\t" in line:
pub, ips = line.split("\t", 1)
peers[pub.strip()] = ips.strip()
return jsonify({"peers": peers})
except Exception as e:
return jsonify({"error": str(e)}), 500
@app.route("/api/peers/add", methods=["POST"])
def add_peer():
if not check_api_key():
return jsonify({"error": "unauthorized"}), 401
data = request.json
pub_key = data.get("public_key", "")
allowed_ips = data.get("allowed_ips", "")
if not pub_key or not allowed_ips:
return jsonify({"error": "missing public_key or allowed_ips"}), 400
try:
subprocess.run(["wg", "set", "wg0", "peer", pub_key, "allowed-ips", allowed_ips], check=True, timeout=5)
subprocess.run(["wg-quick", "save", "wg0"], timeout=5)
return jsonify({"status": "ok"})
except Exception as e:
return jsonify({"error": str(e)}), 500
@app.route("/api/peers/remove", methods=["POST"])
def remove_peer():
if not check_api_key():
return jsonify({"error": "unauthorized"}), 401
pub_key = request.json.get("public_key", "")
if not pub_key:
return jsonify({"error": "missing public_key"}), 400
try:
subprocess.run(["wg", "set", "wg0", "peer", pub_key, "remove"], check=True, timeout=5)
subprocess.run(["wg-quick", "save", "wg0"], timeout=5)
return jsonify({"status": "ok"})
except Exception as e:
return jsonify({"error": str(e)}), 500
@app.route("/api/info")
def info():
if not check_api_key():
return jsonify({"error": "unauthorized"}), 401
env = load_env()
return jsonify({
"ip": env.get("SERVER_PUBLIC_IP_V4"),
"wg_public_key": env.get("SERVER_WG_PUBLIC_KEY"),
"obfuscator_key": env.get("OBFUSCATOR_KEY"),
"ports": env.get("OBFUSCATOR_PORTS", "2083").split(","),
"role": "secondary"
})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8444)
PYEOF
# Mini-API (fetched from PCA — includes /api/router-config for tunnel pull)
PCA_BRANCH="${PCA_BRANCH:-main}"
RAW="https://raw.githubusercontent.com/andrey271192/PCA_Phobos/${PCA_BRANCH}"
if [ -n "${GH_TOKEN:-}" ]; then
curl -fsSL -H "Authorization: token $GH_TOKEN" "$RAW/server/api.py" -o "$PHOBOS_DIR/server/api.py"
else
curl -fsSL "$RAW/server/api.py" -o "$PHOBOS_DIR/server/api.py"
fi
[ -s "$PHOBOS_DIR/server/api.py" ] || { echo "ERROR: api.py fetch failed"; exit 1; }
cat > /etc/systemd/system/phobos-api.service << EOF
[Unit]