Files
memex/system/security-monitor.sh

94 lines
2.6 KiB
Bash
Executable File

#!/bin/bash
# Security Monitor Script for OpenClaw Workspace
# Created: 2026-03-13
# Purpose: Hourly and Daily security checks
LOG_FILE="/home/amr/.openclaw/workspace/memex/7_system/security.log"
DATE=$(date "+%Y-%m-%d %H:%M:%S")
log_msg() {
echo "[$DATE] $1" >> "$LOG_FILE"
}
check_hourly() {
log_msg "--- HOURLY SECURITY CHECK START ---"
# 1. Disk usage
DISK_USAGE=$(df -h / | awk 'NR==2 {print $5}' | sed 's/%//')
if [ "$DISK_USAGE" -gt 90 ]; then
log_msg "ALERT: Disk usage at $DISK_USAGE%"
else
log_msg "Disk usage: $DISK_USAGE%"
fi
# 2. Failed logins (>5 threshold)
FAILED_LOGINS=$(grep "Failed password" /var/log/auth.log 2>/dev/null | wc -l)
if [ "$FAILED_LOGINS" -gt 5 ]; then
log_msg "ALERT: $FAILED_LOGINS failed login attempts detected"
else
log_msg "Failed logins: $FAILED_LOGINS"
fi
# 3. UFW status
if command -v ufw >/dev/null; then
UFW_STATUS=$(sudo ufw status | grep "Status: active" | wc -l)
if [ "$UFW_STATUS" -eq 0 ]; then
log_msg "ALERT: UFW is INACTIVE"
else
log_msg "UFW: Active"
fi
else
log_msg "UFW: Not installed"
fi
log_msg "--- HOURLY SECURITY CHECK END ---"
}
check_daily() {
log_msg "--- DAILY SECURITY CHECK START ---"
# 1. SSH key-only verification
SSH_AUTH_METHODS=$(grep "^PasswordAuthentication" /etc/ssh/sshd_config | awk '{print $2}')
if [ "$SSH_AUTH_METHODS" == "yes" ]; then
log_msg "ALERT: PasswordAuthentication is enabled in SSH"
else
log_msg "SSH Auth: Key-only (likely)"
fi
# 2. fail2ban stats
if command -v fail2ban-client >/dev/null; then
F2B_STATS=$(sudo fail2ban-client status sshd 2>/dev/null | grep "Currently banned" | awk '{print $NF}')
log_msg "Fail2ban: $F2B_STATS currently banned IPs"
else
log_msg "Fail2ban: Not installed"
fi
# 3. Port scan (22, 3000 expected)
if command -v netstat >/dev/null; then
OPEN_PORTS=$(sudo netstat -tulpn | grep LISTEN | awk '{print $4}' | awk -F: '{print $NF}' | sort -u | tr '\n' ' ')
log_msg "Open Ports: $OPEN_PORTS"
fi
# 4. Docker exposure check
if command -v docker >/dev/null; then
DOCKER_CONTAINERS=$(docker ps --format "{{.Names}}: {{.Ports}}")
log_msg "Docker Status: $DOCKER_CONTAINERS"
fi
log_msg "--- DAILY SECURITY CHECK END ---"
}
case "$1" in
hourly)
check_hourly
;;
daily)
check_daily
;;
*)
echo "Usage: $0 {hourly|daily}"
exit 1
;;
esac