From 919369eeccd208af5b4ef3ca20a90afacdd63c61 Mon Sep 17 00:00:00 2001 From: Anthony Date: Wed, 29 Jan 2025 21:03:24 +0800 Subject: [PATCH] Added ssl_manager and its meu, form and action --- mbadmin.jps | 84 +++++++++-- scripts/ssl-manager/ssl_manager.sh | 226 +++++++++++++++++++++++++++++ 2 files changed, 295 insertions(+), 15 deletions(-) create mode 100644 scripts/ssl-manager/ssl_manager.sh diff --git a/mbadmin.jps b/mbadmin.jps index f2fa5b0..469c810 100644 --- a/mbadmin.jps +++ b/mbadmin.jps @@ -1,6 +1,6 @@ type: update id: mbadmin -version: '2.4' +version: '2.5' name: MB Administration description: Mighty Box Control Panel Administration @@ -11,22 +11,30 @@ onInstall: - cmd[cp]: user: root commands: + # Ensure all directories exist - mkdir -p /home/litespeed/mbmanager - mkdir -p /home/litespeed/mbmanager/relay - - cd /home/litespeed/mbmanager - - curl -O https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/litespeed_fetch_settings.sh - - curl -O https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/litespeed_update_settings.sh - - curl -O https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/update_opcache_settings.sh + - mkdir -p /home/litespeed/mbmanager/ssl-manager + # Download main scripts + - (cd /home/litespeed/mbmanager && curl -OL https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/litespeed_fetch_settings.sh \ + -OL https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/litespeed_update_settings.sh \ + -OL https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/update_opcache_settings.sh) - chmod +x /home/litespeed/mbmanager/*.sh - - cd /home/litespeed/mbmanager/relay - - curl -O https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/relay/check_relay_installation.sh - - curl -O https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/relay/check_relay_status.sh - - curl -O https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/relay/disable_relay.sh - - curl -O https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/relay/enable_relay.sh - - curl -O https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/relay/flush_caches.sh - - curl -O https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/relay/install_relay_ocp.sh - - curl -O https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/relay/uninstall_relay.sh + # Download relay scripts + - (cd /home/litespeed/mbmanager/relay && curl -OL https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/relay/check_relay_installation.sh \ + -OL https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/relay/check_relay_status.sh \ + -OL https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/relay/disable_relay.sh \ + -OL https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/relay/enable_relay.sh \ + -OL https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/relay/flush_caches.sh \ + -OL https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/relay/install_relay_ocp.sh \ + -OL https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/relay/uninstall_relay.sh) - chmod +x /home/litespeed/mbmanager/relay/*.sh + # Download SSL manager script + - (cd /home/litespeed/mbmanager/ssl-manager && curl -OL https://deploy-proxy.mightybox.io/tony/mb-admin/raw/branch/main/scripts/ssl-manager/ssl_manager.sh) + - chmod +x /home/litespeed/mbmanager/ssl-manager/*.sh + # Install Certbot for AlmaLinux + - dnf install -y certbot + - dnf install -y python3-certbot-dns-cloudflare menu: - confirmText: Are you sure you want to execute this WP-CLI command? @@ -114,6 +122,12 @@ menu: caption: DB Import Preparation action: db_import_preparation successText: "${response.out}" + - confirmText: Are you sure you want to issue an SSL certificate for this domain? + loadingText: Issuing SSL Certificate... + caption: Issue SSL Certificate + action: issue_ssl_cert + settings: sslCertConfig + successText: "SSL certificate for '${settings.domain}' has been issued successfully." settings: wpCliConfig: @@ -207,10 +221,26 @@ settings: type: text caption: TTL Feed (Seconds) default: "7200" - + sslCertConfig: + submitUnchanged: true + fields: + - name: public_ip + type: text + caption: Public IP Address + required: true + - name: domain + type: text + caption: Domain Name + required: true + - name: email + type: text + caption: Email Address + required: true + actions: dynamic_wp_cli: - cmd[cp]: + user: litespeed commands: - cd /var/www/webroot/ROOT/ - wp ${settings.wp_cli_command} @@ -226,6 +256,7 @@ actions: message: "Directory synchronized successfully from '${settings.old_directory}' to '/var/www/webroot/ROOT/'." search_replace_urls: - cmd[cp]: + user: litespeed commands: - cd /var/www/webroot/ROOT/ - /home/litespeed/bin/wp search-replace '${settings.old_url}' '${settings.new_url}' --all-tables @@ -258,6 +289,7 @@ actions: export_wp_db: - cmd[cp]: + user: litespeed commands: - cd /var/www/webroot/ROOT/ - wp db export /var/www/webroot/ROOT/${settings.db_filename}.sql @@ -332,6 +364,7 @@ actions: user: root commands: - bash /home/litespeed/mbmanager/update_opcache_settings.sh "${settings.memory_consumption}" "${settings.interned_strings_buffer}" "${settings.max_accelerated_files}" "${settings.revalidate_freq}" + - systemctl restart lsws - restartNodes: - nodeGroup: "cp" reboot: true @@ -501,6 +534,14 @@ actions: - return: type: info message: "${response.out}" + issue_ssl_cert: + - cmd[cp]: + user: root + commands: + - bash /home/litespeed/mbmanager/ssl-manager/ssl_manager.sh --public-ip="${settings.public_ip}" --domain="${settings.domain}" --email="${settings.email}" + - return: + type: info + message: "SSL certificate for '${settings.domain}' has been issued successfully." responses: enableSuccess: @@ -529,4 +570,17 @@ buttons: - settings: litespeedConfig action: litespeed_update_settings caption: Update LiteSpeed Cache Settings - submitButtonText: Update Cache Settings \ No newline at end of file + submitButtonText: Update Cache Settings + +onUninstall: + - cmd[cp]: + user: root + commands: + # Remove all installed scripts + - rm -rf /home/litespeed/mbmanager/ssl-manager/* + - rm -rf /home/litespeed/mbmanager/relay/* + - rm -rf /home/litespeed/mbmanager/* + # Remove the parent directory if empty + - rmdir --ignore-fail-on-non-empty /home/litespeed/mbmanager || true + # Uninstall Certbot if no longer needed + - if command -v certbot > /dev/null; then dnf remove -y certbot python3-certbot-dns-cloudflare; fi \ No newline at end of file diff --git a/scripts/ssl-manager/ssl_manager.sh b/scripts/ssl-manager/ssl_manager.sh new file mode 100644 index 0000000..229190c --- /dev/null +++ b/scripts/ssl-manager/ssl_manager.sh @@ -0,0 +1,226 @@ +#!/bin/bash +set -euo pipefail + +# Log file setup +LOG_DIR="/var/log/mb-ssl" +LOG_FILE="$LOG_DIR/ssl-manager.log" +mkdir -p "$LOG_DIR" +chmod 0755 "$LOG_DIR" +exec > >(tee -a "$LOG_FILE") 2>&1 + +# Function to log messages +log() { + echo "$(date '+%Y-%m-%d %H:%M:%S') $1" +} + +# Function to send email via Postmark +send_email() { + local subject="$1" + local body="$2" + local recipient="${EMAIL:-}" + + if [[ -n "$recipient" ]]; then + log "Sending email notification to $recipient..." + curl -s "https://api.postmarkapp.com/email" \ + -X POST \ + -H "Accept: application/json" \ + -H "Content-Type: application/json" \ + -H "X-Postmark-Server-Token: d88b25c4-2fdb-43d3-9097-f6c655a9742b" \ + -d "{ + \"From\": \"admin@mightybox.io\", + \"To\": \"$recipient\", + \"Subject\": \"$subject\", + \"HtmlBody\": \"$body\", + \"MessageStream\": \"outbound\" + }" > /dev/null && log "Email sent successfully." || log "Failed to send email." + else + log "Email not provided. Skipping email notification." + fi +} + +# Function to validate IP address +validate_ip() { + local ip=$1 + [[ "$ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]] && return 0 || return 1 +} + +# Function to validate domain +validate_domain() { + local domain=$1 + [[ "$domain" =~ ^([a-zA-Z0-9](-*[a-zA-Z0-9])*\.)+[a-zA-Z]{2,}$ ]] && return 0 || return 1 +} + +# Function to validate email +validate_email() { + local email=$1 + [[ "$email" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]] && return 0 || return 1 +} + +# Function to validate DNS resolution +validate_dns_resolution() { + log "Validating DNS resolution for $DOMAIN..." + RESOLVED_IPS=$(dig +short "$DOMAIN" A) + + if echo "$RESOLVED_IPS" | grep -q "$PUBLIC_IP"; then + log "DNS validation successful. $DOMAIN resolves to the expected public IP ($PUBLIC_IP)." + return 0 + else + log "DNS validation failed. $DOMAIN does not resolve to the expected public IP ($PUBLIC_IP)." + return 1 + fi +} + +# Function to validate HTTP access +validate_http_access() { + log "Validating HTTP access for $DOMAIN..." + + ACME_DIR="/var/www/webroot/ROOT/.well-known/acme-challenge" + mkdir -p "$ACME_DIR" + chmod 0755 "$ACME_DIR" + + TOKEN=$(openssl rand -hex 16) + echo "$TOKEN" > "$ACME_DIR/test-token" + + # Test HTTP access by retrieving the token + RESPONSE=$(curl -s "http://$DOMAIN/.well-known/acme-challenge/test-token") + + if [[ "$RESPONSE" == "$TOKEN" ]]; then + log "HTTP validation successful. $DOMAIN is accessible." + return 0 + else + log "HTTP validation failed. Unable to retrieve the test token from $DOMAIN." + return 1 + fi +} + +# Function to validate the domain connection +validate_domain_connection() { + if validate_dns_resolution; then + log "Domain validation succeeded via DNS." + return 0 + elif validate_http_access; then + log "Domain validation succeeded via HTTP." + return 0 + else + log "Domain validation failed. $DOMAIN does not point to the correct IP or is not accessible via HTTP." + send_email "SSL Setup Failed" "The domain $DOMAIN could not be validated. Ensure the DNS and HTTP settings are correct." + exit 1 + fi +} + +# Function to update LiteSpeed configuration +update_litespeed_config() { + local config_file="/var/www/conf/httpd_config.xml" + local key_file="/etc/letsencrypt/live/$DOMAIN/privkey.pem" + local cert_file="/etc/letsencrypt/live/$DOMAIN/fullchain.pem" + + log "Updating LiteSpeed configuration..." + if grep -q "$DOMAIN" "$config_file"; then + log "Domain $DOMAIN already exists in the configuration. Updating..." + sed -i "//,/<\/listener>/s|.*|$key_file|" "$config_file" + sed -i "//,/<\/listener>/s|.*|$cert_file|" "$config_file" + else + log "Domain $DOMAIN not found in configuration. Adding new listener..." + sed -i "/<\/listenerList>/i\ + \ + HTTPS-$DOMAIN\ +
*:443
\ + 1\ + $key_file\ + $cert_file\ + 1\ +
" "$config_file" + fi + log "LiteSpeed configuration updated successfully." +} + +# Function to set up automatic renewal +setup_cron_job() { + log "Setting up cron job for Certbot renewal..." + + # Ensure crond is running + if ! systemctl is-active --quiet crond; then + log "Starting crond service..." + sudo systemctl start crond + sudo systemctl enable crond + fi + + # Add cron job for Certbot renewal + if ! crontab -l 2>/dev/null | grep -q "certbot renew"; then + (crontab -l 2>/dev/null; echo "0 3 * * * /usr/bin/certbot renew --quiet") | crontab - + log "Cron job added for Certbot renewal." + else + log "Cron job for Certbot renewal already exists." + fi + + # Verify cron job + log "Verifying cron job..." + if crontab -l | grep -q "certbot renew"; then + log "Cron job successfully set up." + else + log "Failed to set up cron job. Please check manually." + exit 1 + fi +} + +# Parse input parameters +for arg in "$@"; do + case $arg in + --public-ip=*) + PUBLIC_IP="${arg#*=}" + ;; + --domain=*) + DOMAIN="${arg#*=}" + ;; + --email=*) + EMAIL="${arg#*=}" + ;; + *) + echo "Invalid argument: $arg" + exit 1 + ;; + esac +done + +# Input validation +log "Validating inputs..." +if [[ -z "${PUBLIC_IP:-}" || -z "${DOMAIN:-}" ]]; then + echo "Error: --public-ip and --domain are mandatory." + exit 1 +fi +validate_ip "$PUBLIC_IP" || { echo "Invalid public IP: $PUBLIC_IP"; exit 1; } +validate_domain "$DOMAIN" || { echo "Invalid domain: $DOMAIN"; exit 1; } +if [[ -n "${EMAIL:-}" ]]; then + validate_email "$EMAIL" || { echo "Invalid email: $EMAIL"; exit 1; } +fi + +# Validate the domain connection +validate_domain_connection + +# Install Certbot +log "Installing Certbot..." +if ! command -v certbot > /dev/null; then + if [[ -f /etc/debian_version ]]; then + apt-get update && apt-get install -y certbot + elif [[ -f /etc/redhat-release ]]; then + yum install -y certbot + else + echo "Unsupported OS. Install Certbot manually." + exit 1 + fi +fi + +# Issue SSL certificate +CERTBOT_CMD="certbot certonly --webroot -w /var/www/webroot/ROOT -d $DOMAIN --agree-tos --non-interactive" +[[ -n "${EMAIL:-}" ]] && CERTBOT_CMD+=" --email $EMAIL" +if $CERTBOT_CMD; then + log "SSL certificate issued successfully for $DOMAIN." + update_litespeed_config + sudo systemctl reload lsws + send_email "$DOMAIN SSL Certificate Issued Successfully" "The SSL certificate for $DOMAIN has been successfully installed." + setup_cron_job +else + log "Certbot failed." + send_email "SSL Certificate Installation Failed" "An error occurred while installing the SSL certificate for $DOMAIN." + exit 1 +fi