From 0c089d7b07f834d7cc46b3079c583f549479ef19 Mon Sep 17 00:00:00 2001 From: Anthony Date: Sat, 22 Mar 2025 02:21:43 +0800 Subject: [PATCH] added ssl remover shell script --- scripts/ssl-manager/ssl_manager.sh | 162 ++++++++++++++++------------- scripts/ssl-manager/ssl_remover.sh | 160 ++++++++++++++++++++++++++++ 2 files changed, 248 insertions(+), 74 deletions(-) create mode 100644 scripts/ssl-manager/ssl_remover.sh diff --git a/scripts/ssl-manager/ssl_manager.sh b/scripts/ssl-manager/ssl_manager.sh index 432b937..bf29679 100644 --- a/scripts/ssl-manager/ssl_manager.sh +++ b/scripts/ssl-manager/ssl_manager.sh @@ -58,14 +58,15 @@ validate_email() { # Function to validate DNS resolution validate_dns_resolution() { - log "Validating DNS resolution for $DOMAIN..." - RESOLVED_IPS=$(dig +short "$DOMAIN" A) + local domain=$1 + 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)." + 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)." + log "DNS validation failed. $domain does not resolve to the expected public IP ($PUBLIC_IP)." return 1 fi } @@ -95,7 +96,7 @@ validate_http_access() { # Function to validate the domain connection validate_domain_connection() { - if validate_dns_resolution; then + if validate_dns_resolution "$DOMAIN"; then log "Domain validation succeeded via DNS." return 0 elif validate_http_access; then @@ -421,7 +422,7 @@ install_xml_tools() { # Function to create or update a domain-specific HTTPS listener create_domain_listener() { - local domain="$1" + local domain=$1 local config_file="/var/www/conf/httpd_config.xml" local vhost_name="${domain//[.]/_}" local key_file="/etc/letsencrypt/live/$domain/privkey.pem" @@ -717,13 +718,15 @@ restart_litespeed() { } # Parse input parameters +declare -a DOMAINS for arg in "$@"; do case $arg in --public-ip=*) PUBLIC_IP="${arg#*=}" ;; - --domain=*) - DOMAIN="${arg#*=}" + --domains=*) + IFS=',' read -ra DOMAINS <<< "${arg#*=}" + PRIMARY_DOMAIN="${DOMAINS[0]}" ;; --email=*) EMAIL="${arg#*=}" @@ -737,82 +740,93 @@ done # Input validation log "Validating inputs..." -if [[ -z "${PUBLIC_IP:-}" || -z "${DOMAIN:-}" ]]; then - echo "Error: --public-ip and --domain are mandatory." +if [[ -z "${PUBLIC_IP:-}" || ${#DOMAINS[@]} -eq 0 ]]; then + echo "Error: --public-ip and --domain(s) 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; } +for domain in "${DOMAINS[@]}"; do + validate_domain "$domain" || { echo "Invalid domain: $domain"; exit 1; } +done if [[ -n "${EMAIL:-}" ]]; then validate_email "$EMAIL" || { echo "Invalid email: $EMAIL"; exit 1; } fi -# Validate the domain connection -validate_domain_connection +# Main execution loop +for DOMAIN in "${DOMAINS[@]}"; do + log "Processing domain: $DOMAIN" -# 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 - # Check if it's AlmaLinux or other RHEL derivatives - if grep -q "AlmaLinux" /etc/os-release; then - log "Detected AlmaLinux. Installing EPEL repository and Certbot..." - # Install EPEL repository first - dnf install -y epel-release - # Install Certbot and Python modules for the webroot plugin - dnf install -y certbot python3-certbot-apache + # 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 + # Check if it's AlmaLinux or other RHEL derivatives + if grep -q "AlmaLinux" /etc/os-release; then + log "Detected AlmaLinux. Installing EPEL repository and Certbot..." + # Install EPEL repository first + dnf install -y epel-release + # Install Certbot and Python modules for the webroot plugin + dnf install -y certbot python3-certbot-apache + else + # Fallback for other RHEL-based systems + yum install -y certbot + fi else - # Fallback for other RHEL-based systems - yum install -y certbot + echo "Unsupported OS. Install Certbot manually." + exit 1 + fi + fi + + # Check for existing certificate before requesting + if [[ -d "/etc/letsencrypt/live/$DOMAIN" ]]; then + log "Certificate for $DOMAIN already exists. Checking expiry..." + EXPIRY=$(openssl x509 -enddate -noout -in "/etc/letsencrypt/live/$DOMAIN/cert.pem" | cut -d= -f2) + EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s) + NOW_EPOCH=$(date +%s) + DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 )) + + if [[ $DAYS_LEFT -gt 30 ]]; then + log "Certificate still valid for $DAYS_LEFT days. Skipping renewal." + update_litespeed_config + setup_cron_job + continue + else + log "Certificate expires in $DAYS_LEFT days. Proceeding with renewal." + fi + fi + + # Modify Certbot command to include all domains + CERTBOT_CMD="certbot certonly --webroot -w /var/www/webroot/ROOT" + for domain in "${DOMAINS[@]}"; do + CERTBOT_CMD+=" -d $domain" + done + CERTBOT_CMD+=" --agree-tos --non-interactive" + [[ -n "${EMAIL:-}" ]] && CERTBOT_CMD+=" --email $EMAIL" + + # After Certbot installation and before existing certificate check + install_xml_tools + + # Replace the simple reload with the improved function + if $CERTBOT_CMD; then + log "SSL certificate issued successfully for $DOMAIN." + + # Update LiteSpeed config with enhanced safety + if update_litespeed_config; then + restart_litespeed + send_email "$DOMAIN SSL Certificate Issued Successfully" "The SSL certificate for $DOMAIN has been successfully installed." + setup_cron_job + else + log "ERROR: Failed to update LiteSpeed configuration. Manually check your configuration." + send_email "SSL Certificate Installation Warning" "The SSL certificate for $DOMAIN was issued successfully, but there was an error updating the LiteSpeed configuration. Please check your server configuration manually." fi else - echo "Unsupported OS. Install Certbot manually." + log "Certbot failed." + send_email "SSL Certificate Installation Failed" "An error occurred while installing the SSL certificate for $DOMAIN." exit 1 fi -fi - -# Check for existing certificate before requesting -if [[ -d "/etc/letsencrypt/live/$DOMAIN" ]]; then - log "Certificate for $DOMAIN already exists. Checking expiry..." - EXPIRY=$(openssl x509 -enddate -noout -in "/etc/letsencrypt/live/$DOMAIN/cert.pem" | cut -d= -f2) - EXPIRY_EPOCH=$(date -d "$EXPIRY" +%s) - NOW_EPOCH=$(date +%s) - DAYS_LEFT=$(( ($EXPIRY_EPOCH - $NOW_EPOCH) / 86400 )) - - if [[ $DAYS_LEFT -gt 30 ]]; then - log "Certificate still valid for $DAYS_LEFT days. Skipping renewal." - update_litespeed_config - setup_cron_job - exit 0 - else - log "Certificate expires in $DAYS_LEFT days. Proceeding with renewal." - 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" - -# After Certbot installation and before existing certificate check -install_xml_tools - -# Replace the simple reload with the improved function -if $CERTBOT_CMD; then - log "SSL certificate issued successfully for $DOMAIN." - - # Update LiteSpeed config with enhanced safety - if update_litespeed_config; then - restart_litespeed - send_email "$DOMAIN SSL Certificate Issued Successfully" "The SSL certificate for $DOMAIN has been successfully installed." - setup_cron_job - else - log "ERROR: Failed to update LiteSpeed configuration. Manually check your configuration." - send_email "SSL Certificate Installation Warning" "The SSL certificate for $DOMAIN was issued successfully, but there was an error updating the LiteSpeed configuration. Please check your server configuration manually." - fi -else - log "Certbot failed." - send_email "SSL Certificate Installation Failed" "An error occurred while installing the SSL certificate for $DOMAIN." - exit 1 -fi +done diff --git a/scripts/ssl-manager/ssl_remover.sh b/scripts/ssl-manager/ssl_remover.sh new file mode 100644 index 0000000..6c00e3c --- /dev/null +++ b/scripts/ssl-manager/ssl_remover.sh @@ -0,0 +1,160 @@ +#!/bin/bash +set -euo pipefail + +# Log file setup +LOG_DIR="/var/log/mb-ssl" +LOG_FILE="$LOG_DIR/ssl-remover.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" +} + +# Email function (same as in ssl_manager.sh) +send_email() { + local subject="$1" + local body="$2" + local recipient="${EMAIL:-}" + + [[ -n "$recipient" ]] && { + 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." || log "Email failed." + } +} + +# Backup configuration with timestamp +backup_config() { + local config_file="/var/www/conf/httpd_config.xml" + local backup_dir="/var/www/conf/backups" + local timestamp=$(date +%Y%m%d%H%M%S) + + mkdir -p "$backup_dir" + cp "$config_file" "$backup_dir/httpd_config.pre-removal-$timestamp.xml" + log "Config backup saved to $backup_dir/httpd_config.pre-removal-$timestamp.xml" +} + +# Remove certificate using Certbot +remove_certificate() { + local domain="$1" + + if certbot certificates | grep -q "Domains: $domain"; then + log "Removing certificate for $domain..." + certbot delete --cert-name "$domain" --non-interactive + rm -rf "/etc/letsencrypt/live/$domain"* + log "Certificate removed for $domain" + else + log "No certificate found for $domain" + fi +} + +# Remove listeners and associated configurations +cleanup_listeners() { + local domain="$1" + local config_file="/var/www/conf/httpd_config.xml" + local temp_file + + log "Cleaning up listeners for $domain..." + + # Remove listeners + sed -i "/HTTPS-$domain<\/name>/,/<\/listener>/d" "$config_file" + + # Remove vhostMap entries + sed -i "/$domain<\/domain>/,/<\/vhostMap>/d" "$config_file" + + # Remove related virtual host + local vhost_name="${domain//./_}" + sed -i "/$vhost_name<\/name>/,/<\/virtualHost>/d" "$config_file" + + # Cleanup empty listenerList tags + temp_file=$(mktemp) + awk '// {flag=1; print; next} /<\/listenerList>/ {flag=0; print; next} flag && /^[[:space:]]*$/ {next} {print}' "$config_file" > "$temp_file" + mv "$temp_file" "$config_file" +} + +# Validate XML configuration +validate_xml() { + local config_file="/var/www/conf/httpd_config.xml" + + if command -v xmllint >/dev/null; then + log "Validating XML configuration..." + if ! xmllint --noout "$config_file"; then + log "ERROR: Invalid XML configuration after cleanup. Check backups." + return 1 + fi + fi + return 0 +} + +# Restart LiteSpeed if needed +restart_litespeed() { + log "Restarting LiteSpeed..." + systemctl restart lsws && log "LiteSpeed restarted successfully." || log "LiteSpeed restart failed." +} + +# Main execution +main() { + declare -a DOMAINS + + # Parse parameters + while [[ $# -gt 0 ]]; do + case "$1" in + --domains=*) + IFS=',' read -ra DOMAINS <<< "${1#*=}" + shift + ;; + --email=*) + EMAIL="${1#*=}" + shift + ;; + *) + echo "Invalid parameter: $1" + exit 1 + ;; + esac + done + + # Validate input + if [[ ${#DOMAINS[@]} -eq 0 ]]; then + echo "Error: --domains parameter is required" + exit 1 + fi + + backup_config + + for domain in "${DOMAINS[@]}"; do + log "Processing domain: $domain" + + # Validate domain format + [[ "$domain" =~ ^([a-zA-Z0-9](-*[a-zA-Z0-9])*\.)+[a-zA-Z]{2,}$ ]] || { + log "Invalid domain: $domain" + continue + } + + remove_certificate "$domain" + cleanup_listeners "$domain" + done + + if validate_xml; then + restart_litespeed + send_email "SSL Removal Complete" "Successfully removed SSL for domains: ${DOMAINS[*]}" + else + send_email "SSL Removal Warning" "SSL removed but configuration validation failed for domains: ${DOMAINS[*]}" + exit 1 + fi +} + +main "$@" \ No newline at end of file