Securing CloudPanel on Ubuntu 24.04 Part 4 and 5
16/11/2024 16/11/2024 security 5 mins read
Table Of Contents
Part 4 & 5: Advanced Security Controls and PHP Configuration Management #
Let’s create a security system that integrates traffic analysis and PHP configuration management based on CloudPanel.
First, let’s create our main security management script:
# Create the security management scriptsudo nano /usr/local/bin/cloudpanel-php-security-manager.sh
#
#!/bin/bash
# CloudPanel PHP Security Manager# Manages PHP-FPM configurations and security settings across different PHP versions
set -euo pipefail
# Core paths based on CloudPanel structureCP_HOME="/home/clp"DB_PATH="${CP_HOME}/htdocs/app/data/db.sq3"SITES_ROOT="/home"LOG_DIR="${CP_HOME}/logs/php"
mkdir -p "$LOG_DIR"
# Function to handle logging with timestamps and levelslog() { local level="$1" local message="$2" echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $message" | tee -a "${LOG_DIR}/security.log"}
# Validate database existencevalidate_db() { if [ ! -f "$DB_PATH" ]; then log "ERROR" "CloudPanel database not found at $DB_PATH" exit 1 fi}
# Retrieve sites with their PHP settings from database# This function joins site and php_settings tables to get complete configurationget_sites_with_php() { sqlite3 "$DB_PATH" "SELECT s.id, s.domain_name, s.user, s.root_directory, p.php_version, p.id as php_settings_id, p.memory_limit, p.max_execution_time, p.additional_configuration, p.pool_portFROM site sINNER JOIN php_settings p ON s.php_settings_id = p.idWHERE s.type = 'vhost';"}
# Configure PHP version specific settingsconfigure_php_version() { local php_version="$1" local version_number="${php_version/./}" # Convert 7.4 to 74
# Verify PHP version installation if [ ! -d "/etc/php/${php_version}" ]; then log "ERROR" "PHP version ${php_version} not installed" return 1 fi
# Setup PHP-FPM pool directory local fpm_pool_dir="/etc/php/${php_version}/fpm/pool.d" mkdir -p "$fpm_pool_dir"
# Create base PHP-FPM configuration if missing local fpm_conf="/etc/php/${php_version}/fpm/php-fpm.conf" if [ ! -f "$fpm_conf" ]; then cat > "$fpm_conf" << EOF[global]pid = /run/php/php${php_version}-fpm.piderror_log = /var/log/php${version_number}-fpm.loglog_level = noticeemergency_restart_threshold = 10emergency_restart_interval = 1mprocess_control_timeout = 10sdaemonize = yesinclude=/etc/php/${php_version}/fpm/pool.d/*.confEOF fi
# Enable PHP-FPM service systemctl enable "php${version_number}-fpm" 2>/dev/null || true}
# Configure PHP settings for a specific siteconfigure_site_php() { local domain="$1" local user="$2" local php_version="$3" local root_dir="$4" local memory_limit="$5" local max_exec="$6" local additional_config="$7" local pool_port="$8"
local version_number="${php_version/./}" local pool_config="/etc/php/${php_version}/fpm/pool.d/${domain}.conf" local user_php_log_dir="${SITES_ROOT}/${user}/logs/php"
# Create and set permissions for log directory mkdir -p "$user_php_log_dir" chown "${user}:${user}" "$user_php_log_dir"
# Create PHP-FPM pool configuration cat > "$pool_config" << EOF[${domain}]user = ${user}group = ${user}listen = 127.0.0.1:${pool_port}
; Process Managementpm = dynamicpm.max_children = 50pm.start_servers = 5pm.min_spare_servers = 2pm.max_spare_servers = 10
; Path Settingschdir = ${root_dir}
; PHP Settingsphp_admin_flag[log_errors] = onphp_admin_value[error_log] = ${user_php_log_dir}/php-${domain}-error.logphp_admin_value[memory_limit] = ${memory_limit}php_admin_value[max_execution_time] = ${max_exec}php_admin_value[session.save_handler] = filesphp_admin_value[session.save_path] = ${SITES_ROOT}/${user}/tmp/sessionsphp_admin_value[upload_tmp_dir] = ${SITES_ROOT}/${user}/tmp/upload
; Security Settingsphp_admin_flag[allow_url_fopen] = offphp_admin_flag[allow_url_include] = offphp_admin_value[disable_functions] = exec,passthru,shell_exec,system,proc_open,popenphp_admin_value[open_basedir] = ${root_dir}:/tmp:${SITES_ROOT}/${user}/tmp
; Custom Configuration${additional_config}EOF
# Setup temporary directories with proper permissions mkdir -p "${SITES_ROOT}/${user}/tmp/"{sessions,upload} chown -R "${user}:${user}" "${SITES_ROOT}/${user}/tmp" chmod -R 750 "${SITES_ROOT}/${user}/tmp"
log "INFO" "Configured PHP-FPM pool for ${domain} (PHP ${php_version})"}
# Setup log rotation for PHP logssetup_log_rotation() { local user="$1" local domain="$2"
cat > "/etc/logrotate.d/php-${domain}" << EOF${SITES_ROOT}/${user}/logs/php/php-${domain}-error.log { daily rotate 14 missingok notifempty compress delaycompress create 0640 ${user} ${user}}EOF}
# Main execution functionmain() { log "INFO" "Starting CloudPanel PHP security configuration" validate_db
# Create backup directory local backup_date=$(date +%Y%m%d_%H%M%S) local backup_dir="${CP_HOME}/backups/php_security_${backup_date}" mkdir -p "$backup_dir"
# Track configured PHP versions declare -A configured_versions
# Process each site while IFS='|' read -r site_id domain user root_dir php_version settings_id mem_limit max_exec additional port; do if [ -z "${configured_versions[$php_version]:-}" ]; then configure_php_version "$php_version" configured_versions[$php_version]=1
# Backup existing configuration if [ -d "/etc/php/${php_version}" ]; then cp -r "/etc/php/${php_version}" "${backup_dir}/php${php_version}" fi fi
configure_site_php "$domain" "$user" "$php_version" "$root_dir" "$mem_limit" "$max_exec" "$additional" "$port" setup_log_rotation "$user" "$domain" done < <(get_sites_with_php)
log "INFO" "PHP security configuration completed" log "INFO" "Backup stored in: $backup_dir"
# Reload PHP-FPM for each configured version for version in "${!configured_versions[@]}"; do version_num="${version/./}" systemctl reload "php${version_num}-fpm" || log "ERROR" "Failed to reload PHP-FPM for version ${version}" done}
main "$@"
This unified script:
- Reads site configurations directly from CloudPanel
- Configures PHP-FPM pools with settings from the database
- Implements security measures for both PHP
- Analyzes traffic patterns for suspicious activity
- Creates proper backups before making changes
To use this script:
# Make the script executablechmod +x /usr/local/bin/cloudpanel-php-security-manager.sh
# Run the script/usr/local/bin/cloudpanel-php-security-manager.sh