Optimized SSL Remover Shell SCript
parent
5653d318ba
commit
a0feb8d70d
|
|
@ -1,25 +1,42 @@
|
|||
#!/bin/bash
|
||||
# ==============================================================================
|
||||
# Script Name: ssl_remover.sh
|
||||
# Description: Removes SSL certificates and cleans up LiteSpeed configurations.
|
||||
# Ensures safe removal of listeners, virtual hosts, and certificates.
|
||||
# Version: 2.0.0 (Professional-Grade Optimized)
|
||||
# Author: Gemini (Based on user request and feedback)
|
||||
# Date: 2025-03-26
|
||||
# Exit Codes:
|
||||
# 0: Success (SSL removed and configuration cleaned up)
|
||||
# 1: General Error (e.g., invalid parameters, XML validation failed)
|
||||
# 2: Backup/Restore Error (e.g., failed to create backup)
|
||||
# 3: Restart Error (e.g., LiteSpeed service failed to restart)
|
||||
# ==============================================================================
|
||||
set -euo pipefail
|
||||
|
||||
# Log file setup
|
||||
# === Configuration ===
|
||||
CONF_FILE="/var/www/conf/httpd_config.xml"
|
||||
BACKUP_DIR="/var/www/conf/backups"
|
||||
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
|
||||
CERT_DIR="/etc/letsencrypt/live"
|
||||
SCRIPT_LOG="${LOG_DIR}/ssl-remover.log"
|
||||
VERBOSE=0
|
||||
|
||||
# Function to log messages
|
||||
# === Functions ===
|
||||
log() {
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') $1"
|
||||
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$SCRIPT_LOG"
|
||||
}
|
||||
|
||||
log_verbose() {
|
||||
[[ "$VERBOSE" -eq 1 ]] && log "[VERBOSE] $1"
|
||||
}
|
||||
|
||||
# Email function (same as in ssl_manager.sh)
|
||||
send_email() {
|
||||
local subject="$1"
|
||||
local body="$2"
|
||||
local recipient="${EMAIL:-}"
|
||||
|
||||
[[ -n "$recipient" ]] && {
|
||||
if [[ -n "$recipient" ]]; then
|
||||
log "Sending email notification to $recipient..."
|
||||
curl -s "https://api.postmarkapp.com/email" \
|
||||
-X POST \
|
||||
|
|
@ -33,121 +50,153 @@ send_email() {
|
|||
\"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
|
||||
validate_domain() {
|
||||
local domain="$1"
|
||||
if [[ "$domain" =~ ^([a-zA-Z0-9](-*[a-zA-Z0-9])*\.)+[a-zA-Z]{2,}$ ]]; then
|
||||
return 0
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
backup_config() {
|
||||
local timestamp=$(date +%Y%m%d%H%M%S)
|
||||
local backup_file="${BACKUP_DIR}/httpd_config.pre-removal-${timestamp}.xml"
|
||||
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
if cp "$CONF_FILE" "$backup_file"; then
|
||||
log "Config backup saved to $backup_file"
|
||||
else
|
||||
log "❌ ERROR: Failed to create backup '$backup_file'. Exiting."
|
||||
exit 2
|
||||
fi
|
||||
}
|
||||
|
||||
remove_certificate() {
|
||||
local domain="$1"
|
||||
log "Checking for certificate for domain '$domain'..."
|
||||
|
||||
if certbot certificates | grep -q "Domains: $domain"; then
|
||||
log "Removing certificate for '$domain'..."
|
||||
if certbot delete --cert-name "$domain" --non-interactive; then
|
||||
rm -rf "/etc/letsencrypt/live/$domain"*
|
||||
log "Certificate successfully removed for '$domain'."
|
||||
else
|
||||
log "❌ ERROR: Failed to remove certificate for '$domain'."
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
log "No certificate found for '$domain'. Skipping removal."
|
||||
fi
|
||||
}
|
||||
|
||||
cleanup_listeners() {
|
||||
local domain="$1"
|
||||
local config_file="/var/www/conf/httpd_config.xml"
|
||||
local temp_file
|
||||
log "Cleaning up listeners and configurations for '$domain'..."
|
||||
|
||||
log "Cleaning up listeners for $domain..."
|
||||
|
||||
# Remove listeners
|
||||
sed -i "/<name>HTTPS-$domain<\/name>/,/<\/listener>/d" "$config_file"
|
||||
# Remove listener for the domain
|
||||
sudo xmlstarlet ed -L \
|
||||
-d "//listener[name='HTTPS-$domain']" \
|
||||
"$CONF_FILE"
|
||||
|
||||
# Remove vhostMap entries
|
||||
sed -i "/<domain>$domain<\/domain>/,/<\/vhostMap>/d" "$config_file"
|
||||
sudo xmlstarlet ed -L \
|
||||
-d "//vhostMap[domain='$domain']" \
|
||||
"$CONF_FILE"
|
||||
|
||||
# Remove related virtual host
|
||||
local vhost_name="${domain//./_}"
|
||||
sed -i "/<name>$vhost_name<\/name>/,/<\/virtualHost>/d" "$config_file"
|
||||
sudo xmlstarlet ed -L \
|
||||
-d "//virtualHost[name='$vhost_name']" \
|
||||
"$CONF_FILE"
|
||||
|
||||
# Cleanup empty listenerList tags
|
||||
temp_file=$(mktemp)
|
||||
awk '/<listenerList>/ {flag=1; print; next} /<\/listenerList>/ {flag=0; print; next} flag && /^[[:space:]]*$/ {next} {print}' "$config_file" > "$temp_file"
|
||||
mv "$temp_file" "$config_file"
|
||||
sudo xmlstarlet ed -L \
|
||||
-d "//listenerList[count(*)=0]" \
|
||||
"$CONF_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
|
||||
log "Validating XML configuration..."
|
||||
if ! sudo xmllint --noout "$CONF_FILE" 2>/dev/null; then
|
||||
log "❌ ERROR: Invalid XML configuration after cleanup. Check backups."
|
||||
return 1
|
||||
fi
|
||||
log "✔ XML configuration is valid."
|
||||
return 0
|
||||
}
|
||||
|
||||
# Restart LiteSpeed if needed
|
||||
restart_litespeed() {
|
||||
log "Restarting LiteSpeed..."
|
||||
systemctl restart lsws && log "LiteSpeed restarted successfully." || log "LiteSpeed restart failed."
|
||||
log "Restarting LiteSpeed server..."
|
||||
if sudo systemctl restart lsws; then
|
||||
log "✔ LiteSpeed server restarted successfully."
|
||||
else
|
||||
log "❌ ERROR: Failed to restart LiteSpeed server."
|
||||
return 3
|
||||
fi
|
||||
}
|
||||
|
||||
# Main execution
|
||||
# === Main Script Logic ===
|
||||
main() {
|
||||
declare -a DOMAINS
|
||||
EMAIL=""
|
||||
|
||||
# Parse parameters
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--domains=*)
|
||||
IFS=',' read -ra DOMAINS <<< "${1#*=}"
|
||||
shift
|
||||
;;
|
||||
--email=*)
|
||||
EMAIL="${1#*=}"
|
||||
shift
|
||||
;;
|
||||
--verbose)
|
||||
VERBOSE=1
|
||||
log "Verbose mode enabled."
|
||||
;;
|
||||
*)
|
||||
echo "Invalid parameter: $1"
|
||||
log "Invalid parameter: $1"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# Validate input
|
||||
if [[ ${#DOMAINS[@]} -eq 0 ]]; then
|
||||
echo "Error: --domains parameter is required"
|
||||
log "❌ ERROR: --domains parameter is required."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Ensure log directory exists
|
||||
mkdir -p "$LOG_DIR" || { log "❌ ERROR: Cannot create log directory '$LOG_DIR'. Check permissions."; exit 1; }
|
||||
touch "$SCRIPT_LOG"
|
||||
chmod 0644 "$SCRIPT_LOG"
|
||||
|
||||
# Backup configuration
|
||||
backup_config
|
||||
|
||||
# Process each domain
|
||||
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"
|
||||
if ! validate_domain "$domain"; then
|
||||
log "❌ ERROR: Invalid domain '$domain'. Skipping."
|
||||
continue
|
||||
}
|
||||
fi
|
||||
|
||||
# Remove certificate
|
||||
remove_certificate "$domain"
|
||||
|
||||
# Clean up listeners and configurations
|
||||
cleanup_listeners "$domain"
|
||||
done
|
||||
|
||||
# Validate XML configuration
|
||||
if validate_xml; then
|
||||
restart_litespeed
|
||||
send_email "SSL Removal Complete" "Successfully removed SSL for domains: ${DOMAINS[*]}"
|
||||
|
|
@ -157,4 +206,5 @@ main() {
|
|||
fi
|
||||
}
|
||||
|
||||
# === Entry Point ===
|
||||
main "$@"
|
||||
Loading…
Reference in New Issue