secubox-openwrt/package/secubox/secubox-master-link/files/usr/bin/sbx-mesh-invite
CyberMind-FR 39fe2aced4 feat(secubox-master-link): Add CLI tools and secubox-deb API prompt
Add sbx-mesh-invite and sbx-mesh-join CLI tools to secubox-master-link:
- sbx-mesh-invite: Generate invite tokens with URL output (for masters)
- sbx-mesh-join: Join mesh with token (for peers), uses HTTPS

Add .claude/prompts/secubox-deb-masterlink.md:
- API specification for implementing master-link on secubox-deb (VM)
- Endpoints: status, invite, join, peers, approve, cleanup
- Data structures for tokens.json and peers.json
- Integration notes for existing LuCI UI

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-03-26 15:30:30 +01:00

159 lines
4.3 KiB
Bash
Executable File

#!/bin/sh
# SecuBox Mesh Invite Generator
# Generates a join URL that can be shared with peer nodes
# Usage: sbx-mesh-invite [--auto-approve] [--ttl SECONDS]
set -e
TOKENS_FILE="/var/lib/secubox/p2p/master-link/tokens.json"
AUTO_APPROVE="true"
TTL=3600
MASTER_IP=""
# Parse arguments
while [ $# -gt 0 ]; do
case "$1" in
--auto-approve|-a)
AUTO_APPROVE="true"
shift
;;
--manual-approve|-m)
AUTO_APPROVE="false"
shift
;;
--ttl|-t)
TTL="$2"
shift 2
;;
--ip|-i)
MASTER_IP="$2"
shift 2
;;
--help|-h)
cat << 'EOF'
SecuBox Mesh Invite Generator
Usage:
sbx-mesh-invite [options]
Options:
-a, --auto-approve Auto-approve joining nodes (default)
-m, --manual-approve Require manual approval
-t, --ttl SECONDS Token validity in seconds (default: 3600)
-i, --ip ADDRESS Master IP address for the invite URL
-h, --help Show this help
Output:
Prints a join URL that can be copy-pasted to peer nodes.
On the peer, run: sbx-mesh-join <URL>
EOF
exit 0
;;
*)
echo "Unknown option: $1" >&2
exit 1
;;
esac
done
# Ensure tokens directory exists
mkdir -p "$(dirname "$TOKENS_FILE")"
# Generate random token (32 hex chars)
if command -v openssl >/dev/null; then
TOKEN=$(openssl rand -hex 16)
elif [ -r /dev/urandom ]; then
TOKEN=$(head -c 16 /dev/urandom | od -An -tx1 | tr -d ' \n')
else
# Fallback: use date + random
TOKEN=$(date +%s%N | sha256sum | head -c 32)
fi
# Calculate hash
if command -v sha256sum >/dev/null; then
HASH=$(printf '%s' "$TOKEN" | sha256sum | cut -d' ' -f1)
elif command -v openssl >/dev/null; then
HASH=$(printf '%s' "$TOKEN" | openssl dgst -sha256 | awk '{print $2}')
else
echo "Error: No sha256 tool available" >&2
exit 1
fi
# Get timestamps
NOW=$(date -Iseconds 2>/dev/null || date +%Y-%m-%dT%H:%M:%S)
NOW_TS=$(date +%s)
EXPIRES_TS=$((NOW_TS + TTL))
EXPIRES=$(date -Iseconds -d "@$EXPIRES_TS" 2>/dev/null || date -r "$EXPIRES_TS" -Iseconds 2>/dev/null || echo "$EXPIRES_TS")
# Get local IP for URL
LOCAL_IP="$MASTER_IP"
if [ -z "$LOCAL_IP" ]; then
# Try common LAN interfaces first, prefer 192.168.x.x addresses
for iface in br-lan eth0 enp0s8 enp0s3 ens3; do
candidate=$(ip -4 addr show "$iface" 2>/dev/null | grep -oE 'inet 192\.168\.[0-9.]+' | awk '{print $2}' | head -1)
if [ -n "$candidate" ]; then
LOCAL_IP="$candidate"
break
fi
done
# Fallback to any non-loopback, non-10.x address
if [ -z "$LOCAL_IP" ]; then
LOCAL_IP=$(ip -4 addr show 2>/dev/null | grep -oE 'inet [0-9.]+' | grep -v '127.0.0' | grep -v 'inet 10\.' | awk '{print $2}' | head -1)
fi
[ -z "$LOCAL_IP" ] && LOCAL_IP=$(hostname -I 2>/dev/null | awk '{print $1}')
[ -z "$LOCAL_IP" ] && LOCAL_IP="<MASTER_IP>"
fi
# Create new token entry
NEW_TOKEN="{
\"hash\": \"$HASH\",
\"type\": \"join\",
\"created\": \"$NOW\",
\"expires\": \"$EXPIRES\",
\"expires_ts\": $EXPIRES_TS,
\"ttl\": $TTL,
\"status\": \"active\",
\"auto_approve\": $AUTO_APPROVE
}"
# Add to tokens file
if [ -f "$TOKENS_FILE" ]; then
# Append to existing array using Python or jq
if command -v python3 >/dev/null; then
python3 << PYEOF
import json
with open("$TOKENS_FILE", "r") as f:
tokens = json.load(f)
tokens.append(json.loads('''$NEW_TOKEN'''))
with open("$TOKENS_FILE", "w") as f:
json.dump(tokens, f, indent=2)
PYEOF
elif command -v jq >/dev/null; then
tmp=$(mktemp)
jq ". + [$NEW_TOKEN]" "$TOKENS_FILE" > "$tmp" && mv "$tmp" "$TOKENS_FILE"
else
# Manual append (risky but works for simple cases)
sed -i 's/]$/,'"$(echo "$NEW_TOKEN" | tr -d '\n')"']/' "$TOKENS_FILE"
fi
else
echo "[$NEW_TOKEN]" > "$TOKENS_FILE"
fi
# Output the invite URL
echo ""
echo "Mesh Invite Generated"
echo "====================="
echo ""
echo "Token: $TOKEN"
echo "Expires: $EXPIRES"
echo "Auto-approve: $AUTO_APPROVE"
echo ""
echo "Join URL (copy this to the peer node):"
echo ""
echo " https://${LOCAL_IP}/master-link/?token=${TOKEN}"
echo ""
echo "Or run on the peer:"
echo ""
echo " sbx-mesh-join ${LOCAL_IP} ${TOKEN}"
echo ""