94 lines
2.6 KiB
Bash
Executable File
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
|