secubox-openwrt/package/secubox/secubox-mesh/files/usr/sbin/secuboxctl
CyberMind-FR cd6af3edff feat(secubox-mesh): Add OpenWrt mesh daemon with topology management
Port secuboxd from Debian/Go to OpenWrt shell implementation:
- secuboxd daemon with Unix control socket at /var/run/secuboxd/topo.sock
- secuboxctl CLI compatible with Debian version interface
- Mesh libraries: topology, discovery, election, telemetry, control
- Mesh gate election with weighted scoring (uptime, peers, CPU, memory, role)
- mDNS service discovery (_secubox._udp.local) via umdns
- DID integration via mirrornet identity library
- RPCD handler with 11 ubus methods for LuCI integration
- procd init script with respawn and network triggers
- UCI config sections: mesh, node, telemetry, discovery

Fixes subprocess state access for socat handler by saving daemon state to file.

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

286 lines
6.3 KiB
Bash
Executable File

#!/bin/sh
# SecuBox Mesh Control CLI (secuboxctl)
# Communicates with secuboxd via Unix control socket
# CyberMind — SecuBox — 2026
SOCKET="/var/run/secuboxd/topo.sock"
VERSION="1.0.0"
# Send command to daemon and get response
send_command() {
local cmd="$1"
if [ ! -S "$SOCKET" ]; then
echo '{"error":"Daemon not running","socket":"'"$SOCKET"'"}'
return 1
fi
# Use socat if available
if command -v socat >/dev/null 2>&1; then
echo "$cmd" | socat - UNIX-CONNECT:"$SOCKET"
else
# Fallback: use FIFO approach
local fifo_in="/var/run/secuboxd/socket_in"
local fifo_out="/var/run/secuboxd/socket_out"
if [ -p "$fifo_in" ] && [ -p "$fifo_out" ]; then
echo "$cmd" > "$fifo_in"
timeout 5 cat "$fifo_out" 2>/dev/null || echo '{"error":"Timeout"}'
else
echo '{"error":"Socket communication not available"}'
return 1
fi
fi
}
# Format JSON output for display
format_output() {
local json="$1"
local format="${2:-json}"
case "$format" in
json)
if command -v jq >/dev/null 2>&1; then
echo "$json" | jq .
else
echo "$json"
fi
;;
table)
# Simple table formatting using jsonfilter
echo "$json"
;;
*)
echo "$json"
;;
esac
}
# Commands
cmd_status() {
local response
response=$(send_command "mesh.status")
format_output "$response" "$1"
}
cmd_peers() {
local response
response=$(send_command "mesh.peers")
if [ "$1" = "-q" ] || [ "$1" = "--quiet" ]; then
echo "$response" | jsonfilter -e '@[*].did' 2>/dev/null | wc -l
else
format_output "$response" "$1"
fi
}
cmd_topology() {
local response
response=$(send_command "mesh.topology")
format_output "$response" "$1"
}
cmd_nodes() {
local response
response=$(send_command "mesh.nodes")
format_output "$response" "$1"
}
cmd_info() {
local response
response=$(send_command "node.info")
format_output "$response" "$1"
}
cmd_rotate() {
local response
response=$(send_command "node.rotate")
local success
success=$(echo "$response" | jsonfilter -e '@.success' 2>/dev/null)
if [ "$success" = "true" ]; then
echo "Key rotation successful"
echo "$response" | jsonfilter -e '@.new_expiry' 2>/dev/null
return 0
else
echo "Key rotation failed"
echo "$response" | jsonfilter -e '@.error' 2>/dev/null
return 1
fi
}
cmd_telemetry() {
local response
response=$(send_command "telemetry.latest")
format_output "$response" "$1"
}
cmd_ping() {
local response
response=$(send_command "ping")
if echo "$response" | grep -q '"pong":true'; then
echo "Daemon is running"
return 0
else
echo "Daemon not responding"
return 1
fi
}
# Service management
cmd_start() {
if pgrep -x secuboxd >/dev/null 2>&1; then
echo "secuboxd is already running"
return 1
fi
/etc/init.d/secuboxd start
sleep 1
if pgrep -x secuboxd >/dev/null 2>&1; then
echo "secuboxd started"
return 0
else
echo "Failed to start secuboxd"
return 1
fi
}
cmd_stop() {
/etc/init.d/secuboxd stop
sleep 1
if pgrep -x secuboxd >/dev/null 2>&1; then
echo "secuboxd still running, killing..."
pkill -9 secuboxd
fi
echo "secuboxd stopped"
}
cmd_restart() {
cmd_stop
sleep 1
cmd_start
}
# Show usage
usage() {
cat <<EOF
SecuBox Mesh Control CLI (secuboxctl) v$VERSION
Usage: secuboxctl <command> [options]
Mesh Commands:
mesh status Show mesh status (state, role, peers, gate)
mesh peers List connected peers
mesh topology Get mesh topology graph
mesh nodes List all known nodes
Node Commands:
node info Show this node's information
node rotate Rotate node keys
Telemetry:
telemetry latest Get latest system telemetry
Service Commands:
start Start secuboxd daemon
stop Stop secuboxd daemon
restart Restart secuboxd daemon
ping Check if daemon is running
Options:
-f, --format Output format: json (default), table
-q, --quiet Minimal output
-h, --help Show this help
-v, --version Show version
Examples:
secuboxctl mesh status
secuboxctl mesh peers -f table
secuboxctl node info
secuboxctl telemetry latest
Socket: $SOCKET
EOF
}
# Main
main() {
local cmd="$1"
shift
case "$cmd" in
mesh)
local subcmd="$1"
shift
case "$subcmd" in
status) cmd_status "$@" ;;
peers) cmd_peers "$@" ;;
topology) cmd_topology "$@" ;;
nodes) cmd_nodes "$@" ;;
*) echo "Unknown mesh command: $subcmd"; usage; exit 1 ;;
esac
;;
node)
local subcmd="$1"
shift
case "$subcmd" in
info) cmd_info "$@" ;;
rotate) cmd_rotate "$@" ;;
*) echo "Unknown node command: $subcmd"; usage; exit 1 ;;
esac
;;
telemetry)
local subcmd="$1"
shift
case "$subcmd" in
latest) cmd_telemetry "$@" ;;
*) echo "Unknown telemetry command: $subcmd"; usage; exit 1 ;;
esac
;;
status)
cmd_status "$@"
;;
peers)
cmd_peers "$@"
;;
topology)
cmd_topology "$@"
;;
start)
cmd_start
;;
stop)
cmd_stop
;;
restart)
cmd_restart
;;
ping)
cmd_ping
;;
-h|--help|help)
usage
exit 0
;;
-v|--version|version)
echo "secuboxctl $VERSION (OpenWrt)"
exit 0
;;
"")
usage
exit 0
;;
*)
echo "Unknown command: $cmd"
usage
exit 1
;;
esac
}
main "$@"