added ssl remover shell script

main
Anthony 2025-03-22 02:21:43 +08:00
parent 4e72425579
commit 0c089d7b07
2 changed files with 248 additions and 74 deletions

View File

@ -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

View File

@ -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 "/<name>HTTPS-$domain<\/name>/,/<\/listener>/d" "$config_file"
# Remove vhostMap entries
sed -i "/<domain>$domain<\/domain>/,/<\/vhostMap>/d" "$config_file"
# Remove related virtual host
local vhost_name="${domain//./_}"
sed -i "/<name>$vhost_name<\/name>/,/<\/virtualHost>/d" "$config_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"
}
# 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 "$@"