Files
b3nw 3b7d6bb67c Initial commit: custom OpenClaw skills from docker-test
- workspace: capmetro-monitor, github-notifications, model-selector
- workspace-security: vt-monitor, monitor-unauthorized
- workspace-home: cron-manager, monitor-unauthorized
- extensions: vt-sentinel (VT-Sentinel plugin)

Includes sync.sh for pull/push, README, AGENTS.md, .gitignore.
2026-02-16 15:32:44 +00:00

130 lines
4.5 KiB
Bash
Executable File

#!/bin/bash
# Unauthorized connection monitor — cron wrapper
# Orchestrates: log-splitter → check → formatted output with agent instructions
#
# Output is structured for the OpenClaw agent to parse and act on.
# The agent reads SKILL.md for detailed instructions on thread management.
#
# Flow:
# 1. Run log-splitter to extract new unauthorized entries from gateway log
# 2. Check thread index status (does the agent need to refresh it?)
# 3. Run check to categorize IPs as new or returning
# 4. Format output with ACTION markers the agent will parse
#
# Exit: always 0. Empty output = nothing to do (agent replies NO_REPLY)
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# --- Step 1: Split unauthorized entries from gateway log ---
SPLIT_RESULT=$("$SCRIPT_DIR/log-splitter.sh" 2>/dev/null) || true
# --- Step 2: Check thread index ---
INDEX_STATUS=$("$SCRIPT_DIR/index-threads.sh" needs-refresh 2>/dev/null) || INDEX_STATUS="missing"
# --- Step 3: Check for new/returning unauthorized connections ---
CHECK_RESULT=$("$SCRIPT_DIR/check.sh" 2>/dev/null) || CHECK_RESULT='{}'
NEW_COUNT=$(echo "$CHECK_RESULT" | jq '.new_ips | length' 2>/dev/null || echo 0)
RETURNING_COUNT=$(echo "$CHECK_RESULT" | jq '.returning_ips | length' 2>/dev/null || echo 0)
TOTAL=$(echo "$CHECK_RESULT" | jq '.total_events' 2>/dev/null || echo 0)
# Nothing to report
if [ "$NEW_COUNT" -eq 0 ] && [ "$RETURNING_COUNT" -eq 0 ] && [ "$INDEX_STATUS" = "fresh" ]; then
exit 0
fi
OUTPUT=""
# --- Thread index refresh needed ---
if [ "$INDEX_STATUS" != "fresh" ]; then
OUTPUT+="ACTION:INDEX_THREADS
The thread index is ${INDEX_STATUS}. Before processing connections, refresh the thread index.
See SKILL.md section \"Thread Index Management\" for instructions.
---END_ACTION---
"
fi
# --- New IPs: agent should create threads ---
if [ "$NEW_COUNT" -gt 0 ]; then
OUTPUT+="
🚨 UNAUTHORIZED CONNECTIONS — ${NEW_COUNT} NEW IP(s) DETECTED
============================================================
"
# Emit each new IP as an ACTION block
for i in $(seq 0 $((NEW_COUNT - 1))); do
IP=$(echo "$CHECK_RESULT" | jq -r ".new_ips[$i].ip")
FIRST_SEEN=$(echo "$CHECK_RESULT" | jq -r ".new_ips[$i].first_seen")
ATTEMPTS=$(echo "$CHECK_RESULT" | jq -r ".new_ips[$i].attempts")
REASON=$(echo "$CHECK_RESULT" | jq -r ".new_ips[$i].reason")
ORIGIN=$(echo "$CHECK_RESULT" | jq -r ".new_ips[$i].origin")
UA=$(echo "$CHECK_RESULT" | jq -r ".new_ips[$i].user_agent")
REMOTE=$(echo "$CHECK_RESULT" | jq -r ".new_ips[$i].remote")
OUTPUT+="
ACTION:NEW_THREAD
IP:${IP}
---
🚨 **NEW UNAUTHORIZED CONNECTION**
**IP:** \`${IP}\`
**First Seen:** ${FIRST_SEEN}
**Attempts:** ${ATTEMPTS}
**Reason:** ${REASON}
**Origin:** ${ORIGIN}
**User Agent:** ${UA}
**Remote (proxy):** ${REMOTE}
_New IP — thread created by security monitor._
---END_ACTION---
"
done
fi
# --- Returning IPs: agent should update existing threads ---
if [ "$RETURNING_COUNT" -gt 0 ]; then
OUTPUT+="
⚠️ RETURNING CONNECTIONS — ${RETURNING_COUNT} KNOWN IP(s)
==========================================================
"
for i in $(seq 0 $((RETURNING_COUNT - 1))); do
IP=$(echo "$CHECK_RESULT" | jq -r ".returning_ips[$i].ip")
LATEST=$(echo "$CHECK_RESULT" | jq -r ".returning_ips[$i].latest")
NEW_ATTEMPTS=$(echo "$CHECK_RESULT" | jq -r ".returning_ips[$i].new_attempts")
TOTAL_ATTEMPTS=$(echo "$CHECK_RESULT" | jq -r ".returning_ips[$i].total_attempts")
REASON=$(echo "$CHECK_RESULT" | jq -r ".returning_ips[$i].reason")
ORIGIN=$(echo "$CHECK_RESULT" | jq -r ".returning_ips[$i].origin")
UA=$(echo "$CHECK_RESULT" | jq -r ".returning_ips[$i].user_agent")
REMOTE=$(echo "$CHECK_RESULT" | jq -r ".returning_ips[$i].remote")
# Look up existing thread
THREAD_INFO=$("$SCRIPT_DIR/index-threads.sh" lookup "$IP" 2>/dev/null) || THREAD_INFO=""
SESSION_KEY=""
if [ -n "$THREAD_INFO" ]; then
SESSION_KEY=$(echo "$THREAD_INFO" | jq -r '.session_key // empty')
fi
OUTPUT+="
ACTION:UPDATE_THREAD
IP:${IP}
SESSION_KEY:${SESSION_KEY}
---
⚠️ **RETURNING UNAUTHORIZED CONNECTION**
**IP:** \`${IP}\`
**Latest Attempt:** ${LATEST}
**New Attempts (this period):** ${NEW_ATTEMPTS}
**Total Attempts (all time):** ${TOTAL_ATTEMPTS}
**Reason:** ${REASON}
**Origin:** ${ORIGIN}
**User Agent:** ${UA}
**Remote (proxy):** ${REMOTE}
_Recurring access attempt — updated by security monitor._
---END_ACTION---
"
done
fi
echo -e "$OUTPUT"