Securing CloudPanel on Ubuntu 24.04 Part 10

21/11/2024 21/11/2024 security 6 mins read
Table Of Contents

Part 10: Automated Incident Response and Recovery System #

Let’s create a comprehensive incident response system that automatically detects and handles security incidents while maintaining proper logging in CloudPanel.

Terminal window
# Create incident response management script
sudo nano /usr/local/bin/cloudpanel-incident-response.sh

#

#!/bin/bash
# Initialize paths and configuration
CP_HOME="/home/clp"
DB_PATH="${CP_HOME}/htdocs/app/data/db.sq3"
INCIDENT_DIR="${CP_HOME}/logs/incidents"
BACKUP_DIR="${CP_HOME}/backups/incidents"
# Create necessary directories
mkdir -p "$INCIDENT_DIR" "$BACKUP_DIR"
# Function to detect and categorize security incidents
detect_security_incidents() {
echo "Analyzing security incidents..."
# Query CloudPanel's event table for potential incidents
sqlite3 "$DB_PATH" "
SELECT
e.id,
e.created_at,
e.user_name,
e.event_name,
e.event_data,
e.source_ip_address,
e.user_agent
FROM event e
WHERE e.created_at > datetime('now', '-15 minutes')
AND e.event_name IN (
'login_failed',
'unauthorized_access',
'file_modification',
'config_change',
'malware_detected'
)
ORDER BY e.created_at DESC;" | while IFS='|' read -r event_id timestamp username event_name data ip agent; do
case "$event_name" in
"login_failed")
handle_authentication_incident "$event_id" "$ip" "$username"
;;
"unauthorized_access")
handle_access_violation "$event_id" "$ip" "$data"
;;
"file_modification")
handle_file_incident "$event_id" "$username" "$data"
;;
"malware_detected")
handle_malware_incident "$event_id" "$data"
;;
*)
log_unknown_incident "$event_id" "$event_name" "$data"
;;
esac
done
}
# Function to handle authentication-related incidents
handle_authentication_incident() {
local event_id="$1"
local ip="$2"
local username="$3"
# Check for brute force patterns
local failed_attempts=$(sqlite3 "$DB_PATH" "
SELECT COUNT(*) FROM event
WHERE source_ip_address = '$ip'
AND event_name = 'login_failed'
AND created_at > datetime('now', '-1 hour');")
if [ "$failed_attempts" -gt 5 ]; then
# Implement automatic IP blocking
sqlite3 "$DB_PATH" "
INSERT INTO blocked_ip (
created_at,
updated_at,
ip
) VALUES (
datetime('now'),
datetime('now'),
'$ip'
);"
# Create a high-priority notification
create_incident_notification \
"Brute Force Attack Detected" \
"Multiple failed login attempts from IP: $ip targeting user: $username" \
"high"
# Update firewall rules
update_firewall_rules "$ip"
fi
}
# Function to handle file system incidents
handle_file_incident() {
local event_id="$1"
local username="$2"
local file_data="$3"
# Extract file information
local file_path=$(echo "$file_data" | jq -r '.path')
local modification_type=$(echo "$file_data" | jq -r '.type')
# Create incident snapshot
local snapshot_dir="${BACKUP_DIR}/file_incident_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$snapshot_dir"
if [ -f "$file_path" ]; then
# Create file backup
cp -p "$file_path" "$snapshot_dir/"
# Record file metadata
stat "$file_path" > "${snapshot_dir}/file_metadata.txt"
# Check for suspicious content
if grep -qiE "eval|base64_decode|system|exec" "$file_path"; then
# Quarantine suspicious file
local quarantine_dir="${CP_HOME}/quarantine/files"
mkdir -p "$quarantine_dir"
mv "$file_path" "${quarantine_dir}/$(basename "$file_path").$(date +%s)"
create_incident_notification \
"Suspicious File Detected" \
"File containing potentially malicious code: $file_path" \
"critical"
fi
fi
}
# Function to handle malware incidents
handle_malware_incident() {
local event_id="$1"
local malware_data="$2"
# Extract malware information
local infected_path=$(echo "$malware_data" | jq -r '.path')
local malware_type=$(echo "$malware_data" | jq -r '.type')
# Create quarantine directory
local quarantine_dir="${CP_HOME}/quarantine/malware/$(date +%Y%m%d)"
mkdir -p "$quarantine_dir"
if [ -e "$infected_path" ]; then
# Quarantine the infected file/directory
mv "$infected_path" "$quarantine_dir/"
# Record incident details
echo "Quarantined at: $(date)" > "${quarantine_dir}/incident_details.txt"
echo "Original location: $infected_path" >> "${quarantine_dir}/incident_details.txt"
echo "Malware type: $malware_type" >> "${quarantine_dir}/incident_details.txt"
create_incident_notification \
"Malware Detected" \
"Malware type '$malware_type' detected at: $infected_path" \
"critical"
# Trigger additional security scans
initiate_security_scan "$(dirname "$infected_path")"
fi
}
# Function to create incident notifications in CloudPanel
create_incident_notification() {
local subject="$1"
local message="$2"
local severity="$3"
sqlite3 "$DB_PATH" "
INSERT INTO notification (
created_at,
updated_at,
severity,
subject,
message,
is_read
) VALUES (
datetime('now'),
datetime('now'),
'$severity',
'$subject',
'$message',
0
);"
}
# Function to update firewall rules
update_firewall_rules() {
local ip="$1"
echo "Updating firewall rules for IP: $ip"
# Update CloudPanel's firewall rules
sqlite3 "$DB_PATH" "
INSERT INTO firewall_rule (
created_at,
updated_at,
port_range,
source,
description
) VALUES (
datetime('now'),
datetime('now'),
'ALL',
'$ip',
'Automatically blocked due to security incident'
);"
# Apply firewall rules
ufw deny from "$ip" to any comment "Auto-blocked by incident response"
}
# Function to initiate security scans
initiate_security_scan() {
local target_path="$1"
echo "Initiating security scan for: $target_path"
# Record scan initiation
sqlite3 "$DB_PATH" "
INSERT INTO event (
created_at,
user_name,
event_name,
event_data
) VALUES (
datetime('now'),
'system',
'security_scan_initiated',
'{\"path\": \"$target_path\"}'
);"
# Schedule immediate malware scan
clamscan -r "$target_path" --move="${CP_HOME}/quarantine/malware"
}
# Function to generate incident reports
generate_incident_report() {
local report_file="${INCIDENT_DIR}/incident_report_$(date +%Y%m%d).txt"
echo "Generating incident report..."
{
echo "CloudPanel Incident Report - $(date)"
echo "================================="
echo -e "\nSecurity Incidents Summary:"
sqlite3 "$DB_PATH" "
SELECT
event_name,
COUNT(*) as count,
MIN(created_at) as first_seen,
MAX(created_at) as last_seen
FROM event
WHERE created_at > datetime('now', '-24 hours')
AND event_name IN (
'login_failed',
'unauthorized_access',
'file_modification',
'malware_detected'
)
GROUP BY event_name;"
echo -e "\nBlocked IPs:"
sqlite3 "$DB_PATH" "
SELECT ip, created_at
FROM blocked_ip
WHERE created_at > datetime('now', '-24 hours');"
echo -e "\nQuarantined Files:"
find "${CP_HOME}/quarantine" -type f -mtime -1 -ls
} > "$report_file"
}
# Main execution
main() {
echo "Starting incident response system..."
while true; do
# Detect and handle incidents
detect_security_incidents
# Generate daily incident report at midnight
if [ "$(date +%H:%M)" = "00:00" ]; then
generate_incident_report
fi
# Sleep for monitoring interval
sleep 300
done
}
main "$@"

This incident response system provides:

  1. Automated detection and response to security incidents using CloudPanel’s event system
  2. Integration with CloudPanel’s notification and security tables
  3. Automatic quarantine of suspicious files and malware
  4. IP blocking for brute force attempts
  5. Detailed incident reporting and logging
  6. Automated security scanning when incidents are detected

To implement this incident response system:

Terminal window
# Make the script executable
chmod +x /usr/local/bin/cloudpanel-incident-response.sh
# Run the script as a service
sudo systemctl enable cloudpanel-incident-response
sudo systemctl start cloudpanel-incident-response