Securing CloudPanel on Ubuntu 24.04 Part 7
18/11/2024 18/11/2024 security 5 mins read
Table Of Contents
Part 7: SSL Certificate Management and Security #
Let’s create a comprehensive SSL certificate management system:
# Create SSL certificate management scriptsudo nano /usr/local/bin/cloudpanel-ssl-manager.sh
#
#!/bin/bash
# Initialize paths and configurationCP_HOME="/home/clp"DB_PATH="${CP_HOME}/htdocs/app/data/db.sq3"SSL_DIR="${CP_HOME}/services/nginx/ssl-certificates"LOG_DIR="${CP_HOME}/logs/ssl"
mkdir -p "$SSL_DIR" "$LOG_DIR"
# Function to get certificate information from CloudPanel databaseget_certificate_info() { sqlite3 "$DB_PATH" " SELECT c.id, c.site_id, c.uid, c.expires_at, c.type, s.domain_name, s.user FROM certificate c JOIN site s ON c.site_id = s.id WHERE c.default_certificate = 1;"}
# Function to monitor certificate expirationmonitor_certificates() { echo "Monitoring SSL certificates..." local current_time=$(date +%s)
while IFS='|' read -r cert_id site_id uid expires domain user; do # Convert expires_at to timestamp local expire_time=$(date -d "$expires" +%s) local days_remaining=$(( ($expire_time - $current_time) / 86400 ))
echo "Checking certificate for $domain (Expires in $days_remaining days)"
# Alert if certificate is expiring soon if [ $days_remaining -lt 30 ]; then handle_expiring_certificate "$domain" "$days_remaining" "$cert_id" fi
# Verify certificate chain verify_certificate_chain "$domain" "$cert_id"
done < <(get_certificate_info)}
# Function to verify and secure certificatesverify_certificate_chain() { local domain="$1" local cert_id="$2"
# Get certificate chain from database local cert_path="${SSL_DIR}/${domain}.crt" local key_path="${SSL_DIR}/${domain}.key"
# Extract certificate data from database sqlite3 "$DB_PATH" " SELECT certificate, private_key, certificate_chain FROM certificate WHERE id = $cert_id;" | while IFS='|' read -r cert key chain; do
# Save certificate files with proper permissions echo "$cert" > "$cert_path" echo "$key" > "$key_path" chmod 644 "$cert_path" chmod 600 "$key_path"
# Verify certificate chain if ! openssl verify -CAfile <(echo "$chain") "$cert_path" > /dev/null 2>&1; then log_ssl_error "$domain" "Certificate chain verification failed" fi
# Verify certificate matches private key cert_modulus=$(openssl x509 -noout -modulus -in "$cert_path" | openssl md5) key_modulus=$(openssl rsa -noout -modulus -in "$key_path" | openssl md5)
if [ "$cert_modulus" != "$key_modulus" ]; then log_ssl_error "$domain" "Certificate and private key mismatch" fi done}
# Function to handle expiring certificateshandle_expiring_certificate() { local domain="$1" local days="$2" local cert_id="$3"
echo "Certificate for $domain is expiring in $days days"
# Log the expiration warning local message="SSL Certificate Expiration Warning for $domain" local details="Certificate will expire in $days days"
# Update CloudPanel notification system sqlite3 "$DB_PATH" " INSERT INTO notification ( created_at, updated_at, severity, subject, message, is_read ) VALUES ( datetime('now'), datetime('now'), 'warning', '$message', '$details', 0 );"}
# Function to update Nginx SSL configurationupdate_nginx_ssl_config() { local domain="$1" local cert_id="$2"
# Get site configuration path local nginx_conf="${CP_HOME}/services/nginx/sites-enabled/${domain}.conf"
# Update SSL configuration cat > "$nginx_conf" <<EOFserver { listen 443 ssl http2; server_name ${domain};
# SSL Configuration ssl_certificate ${SSL_DIR}/${domain}.crt; ssl_certificate_key ${SSL_DIR}/${domain}.key;
# Modern SSL Configuration ssl_protocols TLSv1.2 TLSv1.3; ssl_prefer_server_ciphers off; ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
# OCSP Stapling ssl_stapling on; ssl_stapling_verify on; resolver 8.8.8.8 8.8.4.4 valid=300s; resolver_timeout 5s;
# Security Headers add_header Strict-Transport-Security "max-age=63072000" always; add_header X-Frame-Options SAMEORIGIN; add_header X-Content-Type-Options nosniff;
# Additional security headers for SSL add_header Content-Security-Policy "default-src 'self' https: data: 'unsafe-inline' 'unsafe-eval'; frame-ancestors 'self'";}
# Redirect HTTP to HTTPSserver { listen 80; server_name ${domain}; return 301 https://$server_name$request_uri;}EOF}
# Function to log SSL-related eventslog_ssl_event() { local domain="$1" local message="$2" local level="$3"
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $domain: $message" >> "${LOG_DIR}/ssl-events.log"}
# Main executionmain() { echo "Starting SSL certificate management..."
# Create backup of current SSL configurations backup_date=$(date +%Y%m%d_%H%M%S) backup_dir="${CP_HOME}/backups/ssl_${backup_date}" mkdir -p "$backup_dir" cp -r "$SSL_DIR" "$backup_dir/"
# Monitor and update certificates monitor_certificates
# Set up daily certificate monitoring if ! crontab -l | grep -q "cloudpanel-ssl-manager.sh"; then (crontab -l 2>/dev/null; echo "0 0 * * * /usr/local/bin/cloudpanel-ssl-manager.sh") | crontab - fi
echo "SSL certificate management completed successfully"}
main "$@"
This script provides:
- Comprehensive SSL certificate management based on CloudPanel’s database structure
- Automatic monitoring of certificate expiration
- Certificate chain verification
- Private key security
- Nginx SSL configuration management
- Integration with CloudPanel’s notification system
To implement this SSL management system:
# Make the script executablechmod +x /usr/local/bin/cloudpanel-ssl-manager.sh
# Run the script/usr/local/bin/cloudpanel-ssl-manager.sh