#!/bin/sh # wizard.sh — One-button Keylink IT fleet setup for Synology routers. # Idempotent — safe to run multiple times. # Usage: wizard.sh [--auto] [--force] # --auto Non-interactive (for postinst / web trigger) # --force Re-register even if already assigned # # Compatible: RT2600ac, RT6600ax (all ipq806x SRM routers) set -e HUB_HOST="162.243.83.36" HUB_PORT="8080" CONF="/etc/kit-connect/connect.conf" AUTO=0 FORCE=0 [ "$1" = "--auto" ] && AUTO=1 [ "$1" = "--force" ] || [ "$2" = "--force" ] && FORCE=1 banner() { echo "" echo " ╔══════════════════════════════════════════╗" echo " ║ KEYLINK IT — Pioneer Bus Fleet Setup ║" echo " ╚══════════════════════════════════════════╝" echo "" } step() { echo " ▶ $*"; } ok() { echo " ✓ $*"; } warn() { echo " ⚠ $*"; } banner # ── Step 1: Detect device ────────────────────────────────────── step "Detecting device..." DEVICE_ID=$(cat /etc/busrouter/device-id 2>/dev/null || true) if [ -z "$DEVICE_ID" ]; then DEVICE_ID=$(hostname 2>/dev/null | sed 's/[^a-zA-Z0-9_-]//g' || echo "unknown") fi mkdir -p /etc/busrouter echo "$DEVICE_ID" > /etc/busrouter/device-id ok "Device ID: ${DEVICE_ID}" # ── Step 2: Check prerequisites ──────────────────────────────── step "Checking prerequisites..." for cmd in curl ssh ssh-keygen; do command -v "$cmd" >/dev/null 2>&1 || { echo " ✗ Missing: $cmd"; exit 1; } done ok "All prerequisites found (curl, ssh)" # ── Step 3: Config file ──────────────────────────────────────── step "Configuring Keylink IT defaults..." mkdir -p /etc/kit-connect /var/packages/kit-connect/target/var if [ ! -f "$CONF" ]; then # Create from template if available if [ -f /var/packages/kit-connect/target/conf/connect.conf ]; then cp /var/packages/kit-connect/target/conf/connect.conf "$CONF" else touch "$CONF" fi fi # Write Keylink IT defaults _write() { grep -q "^${1}=" "$CONF" 2>/dev/null && sed -i "s|^${1}=.*|${1}=${2}|" "$CONF" || echo "${1}=${2}" >> "$CONF" } _write "DEVICE_ID" "$DEVICE_ID" _write "HUB_HOST" "$HUB_HOST" _write "HUB_PORT" "$HUB_PORT" _write "TUNNEL_ENABLE" "1" _write "TUNNEL_REMOTE_HOST" "$HUB_HOST" _write "TUNNEL_REMOTE_USER" "node" _write "TUNNEL_REMOTE_SSH_PORT" "22" _write "TUNNEL_REMOTE_PORT" "0" # auto-assign _write "TUNNEL_LOCAL_SSH_PORT" "2223" _write "TUNNEL_RETRY_DELAY" "30" _write "TAILSCALE_ENABLE" "1" _write "TAILSCALE_AUTH_KEY" "tskey-auth-kJz8wqNVo211CNTRL-GNL5EFjp5aWQcaWPSVn2aW9TNworKUNBV" _write "TAILSCALE_HOSTNAME" "$DEVICE_ID" _write "WATCHDOG_INTERVAL" "60" _write "FORWARD_FAIL_LIMIT" "2" ok "Config written to ${CONF}" # ── Step 4: Register with hub ────────────────────────────────── step "Registering with fleet hub (${HUB_HOST}:${HUB_PORT})..." resp=$(curl -s --connect-timeout 10 --max-time 15 "http://${HUB_HOST}:${HUB_PORT}/api/register/${DEVICE_ID}" 2>/dev/null) || true if [ -z "$resp" ]; then warn "Hub unreachable — will retry on next daemon start" ok "Config saved locally (port will auto-assign when hub is reachable)" else port=$(echo "$resp" | grep -o '"tunnel_port"[[:space:]]*:[[:space:]]*[0-9]*' | grep -o '[0-9]*') status=$(echo "$resp" | grep -o '"status"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4) tskey=$(echo "$resp" | grep -o '"tailscale_auth_key"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4) if [ -n "$port" ] && [ "$port" != "0" ]; then sed -i "s/^TUNNEL_REMOTE_PORT=.*/TUNNEL_REMOTE_PORT=${port}/" "$CONF" 2>/dev/null ok "Hub assigned port ${port} (status: ${status:-ok})" echo "$port" > /var/packages/kit-connect/target/var/hub_port fi if [ -n "$tskey" ]; then sed -i "s|^TAILSCALE_AUTH_KEY=.*|TAILSCALE_AUTH_KEY=${tskey}|" "$CONF" 2>/dev/null ok "Tailscale key configured" fi # ── Authorize tunnel key with hub ────────────────────── if [ -n "$port" ] && [ "$port" != "0" ] && [ -f /var/packages/kit-connect/target/bin/connect_id_ed25519.pub ]; then PUBKEY=$(awk '{print $1" "$2}' /var/packages/kit-connect/target/bin/connect_id_ed25519.pub 2>/dev/null) if [ -n "$PUBKEY" ]; then curl -s --connect-timeout 10 --max-time 15 \ -X POST "http://${HUB_HOST}:${HUB_PORT}/api/authorize-key" \ -H "Content-Type: application/json" \ -d "{\"device_id\":\"${DEVICE_ID}\",\"pubkey\":\"${PUBKEY}\"}" \ >/dev/null 2>&1 && ok "Tunnel key authorized (restrict, port ${port})" || true fi fi fi # ── Step 5: Dashboard server ─────────────────────────────────── step "Setting up local dashboard..." mkdir -p /var/packages/kit-connect/target/www # Dashboard is served by busybox httpd on port 8089 ok "Dashboard will be available on port 8089" # ── Step 6: Start services ───────────────────────────────────── step "Starting kit-connect service..." if [ -x /var/packages/kit-connect/scripts/start-stop-status ]; then /var/packages/kit-connect/scripts/start-stop-status start 2>/dev/null && \ ok "Service started" || warn "Service start returned non-zero" fi # ── Done ─────────────────────────────────────────────────────── ASSIGNED=$(grep '^TUNNEL_REMOTE_PORT=' "$CONF" 2>/dev/null | cut -d= -f2 || echo "pending") echo "" echo " ╔══════════════════════════════════════════╗" echo " ║ SETUP COMPLETE ║" echo " ╠══════════════════════════════════════════╣" printf " ║ Device: %-30s ║\n" "$DEVICE_ID" printf " ║ Port: %-30s ║\n" "$ASSIGNED" printf " ║ Hub: %-30s ║\n" "${HUB_HOST}:${HUB_PORT}" echo " ╠══════════════════════════════════════════╣" echo " ║ Dashboard: http://${DEVICE_ID}:8089/ ║" echo " ╚══════════════════════════════════════════╝" echo "" exit 0