Create test.sh to ease admin testing
This commit is contained in:
236
test.sh
Executable file
236
test.sh
Executable file
@ -0,0 +1,236 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# BaldCanary Diagnostic / Webhook Test Script
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
APP_ROOT="/opt/baldcanary"
|
||||||
|
APP_DB="${APP_ROOT}/db/baldcanary.sqlite"
|
||||||
|
DISPATCHER_SERVICE="baldcanary-dispatcher"
|
||||||
|
OPENCANARY_SERVICE="opencanary"
|
||||||
|
COLLECTOR_SERVICE="baldcanary-decoylog"
|
||||||
|
NGINX_SERVICE="nginx"
|
||||||
|
|
||||||
|
fail() {
|
||||||
|
echo "ERROR: $*" >&2
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
section() {
|
||||||
|
echo
|
||||||
|
echo "============================================================"
|
||||||
|
echo "$*"
|
||||||
|
echo "============================================================"
|
||||||
|
}
|
||||||
|
|
||||||
|
run() {
|
||||||
|
echo "+ $*"
|
||||||
|
"$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
require_root() {
|
||||||
|
if [[ "${EUID}" -ne 0 ]]; then
|
||||||
|
fail "Run this script as root: sudo $0"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_file() {
|
||||||
|
local file="$1"
|
||||||
|
if [[ -e "$file" ]]; then
|
||||||
|
echo "OK: $file exists"
|
||||||
|
ls -lh "$file"
|
||||||
|
else
|
||||||
|
echo "MISSING: $file"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite_query() {
|
||||||
|
local query="$1"
|
||||||
|
|
||||||
|
if [[ ! -f "$APP_DB" ]]; then
|
||||||
|
echo "SQLite DB not found: $APP_DB"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
sqlite3 -header -column "$APP_DB" "$query"
|
||||||
|
}
|
||||||
|
|
||||||
|
insert_test_alert() {
|
||||||
|
section "Insert Test Alert"
|
||||||
|
|
||||||
|
local now
|
||||||
|
now="$(date -u '+%Y-%m-%d %H:%M:%S')"
|
||||||
|
|
||||||
|
sqlite3 "$APP_DB" "
|
||||||
|
INSERT INTO events(source,severity,event_type,src_ip,path,matched_bait,raw_json)
|
||||||
|
VALUES(
|
||||||
|
'system',
|
||||||
|
'high',
|
||||||
|
'test_alert',
|
||||||
|
'127.0.0.1',
|
||||||
|
'manual-test',
|
||||||
|
'manual webhook test',
|
||||||
|
'{\"test\":true,\"created_by\":\"test.sh\",\"created_at\":\"${now}\"}'
|
||||||
|
);
|
||||||
|
"
|
||||||
|
|
||||||
|
local event_id
|
||||||
|
event_id="$(sqlite3 "$APP_DB" "SELECT id FROM events ORDER BY id DESC LIMIT 1;")"
|
||||||
|
|
||||||
|
echo "Inserted test alert event ID: $event_id"
|
||||||
|
echo "Waiting 15 seconds for dispatcher..."
|
||||||
|
sleep 15
|
||||||
|
|
||||||
|
section "Alert Log Result For Test Event"
|
||||||
|
sqlite_query "
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
event_id,
|
||||||
|
target_id,
|
||||||
|
attempted_at,
|
||||||
|
ok,
|
||||||
|
response_code,
|
||||||
|
substr(response_body,1,160) AS response_body,
|
||||||
|
substr(error,1,250) AS error
|
||||||
|
FROM alert_log
|
||||||
|
WHERE event_id = ${event_id}
|
||||||
|
ORDER BY id DESC;
|
||||||
|
"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
require_root
|
||||||
|
|
||||||
|
section "BaldCanary Diagnostic Test"
|
||||||
|
|
||||||
|
echo "Host: $(hostname)"
|
||||||
|
echo "Time: $(date)"
|
||||||
|
echo "User: $(whoami)"
|
||||||
|
|
||||||
|
section "Required Files"
|
||||||
|
|
||||||
|
check_file "$APP_DB"
|
||||||
|
check_file "${APP_ROOT}/config/opencanary_event_labels.json"
|
||||||
|
check_file "${APP_ROOT}/scripts/dispatch_alerts.py"
|
||||||
|
check_file "${APP_ROOT}/scripts/opencanary_collector.py"
|
||||||
|
check_file "/usr/local/bin/baldcanary"
|
||||||
|
check_file "/etc/opencanaryd/opencanary.conf"
|
||||||
|
|
||||||
|
section "Service Status"
|
||||||
|
|
||||||
|
systemctl --no-pager --full status "$NGINX_SERVICE" || true
|
||||||
|
systemctl --no-pager --full status "$OPENCANARY_SERVICE" || true
|
||||||
|
systemctl --no-pager --full status "$COLLECTOR_SERVICE" || true
|
||||||
|
systemctl --no-pager --full status "$DISPATCHER_SERVICE" || true
|
||||||
|
|
||||||
|
section "Listening Ports"
|
||||||
|
|
||||||
|
ss -ltnup || true
|
||||||
|
|
||||||
|
section "SQLite Integrity"
|
||||||
|
|
||||||
|
sqlite3 "$APP_DB" "PRAGMA integrity_check;" || true
|
||||||
|
|
||||||
|
section "BaldCanary Settings"
|
||||||
|
|
||||||
|
sqlite_query "
|
||||||
|
SELECT key, value, updated_at
|
||||||
|
FROM settings
|
||||||
|
ORDER BY key;
|
||||||
|
" || true
|
||||||
|
|
||||||
|
section "Webhook Targets"
|
||||||
|
|
||||||
|
sqlite_query "
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
name,
|
||||||
|
type,
|
||||||
|
enabled,
|
||||||
|
created_at,
|
||||||
|
substr(url,1,80) || CASE WHEN length(url) > 80 THEN '...' ELSE '' END AS url_preview
|
||||||
|
FROM webhook_targets
|
||||||
|
ORDER BY id;
|
||||||
|
" || true
|
||||||
|
|
||||||
|
section "Recent Events"
|
||||||
|
|
||||||
|
sqlite_query "
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
event_time,
|
||||||
|
source,
|
||||||
|
severity,
|
||||||
|
event_type,
|
||||||
|
src_ip,
|
||||||
|
path,
|
||||||
|
matched_bait
|
||||||
|
FROM events
|
||||||
|
ORDER BY id DESC
|
||||||
|
LIMIT 15;
|
||||||
|
" || true
|
||||||
|
|
||||||
|
section "Recent Alert Attempts"
|
||||||
|
|
||||||
|
sqlite_query "
|
||||||
|
SELECT
|
||||||
|
id,
|
||||||
|
event_id,
|
||||||
|
target_id,
|
||||||
|
attempted_at,
|
||||||
|
ok,
|
||||||
|
response_code,
|
||||||
|
substr(response_body,1,160) AS response_body,
|
||||||
|
substr(error,1,250) AS error
|
||||||
|
FROM alert_log
|
||||||
|
ORDER BY id DESC
|
||||||
|
LIMIT 15;
|
||||||
|
" || true
|
||||||
|
|
||||||
|
section "Dispatcher Python Syntax Check"
|
||||||
|
|
||||||
|
if [[ -f "${APP_ROOT}/scripts/dispatch_alerts.py" ]]; then
|
||||||
|
run python3 -m py_compile "${APP_ROOT}/scripts/dispatch_alerts.py" || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
section "Collector Python Syntax Check"
|
||||||
|
|
||||||
|
if [[ -f "${APP_ROOT}/scripts/opencanary_collector.py" ]]; then
|
||||||
|
run python3 -m py_compile "${APP_ROOT}/scripts/opencanary_collector.py" || true
|
||||||
|
fi
|
||||||
|
|
||||||
|
section "Recent Dispatcher Logs"
|
||||||
|
|
||||||
|
journalctl -u "$DISPATCHER_SERVICE" -n 80 --no-pager || true
|
||||||
|
|
||||||
|
section "Recent Collector Logs"
|
||||||
|
|
||||||
|
journalctl -u "$COLLECTOR_SERVICE" -n 60 --no-pager || true
|
||||||
|
|
||||||
|
section "Recent OpenCanary Logs"
|
||||||
|
|
||||||
|
journalctl -u "$OPENCANARY_SERVICE" -n 60 --no-pager || true
|
||||||
|
|
||||||
|
section "Optional Live Webhook Test"
|
||||||
|
|
||||||
|
echo "This will insert a new high-severity test event and wait for the dispatcher."
|
||||||
|
read -r -p "Insert test alert now? [y/N] " answer
|
||||||
|
|
||||||
|
case "$answer" in
|
||||||
|
y|Y|yes|YES)
|
||||||
|
insert_test_alert
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Skipped test alert insertion."
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
section "Done"
|
||||||
|
|
||||||
|
echo "If Teams did not receive the alert, check:"
|
||||||
|
echo " 1. webhook_targets has enabled=1"
|
||||||
|
echo " 2. alert_log has ok=1 and a 2xx response_code"
|
||||||
|
echo " 3. baldcanary-dispatcher logs show no Python errors"
|
||||||
|
echo " 4. the Teams/Power Automate workflow accepts the payload schema"
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
Reference in New Issue
Block a user