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