Files
openclaw-skills/workspace-security/vt-monitor/scripts/check.sh
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

112 lines
3.9 KiB
Bash
Executable File

#!/bin/bash
# Check VT-Sentinel activity — incremental (byte-offset tracking)
# Only reads NEW log lines since last check
set -e
LOG_FILE="/tmp/openclaw/vt-sentinel.log"
STATE_DIR="/home/node/.openclaw/workspace-security/memory"
OFFSET_FILE="$STATE_DIR/vt-log-offset"
mkdir -p "$STATE_DIR"
if [ ! -f "$LOG_FILE" ]; then
echo '{"error":"Gateway log not found"}'
exit 1
fi
# Current file size
FILE_SIZE=$(stat -c%s "$LOG_FILE")
# Last read offset (0 = first run, reads last 1MB as bootstrap)
LAST_OFFSET=0
if [ -f "$OFFSET_FILE" ]; then
LAST_OFFSET=$(cat "$OFFSET_FILE")
fi
# If file shrank (log rotation), reset
if [ "$LAST_OFFSET" -gt "$FILE_SIZE" ]; then
LAST_OFFSET=0
fi
# Dedicated log is small — no need for bootstrap limit
SKIP=$LAST_OFFSET
BYTES_NEW=$((FILE_SIZE - SKIP))
# Nothing new
if [ "$BYTES_NEW" -le 0 ]; then
echo "$FILE_SIZE" > "$OFFSET_FILE"
echo '{"totalEvents":0,"alerts":false,"summary":{"uploads":0,"upload_complete":0,"upload_failed":0,"cache_hits":0,"verdicts":{"clean":0,"malicious":0,"suspicious":0},"quarantined":0,"blocked":0},"events":[]}'
exit 0
fi
# Read only new bytes, grep VT-Sentinel
TMPFILE=$(mktemp)
trap "rm -f $TMPFILE" EXIT
tail -c +"$((SKIP + 1))" "$LOG_FILE" | grep '"subsystem.*gateway"' | grep '\[VT-Sentinel\]' | while IFS= read -r line; do
TIMESTAMP=$(echo "$line" | grep -oP '"date":"\K[^"]*' | head -1)
MESSAGE=$(echo "$line" | grep -oP '\[VT-Sentinel\] \K[^"\\]*' | head -1)
[ -z "$TIMESTAMP" ] || [ -z "$MESSAGE" ] && continue
CATEGORY="info"
case "$MESSAGE" in
*"Unknown"*"uploading"*) CATEGORY="upload" ;;
*"Uploaded for analysis"*) CATEGORY="upload_complete" ;;
*"Upload failed"*) CATEGORY="upload_failed" ;;
*"Cache hit"*) CATEGORY="cache_hit" ;;
*"MALICIOUS"*) CATEGORY="verdict_malicious" ;;
*"SUSPICIOUS"*) CATEGORY="verdict_suspicious" ;;
*"clean"*|*"BENIGN"*) CATEGORY="verdict_clean" ;;
*"quarantin"*) CATEGORY="quarantine" ;;
*"BLOCKED"*|*"blocked"*) CATEGORY="blocked" ;;
*"Watching:"*) CATEGORY="config" ;;
*"Plugin loaded"*|*"Service stopped"*|*"Auto-"*|*"Registered"*|*"Using"*) CATEGORY="lifecycle" ;;
esac
jq -cn --arg ts "$TIMESTAMP" --arg msg "$MESSAGE" --arg cat "$CATEGORY" \
'{"timestamp":$ts,"message":$msg,"category":$cat}'
done > "$TMPFILE"
# Save new offset
echo "$FILE_SIZE" > "$OFFSET_FILE"
TOTAL=$(wc -l < "$TMPFILE" | tr -d ' ')
[ -z "$TOTAL" ] && TOTAL=0
if [ "$TOTAL" -eq 0 ]; then
echo '{"totalEvents":0,"alerts":false,"summary":{"uploads":0,"upload_complete":0,"upload_failed":0,"cache_hits":0,"verdicts":{"clean":0,"malicious":0,"suspicious":0},"quarantined":0,"blocked":0},"events":[]}'
exit 0
fi
EVENTS_JSON=$(jq -s '.' "$TMPFILE")
count_cat() {
local c
c=$(grep -c "\"category\":\"$1\"" "$TMPFILE" 2>/dev/null || true)
echo "${c:-0}"
}
jq -n \
--argjson events "$EVENTS_JSON" \
--argjson total "$TOTAL" \
--argjson uploads "$(count_cat upload)" \
--argjson upload_complete "$(count_cat upload_complete)" \
--argjson upload_failed "$(count_cat upload_failed)" \
--argjson cache_hits "$(count_cat cache_hit)" \
--argjson clean "$(count_cat verdict_clean)" \
--argjson malicious "$(count_cat verdict_malicious)" \
--argjson suspicious "$(count_cat verdict_suspicious)" \
--argjson quarantined "$(count_cat quarantine)" \
--argjson blocked "$(count_cat blocked)" \
'{
totalEvents: $total,
summary: {
uploads: $uploads, upload_complete: $upload_complete, upload_failed: $upload_failed,
cache_hits: $cache_hits,
verdicts: {clean: $clean, malicious: $malicious, suspicious: $suspicious},
quarantined: $quarantined, blocked: $blocked
},
alerts: ($malicious > 0 or $suspicious > 0 or $quarantined > 0 or $blocked > 0),
events: $events
}'