Skip to content

Instantly share code, notes, and snippets.

@mindfulvector
Created September 25, 2024 23:29
Show Gist options
  • Save mindfulvector/8320e9c089aaf0e375579f2e555c3bbc to your computer and use it in GitHub Desktop.
Save mindfulvector/8320e9c089aaf0e375579f2e555c3bbc to your computer and use it in GitHub Desktop.
lego --run-hook script to install into Apache2
#!/bin/bash
# Check if all required environment variables are set
required_vars=("LEGO_ACCOUNT_EMAIL" "LEGO_CERT_DOMAIN" "LEGO_CERT_PATH" "LEGO_CERT_KEY_PATH")
for var in "${required_vars[@]}"; do
if [ -z "${!var}" ]; then
echo "Error: $var is not set"
exit 1
fi
done
# Set Apache configuration directories
APACHE_CONF_DIR="/etc/apache2"
SITES_ENABLED_DIR="${APACHE_CONF_DIR}/sites-enabled"
SITES_AVAILABLE_DIR="${APACHE_CONF_DIR}/sites-available"
# Set backup directory
BACKUP_DIR="/root/backups"
# Derive the path for the CA bundle
LEGO_CA_CERT_PATH="${LEGO_CERT_PATH%.*}.issuer.crt"
# Function to backup a file
backup_file() {
local file=$1
local filename=$(basename "$file")
local timestamp=$(date +"%Y%m%d_%H%M%S")
local backup="${BACKUP_DIR}/${filename}_${timestamp}.bak"
# Create backup directory if it doesn't exist
mkdir -p "$BACKUP_DIR"
# Create the backup
cp "$file" "$backup"
echo "Backed up $file to $backup"
# Verify backup
if cmp -s "$file" "$backup"; then
local size=$(wc -c < "$file")
if [ $size -ge 100 ]; then # Assuming 100 bytes is a reasonable minimum length
echo "Backup verified successfully for $file"
else
echo "Warning: Backup file $backup seems too small (${size} bytes)"
fi
else
echo "Error: Backup verification failed for $file"
exit 1
fi
}
# Function to check SSL cipher compatibility
check_ssl_cipher_compatibility() {
local config_file=$1
local ssl_cipher_suite=$(grep "SSLCipherSuite" "$config_file" | awk '{print $2}')
if [ -z "$ssl_cipher_suite" ]; then
echo "Error: SSLCipherSuite not found in $config_file"
return 1
fi
local needs_update=false
local update_recommendation=""
# Check for presence of necessary ciphers
if [[ "$ssl_cipher_suite" != *"HIGH"* && "$ssl_cipher_suite" != *"MEDIUM"* && "$ssl_cipher_suite" != "ALL"* ]]; then
needs_update=true
update_recommendation=":HIGH:MEDIUM"
fi
# Check for exclusion of weak ciphers
if [[ "$ssl_cipher_suite" != *"!LOW"* && "$ssl_cipher_suite" != *"!EXP"* && "$ssl_cipher_suite" != *"!EXPORT"* ]]; then
needs_update=true
update_recommendation="$update_recommendation:!LOW:!EXP"
fi
# Check for exclusion of NULL ciphers if not already present
if [[ "$ssl_cipher_suite" != *"!aNULL"* || "$ssl_cipher_suite" != *"!eNULL"* ]]; then
needs_update=true
update_recommendation="$update_recommendation:!aNULL:!eNULL"
fi
# Check for modern protocols (assumed to be included if ALL is used)
if [[ "$ssl_cipher_suite" != "ALL"* && "$ssl_cipher_suite" != *"TLSv1.2"* ]]; then
needs_update=true
update_recommendation="$update_recommendation:TLSv1.2"
fi
if $needs_update; then
echo "Warning: SSLCipherSuite in $config_file may need to be updated for optimal security with modern certificates"
echo "Current value: $ssl_cipher_suite"
echo "Recommended additions: ${update_recommendation}"
echo "Please review and update the SSLCipherSuite directive if necessary"
return 1
else
echo "SSLCipherSuite in $config_file appears to be compatible with modern certificates"
return 0
fi
}
# Function to update SSL certificate files in a configuration
update_ssl_config() {
local config_file=$1
# Backup the original file
backup_file "$config_file"
# Update certificate file paths
sed -i "s|SSLCertificateFile .*|SSLCertificateFile ${LEGO_CERT_PATH}|" "$config_file"
sed -i "s|SSLCertificateKeyFile .*|SSLCertificateKeyFile ${LEGO_CERT_KEY_PATH}|" "$config_file"
sed -i "s|SSLCACertificateFile .*|SSLCACertificateFile ${LEGO_CA_CERT_PATH}|" "$config_file"
echo "Updated SSL certificate paths in $config_file"
}
# Process each enabled site
for site in "$SITES_ENABLED_DIR"/*; do
if [ -L "$site" ]; then
real_config=$(readlink -f "$site")
echo "Processing $real_config"
# Check if this config is for the domain we're updating
if grep -q "ServerName ${LEGO_CERT_DOMAIN}" "$real_config"; then
if check_ssl_cipher_compatibility "$real_config"; then
update_ssl_config "$real_config"
else
echo "Skipping update for $real_config due to incompatible SSLCipherSuite"
echo "Please update the SSLCipherSuite directive before proceeding"
exit 1
fi
else
echo "Skipping $real_config (not for ${LEGO_CERT_DOMAIN})"
fi
fi
done
# Reload Apache to apply changes
service apache2 reload
echo "Certificate installation process completed for ${LEGO_CERT_DOMAIN}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment