Securing CloudPanel on Ubuntu 24.04 Part 9
20/11/2024 20/11/2024 security 5 mins read
Table Of Contents
Part 9: Comprehensive Security Auditing and Performance Monitoring #
Let’s create an integrated monitoring and auditing system:
# Create comprehensive monitoring scriptsudo nano /usr/local/bin/cloudpanel-security-monitor.sh
#
#!/bin/bash
# Initialize paths and configurationCP_HOME="/home/clp"DB_PATH="${CP_HOME}/htdocs/app/data/db.sq3"LOG_DIR="${CP_HOME}/logs/monitoring"AUDIT_DIR="${CP_HOME}/logs/audit"
# Create necessary directoriesmkdir -p "$LOG_DIR" "$AUDIT_DIR"
# Function to record system metrics in CloudPanel's databaserecord_system_metrics() { local timestamp=$(date '+%Y-%m-%d %H:%M:%S')
# Record CPU usage local cpu_usage=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}') sqlite3 "$DB_PATH" " INSERT INTO instance_cpu (created_at, value) VALUES ('$timestamp', $cpu_usage);"
# Record memory usage local memory_usage=$(free | grep Mem | awk '{print ($3/$2 * 100)}') sqlite3 "$DB_PATH" " INSERT INTO instance_memory (created_at, value) VALUES ('$timestamp', $memory_usage);"
# Record load averages local load_1min=$(uptime | awk '{print $(NF-2)}' | tr -d ',') local load_5min=$(uptime | awk '{print $(NF-1)}' | tr -d ',') local load_15min=$(uptime | awk '{print $NF}')
sqlite3 "$DB_PATH" " INSERT INTO instance_load_average (created_at, period, value) VALUES ('$timestamp', 1, $load_1min), ('$timestamp', 5, $load_5min), ('$timestamp', 15, $load_15min);"
# Record disk usage for each mount point df -P | grep '^/' | while read filesystem size used avail use mountpoint; do sqlite3 "$DB_PATH" " INSERT INTO instance_disk_usage (created_at, disk, value) VALUES ('$timestamp', '$mountpoint', ${use%\%});" done}
# Function to analyze security events from CloudPanel's event tableanalyze_security_events() { echo "Analyzing security events..."
# Get recent security events sqlite3 "$DB_PATH" " SELECT created_at, user_name, user_role, event_name, event_data, source_ip_address, user_agent FROM event WHERE created_at > datetime('now', '-1 hour') ORDER BY created_at DESC;" | while IFS='|' read -r timestamp username role event_name data ip agent; do
# Analyze for suspicious patterns case "$event_name" in "login_failed") check_brute_force_attempts "$username" "$ip" ;; "file_modified") verify_file_changes "$data" ;; "config_changed") audit_configuration_change "$username" "$data" ;; esac done}
# Function to check for brute force attemptscheck_brute_force_attempts() { local username="$1" local ip="$2"
# Count recent failed login attempts local failed_attempts=$(sqlite3 "$DB_PATH" " SELECT COUNT(*) FROM event WHERE event_name = 'login_failed' AND source_ip_address = '$ip' AND created_at > datetime('now', '-1 hour');")
if [ "$failed_attempts" -gt 5 ]; then # Log the security incident log_security_incident "Possible brute force attack" \ "Multiple failed login attempts from IP: $ip targeting user: $username"
# Block the IP address through CloudPanel's firewall sqlite3 "$DB_PATH" " INSERT INTO blocked_ip ( site_id, created_at, updated_at, ip ) VALUES ( NULL, datetime('now'), datetime('now'), '$ip' );" fi}
# Function to verify file changesverify_file_changes() { local file_data="$1"
# Extract file path from event data local file_path=$(echo "$file_data" | jq -r '.path')
if [ -f "$file_path" ]; then # Calculate current file hash local current_hash=$(sha256sum "$file_path" | cut -d' ' -f1)
# Compare with expected hash if available if [ -f "${file_path}.hash" ]; then local expected_hash=$(cat "${file_path}.hash") if [ "$current_hash" != "$expected_hash" ]; then log_security_incident "Unexpected file modification" \ "File $file_path has been modified unexpectedly" fi else # Store initial hash for future comparison echo "$current_hash" > "${file_path}.hash" fi fi}
# Function to audit configuration changesaudit_configuration_change() { local username="$1" local config_data="$2"
# Log the configuration change echo "[$(date '+%Y-%m-%d %H:%M:%S')] User $username modified configuration: $config_data" >> "$AUDIT_DIR/config_changes.log"
# Store in CloudPanel's event system sqlite3 "$DB_PATH" " INSERT INTO event ( created_at, user_name, user_role, event_name, event_data ) VALUES ( datetime('now'), '$username', (SELECT role FROM user WHERE user_name = '$username'), 'config_audit', '$config_data' );"}
# Function to generate security reportsgenerate_security_report() { local report_file="$AUDIT_DIR/security_report_$(date +%Y%m%d).txt"
echo "CloudPanel Security Audit Report - $(date)" > "$report_file" echo "==========================================" >> "$report_file"
# System Metrics Summary echo "System Performance Metrics:" >> "$report_file" sqlite3 "$DB_PATH" " SELECT avg(value) as avg_cpu, max(value) as max_cpu FROM instance_cpu WHERE created_at > datetime('now', '-24 hours');" >> "$report_file"
# Security Events Summary echo -e "\nSecurity Events Summary:" >> "$report_file" sqlite3 "$DB_PATH" " SELECT event_name, COUNT(*) as event_count FROM event WHERE created_at > datetime('now', '-24 hours') GROUP BY event_name;" >> "$report_file"
# Failed Login Attempts echo -e "\nFailed Login Attempts:" >> "$report_file" sqlite3 "$DB_PATH" " SELECT source_ip_address, COUNT(*) as attempt_count FROM event WHERE event_name = 'login_failed' AND created_at > datetime('now', '-24 hours') GROUP BY source_ip_address HAVING attempt_count > 3;" >> "$report_file"}
# Main execution loopmain() { echo "Starting security monitoring system..."
while true; do # Record system metrics record_system_metrics
# Analyze security events analyze_security_events
# Generate daily report at midnight if [ "$(date +%H:%M)" = "00:00" ]; then generate_security_report fi
# Sleep for monitoring interval sleep 300 done}
main "$@"
This monitoring system provides:
- Comprehensive system metrics tracking using CloudPanel’s database structure
- Security event analysis and correlation
- Automated threat detection and response
- Configuration change auditing
- Daily security reports
- Integration with CloudPanel’s event logging system