diff --git a/gl-kit-connect/Makefile b/gl-kit-connect/Makefile new file mode 100644 index 0000000..70e2b0e --- /dev/null +++ b/gl-kit-connect/Makefile @@ -0,0 +1,69 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=kit-connect +PKG_VERSION:=0.1.0 +PKG_RELEASE:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/kit-connect + SECTION:=net + CATEGORY:=Network + TITLE:=Pioneer Bus Fleet — Connectivity Agent + DEPENDS:=+curl +openssh-client +tailscale + PKGARCH:=all +endef + +define Package/kit-connect/description + Unified management connectivity for Pioneer bus fleet routers. + Deploys Tailscale + reverse SSH tunnel. Hub auto-assigns ports. + Includes one-button setup wizard and local status dashboard. + + Compatible: GL-XE3000, GL-MT3000, and all OpenWrt-based fleet routers. +endef + +define Build/Compile +endef + +define Package/kit-connect/install + $(INSTALL_DIR) $(1)/etc/init.d $(1)/etc/config $(1)/etc/kitconnect + $(INSTALL_DIR) $(1)/usr/sbin $(1)/www/kitconnect + + # Init + config + $(INSTALL_BIN) ./files/etc/init.d/kitconnect $(1)/etc/init.d/kitconnect + $(INSTALL_CONF) ./files/etc/config/kitconnect $(1)/etc/config/kitconnect + + # Binaries + $(INSTALL_BIN) ./files/usr/sbin/connect-daemon.sh $(1)/usr/sbin/connect-daemon.sh + $(INSTALL_BIN) ./files/usr/sbin/connect-register.sh $(1)/usr/sbin/connect-register.sh + $(INSTALL_BIN) ./files/usr/sbin/connect-wizard.sh $(1)/usr/sbin/connect-wizard.sh + + # SSH key (private — must be 600) + $(INSTALL_DATA) ./files/etc/kitconnect/connect_id_ed25519 $(1)/etc/kitconnect/connect_id_ed25519 + chmod 600 $(1)/etc/kitconnect/connect_id_ed25519 + + # Web UI + $(INSTALL_DATA) ./files/www/kitconnect/index.html $(1)/www/kitconnect/index.html + $(INSTALL_BIN) ./files/www/kitconnect/wizard.cgi $(1)/www/kitconnect/wizard.cgi +endef + +define Package/kit-connect/postinst +#!/bin/sh +# Run the setup wizard on first install +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/kitconnect enable 2>/dev/null || true + /usr/sbin/connect-wizard.sh --auto 2>/dev/null || true + /etc/init.d/kitconnect start 2>/dev/null || true +fi +endef + +define Package/kit-connect/prerm +#!/bin/sh +# Stop service before removal +if [ -z "$${IPKG_INSTROOT}" ]; then + /etc/init.d/kitconnect stop 2>/dev/null || true + /etc/init.d/kitconnect disable 2>/dev/null || true +fi +endef + +$(eval $(call BuildPackage,kit-connect)) diff --git a/gl-kit-connect/files/etc/config/kitconnect b/gl-kit-connect/files/etc/config/kitconnect new file mode 100644 index 0000000..da644c6 --- /dev/null +++ b/gl-kit-connect/files/etc/config/kitconnect @@ -0,0 +1,26 @@ +config kitconnect 'main' + # ── Device Identity ──────────────────────────────────── + option device_id '' + # Auto-detected from /etc/busrouter/device-id or hostname + + # ── Hub Registration ──────────────────────────────────── + option hub_host '162.243.83.36' + option hub_port '8080' + + # ── Reverse SSH Tunnel ────────────────────────────────── + option tunnel_enable '1' + option tunnel_remote_host '162.243.83.36' + option tunnel_remote_user 'node' + option tunnel_remote_ssh_port '22' + option tunnel_remote_port '0' # 0 = auto-assign via hub + option tunnel_local_port '2223' + option tunnel_retry_delay '30' + + # ── Tailscale ────────────────────────────────────────── + option tailscale_enable '1' + option tailscale_auth_key 'tskey-auth-kJz8wqNVo211CNTRL-GNL5EFjp5aWQcaWPSVn2aW9TNworKUNBV' + option tailscale_hostname '' + + # ── Behaviour ────────────────────────────────────────── + option watchdog_interval '60' + option forward_fail_limit '2' diff --git a/gl-kit-connect/files/etc/init.d/kitconnect b/gl-kit-connect/files/etc/init.d/kitconnect new file mode 100644 index 0000000..8d07a8f --- /dev/null +++ b/gl-kit-connect/files/etc/init.d/kitconnect @@ -0,0 +1,43 @@ +#!/bin/sh /etc/rc.common +# kit-connect — Pioneer Bus Fleet connectivity agent +# Manages Tailscale + reverse SSH tunnel to the fleet hub. +# One package, all GL routers. Hub assigns ports and keys. + +USE_PROCD=1 +START=90 + +EXTRA_COMMANDS="wizard status" +EXTRA_HELP=" wizard Run the Keylink IT setup wizard + status Show connectivity status" + +start_service() { + procd_open_instance + procd_set_param command /usr/sbin/connect-daemon.sh + procd_set_param respawn 3600 5 0 # max 1 respawn/hr, 5s delay, unlimited + procd_set_param stdout 1 + procd_set_param stderr 1 + procd_close_instance +} + +wizard() { + /usr/sbin/connect-wizard.sh +} + +status() { + echo "=== kit-connect Status ===" + echo "Device: $(cat /etc/busrouter/device-id 2>/dev/null || hostname)" + if [ -f /var/run/kitconnect.pid ] && kill -0 "$(cat /var/run/kitconnect.pid)" 2>/dev/null; then + echo "Daemon: running (PID $(cat /var/run/kitconnect.pid))" + else + echo "Daemon: stopped" + fi + uci -q show kitconnect 2>/dev/null | while IFS='=' read -r key val; do + echo "Config: ${key##*.}=${val//\'/}" + done + echo "Tunnel PID: $(cat /var/run/kitconnect-tunnel.pid 2>/dev/null || echo 'none')" + if command -v tailscale >/dev/null 2>&1; then + tailscale status 2>/dev/null | head -3 + else + echo "Tailscale: not installed" + fi +} diff --git a/gl-kit-connect/files/usr/sbin/connect-daemon.sh b/gl-kit-connect/files/usr/sbin/connect-daemon.sh new file mode 100644 index 0000000..beb01b9 --- /dev/null +++ b/gl-kit-connect/files/usr/sbin/connect-daemon.sh @@ -0,0 +1,188 @@ +#!/bin/sh +# kit-connect daemon — manages Tailscale + reverse SSH tunnel. +# Runs under procd supervision (auto-respawn on crash). +# Config: /etc/config/kitconnect (UCI) + hub-assigned settings. +# One package, all GL routers. Hub assigns ports and keys. + +PKG="kit-connect" +STATE_DIR="/var/run/kitconnect" +CONF="/etc/config/kitconnect" +KEY="/etc/kitconnect/connect_id_ed25519" +PID_FILE="$STATE_DIR/daemon.pid" +TUNNEL_PID="$STATE_DIR/tunnel.pid" +LOG_TAG="kit-connect" + +log() { + logger -t "$LOG_TAG" -p daemon.info "$*" +} + +warn() { + logger -t "$LOG_TAG" -p daemon.warn "WARN: $*" +} + +mkdir -p "$STATE_DIR" +chmod 600 "$KEY" 2>/dev/null +echo "$$" > "$PID_FILE" + +# ── Config loader (UCI → shell vars) ────────────────────────── +load_config() { + _uci() { uci -q get "kitconnect.main.${1}" 2>/dev/null || echo "${2}"; } + + DEVICE_ID=$(_uci device_id "") + [ -z "$DEVICE_ID" ] && DEVICE_ID=$(cat /etc/busrouter/device-id 2>/dev/null || hostname | sed 's/[^a-zA-Z0-9_-]//g') + + HUB_HOST=$(_uci hub_host "162.243.83.36") + HUB_PORT=$(_uci hub_port "8080") + + TUNNEL_ENABLE=$(_uci tunnel_enable "1") + TUNNEL_REMOTE_HOST=$(_uci tunnel_remote_host "162.243.83.36") + TUNNEL_REMOTE_USER=$(_uci tunnel_remote_user "node") + TUNNEL_REMOTE_SSH_PORT=$(_uci tunnel_remote_ssh_port "22") + TUNNEL_REMOTE_PORT=$(_uci tunnel_remote_port "0") + TUNNEL_LOCAL_PORT=$(_uci tunnel_local_port "2223") + TUNNEL_RETRY_DELAY=$(_uci tunnel_retry_delay "30") + + TAILSCALE_ENABLE=$(_uci tailscale_enable "1") + TAILSCALE_AUTH_KEY=$(_uci tailscale_auth_key "") + TAILSCALE_HOSTNAME=$(_uci tailscale_hostname "") + [ -z "$TAILSCALE_HOSTNAME" ] && TAILSCALE_HOSTNAME="$DEVICE_ID" + + WATCHDOG_INTERVAL=$(_uci watchdog_interval "60") + FORWARD_FAIL_LIMIT=$(_uci forward_fail_limit "2") + + # Binary detection + TAILSCALE_BIN=$(command -v tailscale 2>/dev/null || echo "/usr/sbin/tailscale") + TAILSCALED_BIN=$(command -v tailscaled 2>/dev/null || echo "/usr/sbin/tailscaled") +} + +# ── Start Tailscale ──────────────────────────────────────────── +start_tailscale() { + [ "$TAILSCALE_ENABLE" != "1" ] && { log "tailscale: disabled in config"; return 0; } + [ -z "$TAILSCALE_AUTH_KEY" ] && { log "tailscale: no auth key — skipping"; return 0; } + ! command -v "$TAILSCALE_BIN" >/dev/null 2>&1 && { log "tailscale: binary not found"; return 1; } + + # Already connected? + if "$TAILSCALE_BIN" status >/dev/null 2>&1; then + log "tailscale: already connected ($($TAILSCALE_BIN ip -4 2>/dev/null || echo no-ip))" + return 0 + fi + + log "tailscale: starting daemon..." + "$TAILSCALED_BIN" --tun=userspace-networking >/dev/null 2>&1 & + sleep 3 + + log "tailscale: authenticating..." + "$TAILSCALE_BIN" up \ + --auth-key "$TAILSCALE_AUTH_KEY" \ + --hostname "${TAILSCALE_HOSTNAME}" \ + --accept-routes=false \ + --accept-dns=false 2>&1 | while read -r line; do log "tailscale: $line"; done + + local ts_ip + ts_ip=$("$TAILSCALE_BIN" ip -4 2>/dev/null || echo "unknown") + log "tailscale: connected — IP=${ts_ip}" +} + +# ── Start reverse SSH tunnel ─────────────────────────────────── +start_tunnel() { + [ "$TUNNEL_ENABLE" != "1" ] && { log "tunnel: disabled"; return 0; } + [ "$TUNNEL_REMOTE_PORT" = "0" ] && { register_with_hub; load_config; } + [ "$TUNNEL_REMOTE_PORT" = "0" ] && { log "tunnel: no port assigned — skipping"; return 0; } + + log "tunnel: opening R:0.0.0.0:${TUNNEL_REMOTE_PORT} → 127.0.0.1:${TUNNEL_LOCAL_PORT}" + + ssh \ + -o StrictHostKeyChecking=no \ + -o UserKnownHostsFile=/dev/null \ + -o ServerAliveInterval=15 \ + -o ServerAliveCountMax=3 \ + -o ExitOnForwardFailure=yes \ + -o BatchMode=yes \ + -p "${TUNNEL_REMOTE_SSH_PORT}" \ + -N \ + -R "0.0.0.0:${TUNNEL_REMOTE_PORT}:127.0.0.1:${TUNNEL_LOCAL_PORT}" \ + -i "$KEY" \ + "${TUNNEL_REMOTE_USER}@${TUNNEL_REMOTE_HOST}" \ + 2>"$STATE_DIR/ssh_err" & + + SSH_PID=$! + echo "$SSH_PID" > "$TUNNEL_PID" + log "tunnel: SSH PID=${SSH_PID} port=${TUNNEL_REMOTE_PORT}" + + # Watchdog loop — monitors tunnel health + _fail_count=0 + while kill -0 "$SSH_PID" 2>/dev/null; do + sleep "$WATCHDOG_INTERVAL" + kill -0 "$SSH_PID" 2>/dev/null || break + + if timeout 10 ssh \ + -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ + -o ConnectTimeout=5 -o BatchMode=yes \ + -p "${TUNNEL_REMOTE_SSH_PORT}" -i "$KEY" \ + "${TUNNEL_REMOTE_USER}@${TUNNEL_REMOTE_HOST}" \ + "timeout 3 bash -c 'echo >/dev/tcp/127.0.0.1/${TUNNEL_REMOTE_PORT}' 2>/dev/null" \ + 2>/dev/null; then + [ "$_fail_count" -gt 0 ] && log "tunnel: forward recovered after ${_fail_count} checks" + _fail_count=0 + else + _fail_count=$((_fail_count + 1)) + warn "tunnel: forward check failed (${_fail_count}/${FORWARD_FAIL_LIMIT})" + [ "$_fail_count" -ge "$FORWARD_FAIL_LIMIT" ] && break + fi + done + + kill "$SSH_PID" 2>/dev/null + rm -f "$TUNNEL_PID" + log "tunnel: exited — will retry in ${TUNNEL_RETRY_DELAY}s" + sleep "$TUNNEL_RETRY_DELAY" + return 1 +} + +# ── Hub registration — get assigned port ─────────────────────── +register_with_hub() { + [ "$TUNNEL_REMOTE_PORT" != "0" ] && { return 0; } + + log "hub: registering device ${DEVICE_ID}..." + + resp=$(curl -s --connect-timeout 10 \ + "http://${HUB_HOST}:${HUB_PORT}/api/register/${DEVICE_ID}" 2>/dev/null) || true + + [ -z "$resp" ] && { warn "hub: unreachable"; return 1; } + + # Parse JSON response (no jq dependency — grep + cut) + port=$(echo "$resp" | grep -o '"tunnel_port"[[:space:]]*:[[:space:]]*[0-9]*' | grep -o '[0-9]*') + tskey=$(echo "$resp" | grep -o '"tailscale_auth_key"[[:space:]]*:[[:space:]]*"[^"]*"' | cut -d'"' -f4) + + if [ -n "$port" ] && [ "$port" != "0" ]; then + uci set kitconnect.main.tunnel_remote_port="$port" + uci commit kitconnect + log "hub: assigned port ${port}" + echo "$port" > "$STATE_DIR/hub_port" + fi + + if [ -n "$tskey" ] && [ "$tskey" != "$TAILSCALE_AUTH_KEY" ]; then + uci set kitconnect.main.tailscale_auth_key="$tskey" + uci commit kitconnect + log "hub: updated Tailscale key" + fi +} + +# ── Main loop (one cycle — procd respawns on exit) ──────────── +log "EVENT=DAEMON_START device=${DEVICE_ID}" +load_config + +# Ensure device-id file exists +mkdir -p /etc/busrouter +[ ! -f /etc/busrouter/device-id ] && echo "$DEVICE_ID" > /etc/busrouter/device-id + +# Register with hub (non-fatal — retries next cycle) +register_with_hub 2>/dev/null || true + +# Start Tailscale (runs in background, stays up) +start_tailscale 2>/dev/null || true + +# Start tunnel (blocks until failure, then exits — procd restarts) +start_tunnel 2>/dev/null || true + +log "EVENT=DAEMON_EXIT device=${DEVICE_ID}" +exit 0 diff --git a/gl-kit-connect/files/usr/sbin/connect-register.sh b/gl-kit-connect/files/usr/sbin/connect-register.sh new file mode 100644 index 0000000..379c4b1 --- /dev/null +++ b/gl-kit-connect/files/usr/sbin/connect-register.sh @@ -0,0 +1,58 @@ +#!/bin/sh +# connect-register.sh — Standalone hub registration (callable from wizard or cron) +# Usage: connect-register.sh [--force] +# Re-registers even if already assigned when --force is given. + +HUB_HOST="162.243.83.36" +HUB_PORT="8080" + +DEVICE_ID=$(cat /etc/busrouter/device-id 2>/dev/null || hostname | sed 's/[^a-zA-Z0-9_-]//g') +CURRENT_PORT=$(uci -q get kitconnect.main.tunnel_remote_port 2>/dev/null || echo "0") + +[ "$1" = "--force" ] && CURRENT_PORT="0" +[ "$CURRENT_PORT" != "0" ] && { + echo "Already registered (port ${CURRENT_PORT}). Use --force to re-register." + exit 0 +} + +echo "Registering device ${DEVICE_ID} with hub ${HUB_HOST}:${HUB_PORT}..." +resp=$(curl -s --connect-timeout 10 "http://${HUB_HOST}:${HUB_PORT}/api/register/${DEVICE_ID}" 2>/dev/null) + +[ -z "$resp" ] && { + echo "ERROR: Hub unreachable at ${HUB_HOST}:${HUB_PORT}" + exit 1 +} + +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) + +echo "" +echo " Device: ${DEVICE_ID}" +echo " Status: ${status:-unknown}" +echo " Port: ${port:-none}" +echo "" + +if [ -n "$port" ] && [ "$port" != "0" ]; then + uci set kitconnect.main.tunnel_remote_port="$port" + uci commit kitconnect + echo "Port ${port} saved to UCI config." +fi + +if [ -n "$tskey" ]; then + uci set kitconnect.main.tailscale_auth_key="$tskey" + uci commit kitconnect + echo "Tailscale auth key updated from hub." +fi + +if [ "$status" = "new" ]; then + echo "" + echo "============================================" + echo " ✓ Device registered successfully!" + echo " Port ${port} assigned for reverse SSH." + echo " Restart kit-connect to apply:" + echo " /etc/init.d/kitconnect restart" + echo "============================================" +elif [ "$status" = "existing" ]; then + echo "✓ Device was already registered (existing assignment confirmed)." +fi diff --git a/gl-kit-connect/files/usr/sbin/connect-wizard.sh b/gl-kit-connect/files/usr/sbin/connect-wizard.sh new file mode 100644 index 0000000..07fd6dc --- /dev/null +++ b/gl-kit-connect/files/usr/sbin/connect-wizard.sh @@ -0,0 +1,162 @@ +#!/bin/sh +# connect-wizard.sh — One-button Keylink IT fleet setup. +# Idempotent — safe to run multiple times. +# Usage: connect-wizard.sh [--auto] [--force] +# --auto Non-interactive mode (for postinst) +# --force Re-register even if already assigned + +set -e + +HUB_HOST="162.243.83.36" +HUB_PORT="8080" +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 " ⚠ $*"; } +fail() { 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") + # If hostname is generic, try to derive from model + if [ "$DEVICE_ID" = "OpenWrt" ] || [ "$DEVICE_ID" = "openwrt" ] || [ -z "$DEVICE_ID" ]; then + model=$(cat /tmp/sysinfo/model 2>/dev/null | tr ' ' '-' | sed 's/[^a-zA-Z0-9_-]//g' || echo "") + [ -n "$model" ] && DEVICE_ID="${model}-$(cat /sys/class/net/eth0/address 2>/dev/null | tr -d ':' | tail -c 6 || echo '000000')" + [ -z "$DEVICE_ID" ] && DEVICE_ID="GL-unknown" + fi +fi +mkdir -p /etc/busrouter +echo "$DEVICE_ID" > /etc/busrouter/device-id +ok "Device ID: ${DEVICE_ID}" + +# ── Step 2: Check prerequisites ──────────────────────────────── +step "Checking prerequisites..." + +MISSING="" +for cmd in curl ssh ssh-keygen; do + command -v "$cmd" >/dev/null 2>&1 || MISSING="${MISSING} ${cmd}" +done + +if [ -n "$MISSING" ]; then + fail "Missing:${MISSING}" + [ "$AUTO" = "1" ] && exit 1 + echo "" + echo " Install missing packages with:" + echo " opkg update && opkg install curl openssh-client" + exit 1 +fi +ok "All prerequisites found (curl, ssh)" + +# ── Step 3: SSH key ──────────────────────────────────────────── +step "Checking SSH key..." +KEY="/etc/kitconnect/connect_id_ed25519" +if [ ! -f "$KEY" ]; then + warn "Key not found at ${KEY}, generating..." + mkdir -p /etc/kitconnect + ssh-keygen -t ed25519 -f "$KEY" -N "" -C "kit-connect-${DEVICE_ID}" >/dev/null 2>&1 + ok "Generated new Ed25519 key" +else + ok "SSH key present" +fi +chmod 600 "$KEY" + +# ── Step 4: UCI config defaults ──────────────────────────────── +step "Configuring Keylink IT defaults..." + +# Ensure UCI config exists +if ! uci -q get kitconnect.main >/dev/null 2>&1; then + uci set kitconnect.main=kitconnect +fi + +uci -q set kitconnect.main.device_id="$DEVICE_ID" +uci -q set kitconnect.main.hub_host="$HUB_HOST" +uci -q set kitconnect.main.hub_port="$HUB_PORT" +uci -q set kitconnect.main.tunnel_enable='1' +uci -q set kitconnect.main.tunnel_remote_host="$HUB_HOST" +uci -q set kitconnect.main.tunnel_remote_user='node' +uci -q set kitconnect.main.tunnel_remote_ssh_port='22' +uci -q set kitconnect.main.tunnel_remote_port='0' +uci -q set kitconnect.main.tunnel_local_port='2223' +uci -q set kitconnect.main.tailscale_enable='1' +uci -q set kitconnect.main.tailscale_auth_key='tskey-auth-kJz8wqNVo211CNTRL-GNL5EFjp5aWQcaWPSVn2aW9TNworKUNBV' +uci -q set kitconnect.main.tailscale_hostname="$DEVICE_ID" +uci -q set kitconnect.main.watchdog_interval='60' +uci -q set kitconnect.main.forward_fail_limit='2' +uci commit kitconnect +ok "UCI config written" + +# ── Step 5: Register with hub ────────────────────────────────── +step "Registering with fleet hub (${HUB_HOST}:${HUB_PORT})..." + +REG_FLAG="" +[ "$FORCE" = "1" ] && REG_FLAG="--force" + +resp=$(curl -s --connect-timeout 10 "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 + uci set kitconnect.main.tunnel_remote_port="$port" + uci commit kitconnect + ok "Hub assigned port ${port} (status: ${status})" + fi + if [ -n "$tskey" ]; then + uci set kitconnect.main.tailscale_auth_key="$tskey" + uci commit kitconnect + ok "Tailscale key configured" + fi +fi + +# ── Step 6: Enable & start service ───────────────────────────── +step "Enabling kit-connect service..." +/etc/init.d/kitconnect enable 2>/dev/null && ok "Enabled at boot" || warn "Could not enable (may already be enabled)" + +step "Starting kit-connect..." +if /etc/init.d/kitconnect start 2>/dev/null; then + ok "Service started" +else + warn "Service start returned non-zero (check logread for details)" +fi + +# ── Done ─────────────────────────────────────────────────────── +echo "" +echo " ╔══════════════════════════════════════════╗" +echo " ║ SETUP COMPLETE ║" +echo " ╠══════════════════════════════════════════╣" +echo " ║ Device: $(printf '%-30s' "$DEVICE_ID")║" + +ASSIGNED=$(uci -q get kitconnect.main.tunnel_remote_port 2>/dev/null || echo "pending") +echo " ║ Port: $(printf '%-30s' "$ASSIGNED")║" +echo " ║ Hub: $(printf '%-30s' "${HUB_HOST}:${HUB_PORT}")║" +echo " ╠══════════════════════════════════════════╣" +echo " ║ Dashboard: http://$(hostname)/kitconnect/$(printf ' ')%s║" "" +echo " ║ Status: /etc/init.d/kitconnect status║" +echo " ╚══════════════════════════════════════════╝" +echo "" +echo " The daemon is now running under procd supervision." +echo " If it crashes, procd will restart it automatically." +echo "" + +exit 0 diff --git a/gl-kit-connect/files/www/kitconnect/index.html b/gl-kit-connect/files/www/kitconnect/index.html new file mode 100644 index 0000000..f1feb51 --- /dev/null +++ b/gl-kit-connect/files/www/kitconnect/index.html @@ -0,0 +1,185 @@ + + +
+ + ++ Configures all Keylink IT defaults — device ID, fleet hub, Tailscale, reverse SSH tunnel. + Safe to run multiple times. +
+ + ++ Configures Keylink IT fleet defaults — device ID, hub, Tailscale, reverse SSH. + Safe to run multiple times. +
+ + +