8 Commits

Author SHA1 Message Date
Андрей Бобырев
14bb6ae589 stable 1.2.7: phobos:// pad missing fields with '= none' (PhobosWG import fix)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 14:57:21 +03:00
Андрей Бобырев
51712310f6 fix: force OBFUSCATOR_PORT from OBFUSCATOR_PORTS[0] (override lib-core 51821 default)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 13:56:01 +03:00
Андрей Бобырев
6ec1782d8b fix(stable): client obfuscator targets real listening port (OBFUSCATOR_PORTS[0])
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 13:53:37 +03:00
Андрей Бобырев
e61ec09b18 fix: find -type f for wg-obfuscator binary in archive (tar unpacks to dir)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 12:26:40 +03:00
Андрей Бобырев
ed3071a971 bump stable to 1.2.6 (aarch64 router binary fix)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 12:24:35 +03:00
Андрей Бобырев
db4cab7a38 fix(stable): fetch router-arch binaries from ClusterM (aarch64, mipsel, armv7)
Keenetic routers are aarch64 but Ground-Zerro only ships x86_64. Installer
now copies all Ground-Zerro binaries + fetches missing arm64/mipsel/armv7
from ClusterM/wg-obfuscator latest release so action_package includes the
right binary for every router architecture.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 12:24:35 +03:00
Андрей Бобырев
9f402be886 fix(stable): api.py in managed_files (port from dev)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 02:48:35 +03:00
Андрей Бобырев
8971565e6e fix: add server/api.py to managed_files (phobos-update now deploys agent)
The secondary agent api.py was not included in the update manifest, so
phobos-update left stale api.py on the server after channel switches.
Adding it ensures bandwidth-aware /api/health reaches secondaries on update.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 02:48:35 +03:00
4 changed files with 77 additions and 8 deletions

View File

@@ -1 +1 @@
1.2.5 1.2.7

39
app.py
View File

@@ -721,11 +721,46 @@ def build_phone_config(cid, mode="android"):
if os.path.exists(instpath): if os.path.exists(instpath):
inst = open(instpath).read().strip() inst = open(instpath).read().strip()
conf = wg + "\n\n" + inst + "\n" conf = wg + "\n\n" + inst + "\n"
b64 = base64.urlsafe_b64encode(conf.encode()).decode().rstrip("=") # PhobosWG requires ALL fields present; missing -> "= none" before base64
link = "phobos://" + b64 + "#" + urllib.parse.quote(cid) # (spec 2.3). Ground-Zerro configs lack PresharedKey -> import fails otherwise.
padded = _pad_conf_with_none(conf)
b64 = base64.urlsafe_b64encode(padded.encode()).decode().rstrip("=")
link = "phobos://" + b64 + "#" + urllib.parse.quote(cid or "none")
return conf, link return conf, link
def _pad_conf_with_none(conf):
"""Insert '<key> = none' for every missing mandatory PhobosWG field
(phobos:// spec 2.3). Only for phobos:// payload, NOT raw .conf."""
mandatory = {
"[interface]": ["PrivateKey", "Address", "MTU", "DNS"],
"[peer]": ["PublicKey", "PresharedKey", "AllowedIPs", "PersistentKeepalive", "Endpoint"],
"[instance]": ["source-if", "source-lport", "target", "key", "masking",
"verbose", "idle-timeout", "max-dummy"],
}
sections = []
cur = None
for ln in conf.split("\n"):
s = ln.strip()
if s.startswith("[") and s.endswith("]"):
cur = [s, []]
sections.append(cur)
elif cur is not None:
cur[1].append(ln)
out = []
for header, lines in sections:
keys = {ln.split("=", 1)[0].strip().lower() for ln in lines if "=" in ln}
while lines and lines[-1].strip() == "":
lines.pop()
for req in mandatory.get(header.lower(), []):
if req.lower() not in keys:
lines.append("%s = none" % req)
out.append(header)
out.extend(lines)
out.append("")
return "\n".join(out).rstrip("\n") + "\n"
def qr_datauri(data): def qr_datauri(data):
try: try:
import qrcode, io, base64 import qrcode, io, base64

View File

@@ -85,12 +85,27 @@ if [ ! -x /usr/local/bin/wg-obfuscator ]; then
git init -q; git remote add origin https://github.com/Ground-Zerro/Phobos.git git init -q; git remote add origin https://github.com/Ground-Zerro/Phobos.git
git config core.sparseCheckout true; echo "wg-obfuscator" > .git/info/sparse-checkout git config core.sparseCheckout true; echo "wg-obfuscator" > .git/info/sparse-checkout
git pull origin main -q git pull origin main -q
cp -f "wg-obfuscator/bin/wg-obfuscator-${ARCH}" "$PHOBOS_DIR/bin/" 2>/dev/null || true cp -f "wg-obfuscator/bin/"wg-obfuscator-* "$PHOBOS_DIR/bin/" 2>/dev/null || true
chmod +x "$PHOBOS_DIR/bin/"wg-obfuscator-* 2>/dev/null || true chmod +x "$PHOBOS_DIR/bin/"wg-obfuscator-* 2>/dev/null || true
ln -sf "$PHOBOS_DIR/bin/wg-obfuscator-${ARCH}" /usr/local/bin/wg-obfuscator ln -sf "$PHOBOS_DIR/bin/wg-obfuscator-${ARCH}" /usr/local/bin/wg-obfuscator 2>/dev/null || true
cd /; rm -rf "$R" cd /; rm -rf "$R"
fi fi
_OBF_TAG=$(curl -fsSL -m10 https://api.github.com/repos/ClusterM/wg-obfuscator/releases/latest 2>/dev/null | grep '"tag_name"' | head -1 | sed 's/.*"tag_name": *"\(.*\)".*/\1/')
_CB="https://github.com/ClusterM/wg-obfuscator/releases/download/${_OBF_TAG}"
for _am in "aarch64:linux-arm64" "mipsel:linux-mipsel-mips32" "mips:linux-mips-mips32" "armv7:linux-armv7-hf"; do
_da="${_am%%:*}"; _ss="${_am##*:}"
if [ ! -f "$PHOBOS_DIR/bin/wg-obfuscator-${_da}" ] && [ -n "$_OBF_TAG" ]; then
_t=$(mktemp -d)
curl -fsSL -m30 "${_CB}/wg-obfuscator-${_OBF_TAG}-${_ss}.tar.gz" -o "$_t/o.tgz" 2>/dev/null &&
tar -xzf "$_t/o.tgz" -C "$_t" 2>/dev/null &&
_b=$(find "$_t" -name "wg-obfuscator" -type f | head -1) &&
[ -n "$_b" ] && cp "$_b" "$PHOBOS_DIR/bin/wg-obfuscator-${_da}" && chmod +x "$PHOBOS_DIR/bin/wg-obfuscator-${_da}" && echo " +wg-obfuscator-${_da} (ClusterM ${_OBF_TAG})"
rm -rf "$_t"
fi
done
[ -x /usr/local/bin/wg-obfuscator ] || ln -sf "$PHOBOS_DIR/bin/wg-obfuscator-${ARCH}" /usr/local/bin/wg-obfuscator 2>/dev/null || true
[ -x /usr/local/bin/wg-obfuscator ] || { echo "ERROR: obfuscator binary for $ARCH missing"; exit 1; } [ -x /usr/local/bin/wg-obfuscator ] || { echo "ERROR: obfuscator binary for $ARCH missing"; exit 1; }
echo " bins: $(ls $PHOBOS_DIR/bin/ | tr '\n' ' ')"
# ── 3. Phobos repo (onboarding scripts) ── # ── 3. Phobos repo (onboarding scripts) ──
echo "[3/9] Phobos repo (onboarding scripts)..." echo "[3/9] Phobos repo (onboarding scripts)..."

View File

@@ -6,6 +6,12 @@ check_root
load_env load_env
ensure_dirs ensure_dirs
# server.env stores OBFUSCATOR_PORTS (plural, comma list). Client obfuscator
# must target an ACTUAL listening port. lib-core load_env defaults OBFUSCATOR_PORT
# to 51821 (NOT listened on) -> handshake failed. Override unconditionally from
# the real port list when present.
[ -n "${OBFUSCATOR_PORTS:-}" ] && export OBFUSCATOR_PORT="$(echo "$OBFUSCATOR_PORTS" | cut -d',' -f1)"
CMD="${1:-help}" CMD="${1:-help}"
CLIENT_ARG="${2:-}" CLIENT_ARG="${2:-}"
EXTRA_ARG="${3:-}" EXTRA_ARG="${3:-}"
@@ -209,8 +215,21 @@ action_package() {
cp "$dir/${id}.conf" "$pkg_root/${id}.conf" cp "$dir/${id}.conf" "$pkg_root/${id}.conf"
cp "$dir/wg-obfuscator.conf" "$pkg_root/wg-obfuscator.conf" cp "$dir/wg-obfuscator.conf" "$pkg_root/wg-obfuscator.conf"
for arch in mipsel mips aarch64 armv7 x86_64; do # Fetch missing router-arch binaries from ClusterM on-demand
[[ -f "$PHOBOS_DIR/bin/wg-obfuscator-$arch" ]] && cp "$PHOBOS_DIR/bin/wg-obfuscator-$arch" "$pkg_root/bin/" local _tag; _tag=$(curl -fsSL -m10 https://api.github.com/repos/ClusterM/wg-obfuscator/releases/latest 2>/dev/null | grep '"tag_name"' | head -1 | sed 's/.*"tag_name": *"\(.*\)".*//')
local _cb="https://github.com/ClusterM/wg-obfuscator/releases/download/${_tag}"
declare -A _am=([aarch64]="linux-arm64" [mipsel]="linux-mipsel-mips32" [mips]="linux-mips-mips32" [armv7]="linux-armv7-hf" [x86_64]="linux-x64")
for _arch in aarch64 mipsel mips armv7 x86_64; do
if [[ ! -f "$PHOBOS_DIR/bin/wg-obfuscator-$_arch" ]] && [[ -n "$_tag" ]]; then
local _t; _t=$(mktemp -d)
if curl -fsSL -m30 "${_cb}/wg-obfuscator-${_tag}-${_am[$_arch]}.tar.gz" -o "$_t/o.tgz" 2>/dev/null; then
tar -xzf "$_t/o.tgz" -C "$_t" 2>/dev/null || true
local _b; _b=$(find "$_t" -name "wg-obfuscator" -type f | head -1)
[[ -n "$_b" ]] && cp "$_b" "$PHOBOS_DIR/bin/wg-obfuscator-$_arch" && chmod +x "$PHOBOS_DIR/bin/wg-obfuscator-$_arch" && log_info "+wg-obfuscator-$_arch (ClusterM ${_tag})"
fi
rm -rf "$_t"
fi
[[ -f "$PHOBOS_DIR/bin/wg-obfuscator-$_arch" ]] && cp "$PHOBOS_DIR/bin/wg-obfuscator-$_arch" "$pkg_root/bin/"
done done
local tpl_dir="$REPO_DIR/client/templates" local tpl_dir="$REPO_DIR/client/templates"
@@ -249,7 +268,7 @@ action_package() {
source "$PHOBOS_DIR/server/server.env" source "$PHOBOS_DIR/server/server.env"
cat > "$pkg_root/failover.conf" <<FAILEOF cat > "$pkg_root/failover.conf" <<FAILEOF
# Phobos Failover Configuration # Phobos Failover Configuration
SERVER_1=${SERVER_PUBLIC_IP_V4}:51821,51822,51823 SERVER_1=${SERVER_PUBLIC_IP_V4}:${OBFUSCATOR_PORTS:-51821,51822,51823}
KEY_1=${OBFUSCATOR_KEY} KEY_1=${OBFUSCATOR_KEY}
FAILEOF FAILEOF