#!/bin/bash # FOXHUNT PRODUCTION CERTIFICATE DEPLOYMENT SCRIPT # This script deploys production-grade TLS certificates # Author: Claude Code Security Deployment # Date: 2025-09-07 set -euo pipefail # Configuration CERT_DIR="/etc/foxhunt/certs" BACKUP_DIR="/etc/foxhunt/certs/backup/$(date +%Y%m%d-%H%M%S)" LOG_FILE="/var/log/foxhunt/cert-deployment.log" SERVICES=("trading-engine" "market-data" "ai-intelligence" "broker-connector" "data-aggregator" "integration-hub" "persistence") # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Logging function log() { echo -e "${BLUE}[$(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "${LOG_FILE}" } error() { echo -e "${RED}[ERROR $(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "${LOG_FILE}" } success() { echo -e "${GREEN}[SUCCESS $(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "${LOG_FILE}" } warning() { echo -e "${YELLOW}[WARNING $(date '+%Y-%m-%d %H:%M:%S')]${NC} $1" | tee -a "${LOG_FILE}" } # Check if running as root check_root() { if [[ $EUID -ne 0 ]]; then error "This script must be run as root for certificate deployment" exit 1 fi } # Create necessary directories setup_directories() { log "Setting up certificate directories..." mkdir -p "${CERT_DIR}" mkdir -p "${BACKUP_DIR}" mkdir -p "/var/log/foxhunt" # Set proper permissions chmod 755 "${CERT_DIR}" chmod 700 "${BACKUP_DIR}" chmod 755 "/var/log/foxhunt" for service in "${SERVICES[@]}"; do mkdir -p "${CERT_DIR}/services/${service}" chmod 755 "${CERT_DIR}/services/${service}" done mkdir -p "${CERT_DIR}/ca" chmod 700 "${CERT_DIR}/ca" success "Certificate directories created successfully" } # Backup existing certificates backup_existing_certs() { log "Backing up existing certificates..." if [[ -d "${CERT_DIR}" ]] && [[ $(ls -A "${CERT_DIR}" 2>/dev/null) ]]; then cp -r "${CERT_DIR}"/* "${BACKUP_DIR}/" 2>/dev/null || true success "Existing certificates backed up to ${BACKUP_DIR}" else log "No existing certificates to backup" fi } # Generate production CA certificate generate_production_ca() { log "Generating production CA certificate..." # CA private key openssl genpkey -algorithm RSA -out "${CERT_DIR}/ca/ca-key.pem" -pkcs8 -aes256 \ -pass pass:"${CA_PASSWORD:-$(openssl rand -base64 32)}" # CA certificate openssl req -new -x509 -key "${CERT_DIR}/ca/ca-key.pem" \ -out "${CERT_DIR}/ca/ca-cert.pem" \ -days 3650 \ -pass pass:"${CA_PASSWORD:-$(openssl rand -base64 32)}" \ -subj "/C=US/ST=NY/L=NewYork/O=Foxhunt Production/OU=Security/CN=Foxhunt Production CA" \ -extensions v3_ca \ -config <(cat < "${service_dir}/${service}-chain.pem" # Set proper permissions chmod 400 "${service_dir}/${service}-key.pem" chmod 444 "${service_dir}/${service}-cert.pem" chmod 444 "${service_dir}/${service}-chain.pem" # Clean up CSR rm -f "${service_dir}/${service}-csr.pem" success "Certificate generated for ${service}" done } # Generate main application certificates generate_main_certificates() { log "Generating main application certificates..." # Main application private key openssl genpkey -algorithm RSA -out "${CERT_DIR}/foxhunt-key.pem" -pkcs8 # Certificate signing request for main application openssl req -new -key "${CERT_DIR}/foxhunt-key.pem" \ -out "${CERT_DIR}/foxhunt-csr.pem" \ -subj "/C=US/ST=NY/L=NewYork/O=Foxhunt Production/OU=Trading Platform/CN=trading.foxhunt.com" \ -config <(cat < "${CERT_DIR}/foxhunt-chain.pem" # Set proper permissions chmod 400 "${CERT_DIR}/foxhunt-key.pem" chmod 444 "${CERT_DIR}/foxhunt-cert.pem" chmod 444 "${CERT_DIR}/foxhunt-chain.pem" # Clean up CSR rm -f "${CERT_DIR}/foxhunt-csr.pem" success "Main application certificates generated" } # Validate certificates validate_certificates() { log "Validating generated certificates..." # Validate CA certificate if openssl x509 -in "${CERT_DIR}/ca/ca-cert.pem" -noout -text >/dev/null 2>&1; then success "CA certificate is valid" else error "CA certificate validation failed" return 1 fi # Validate service certificates for service in "${SERVICES[@]}"; do local cert_file="${CERT_DIR}/services/${service}/${service}-cert.pem" if openssl x509 -in "${cert_file}" -noout -text >/dev/null 2>&1; then # Verify certificate chain if openssl verify -CAfile "${CERT_DIR}/ca/ca-cert.pem" "${cert_file}" >/dev/null 2>&1; then success "Certificate for ${service} is valid and properly signed" else error "Certificate chain validation failed for ${service}" return 1 fi else error "Certificate validation failed for ${service}" return 1 fi done # Validate main application certificate if openssl x509 -in "${CERT_DIR}/foxhunt-cert.pem" -noout -text >/dev/null 2>&1; then if openssl verify -CAfile "${CERT_DIR}/ca/ca-cert.pem" "${CERT_DIR}/foxhunt-cert.pem" >/dev/null 2>&1; then success "Main application certificate is valid and properly signed" else error "Main application certificate chain validation failed" return 1 fi else error "Main application certificate validation failed" return 1 fi } # Set up certificate monitoring setup_certificate_monitoring() { log "Setting up certificate monitoring..." # Create certificate expiry check script cat > /usr/local/bin/foxhunt-cert-monitor.sh << 'EOF' #!/bin/bash # Foxhunt Certificate Monitoring Script # Checks certificate expiry and sends alerts CERT_DIR="/etc/foxhunt/certs" ALERT_DAYS=30 ALERT_EMAIL="security-alerts@foxhunt.com" check_cert_expiry() { local cert_file=$1 local cert_name=$2 if [[ ! -f "$cert_file" ]]; then echo "Certificate file not found: $cert_file" return 1 fi local expiry_date=$(openssl x509 -in "$cert_file" -noout -enddate | cut -d= -f2) local expiry_timestamp=$(date -d "$expiry_date" +%s) local current_timestamp=$(date +%s) local days_until_expiry=$(( (expiry_timestamp - current_timestamp) / 86400 )) if [[ $days_until_expiry -le $ALERT_DAYS ]]; then echo "ALERT: Certificate $cert_name expires in $days_until_expiry days" # Send alert email (configure your mail system) # echo "Certificate $cert_name expires in $days_until_expiry days" | mail -s "Certificate Expiry Alert" "$ALERT_EMAIL" else echo "Certificate $cert_name is valid for $days_until_expiry days" fi } # Check all certificates check_cert_expiry "$CERT_DIR/ca/ca-cert.pem" "CA Certificate" check_cert_expiry "$CERT_DIR/foxhunt-cert.pem" "Main Application Certificate" for service_dir in "$CERT_DIR/services"/*; do if [[ -d "$service_dir" ]]; then service_name=$(basename "$service_dir") check_cert_expiry "$service_dir/${service_name}-cert.pem" "$service_name Service Certificate" fi done EOF chmod +x /usr/local/bin/foxhunt-cert-monitor.sh # Create systemd timer for certificate monitoring cat > /etc/systemd/system/foxhunt-cert-monitor.service << EOF [Unit] Description=Foxhunt Certificate Monitoring After=network.target [Service] Type=oneshot ExecStart=/usr/local/bin/foxhunt-cert-monitor.sh User=root EOF cat > /etc/systemd/system/foxhunt-cert-monitor.timer << EOF [Unit] Description=Run Foxhunt Certificate Monitoring Daily Requires=foxhunt-cert-monitor.service [Timer] OnCalendar=daily Persistent=true [Install] WantedBy=timers.target EOF systemctl daemon-reload systemctl enable foxhunt-cert-monitor.timer systemctl start foxhunt-cert-monitor.timer success "Certificate monitoring configured" } # Generate Diffie-Hellman parameters generate_dh_params() { log "Generating Diffie-Hellman parameters (this may take a while)..." # Generate strong DH parameters openssl dhparam -out "${CERT_DIR}/dhparam.pem" 4096 chmod 444 "${CERT_DIR}/dhparam.pem" success "Diffie-Hellman parameters generated" } # Create certificate deployment summary create_deployment_summary() { log "Creating certificate deployment summary..." local summary_file="/etc/foxhunt/certs/deployment-summary.txt" cat > "$summary_file" << EOF FOXHUNT PRODUCTION CERTIFICATE DEPLOYMENT SUMMARY ================================================= Deployment Date: $(date) Deployment Script: $0 Backup Location: $BACKUP_DIR CERTIFICATES GENERATED: ---------------------- 1. Certificate Authority (CA) - Location: ${CERT_DIR}/ca/ca-cert.pem - Key: ${CERT_DIR}/ca/ca-key.pem - Validity: 10 years - Algorithm: RSA 4096-bit 2. Main Application Certificate - Location: ${CERT_DIR}/foxhunt-cert.pem - Key: ${CERT_DIR}/foxhunt-key.pem - Chain: ${CERT_DIR}/foxhunt-chain.pem - Validity: 1 year - Algorithm: RSA 2048-bit - Domains: trading.foxhunt.com, api.foxhunt.com, ws.foxhunt.com, *.foxhunt.com 3. Service Certificates: EOF for service in "${SERVICES[@]}"; do cat >> "$summary_file" << EOF - ${service}: ${CERT_DIR}/services/${service}/${service}-cert.pem Domain: ${service}.production.foxhunt.internal EOF done cat >> "$summary_file" << EOF SECURITY FEATURES ENABLED: ------------------------- - TLS 1.3 minimum - Perfect Forward Secrecy - Certificate chain validation - OCSP stapling ready - Certificate monitoring configured - Automated expiry alerts NEXT STEPS: ---------- 1. Update application configuration to use new certificates 2. Restart all services to load new certificates 3. Configure load balancer/proxy with new certificates 4. Test TLS configuration with SSL Labs or similar tool 5. Monitor certificate expiry alerts MAINTENANCE: ----------- - Certificates expire in 1 year ($(date -d "+1 year")) - Set up automated renewal before expiry - Monitor certificate chain validity - Regular security audits recommended For support: security-team@foxhunt.com EOF chmod 644 "$summary_file" success "Deployment summary created at $summary_file" } # Main deployment function main() { echo "===============================================" echo "FOXHUNT PRODUCTION CERTIFICATE DEPLOYMENT" echo "===============================================" log "Starting production certificate deployment..." check_root setup_directories backup_existing_certs generate_production_ca generate_service_certificates generate_main_certificates generate_dh_params validate_certificates setup_certificate_monitoring create_deployment_summary echo "" success "===============================================" success "CERTIFICATE DEPLOYMENT COMPLETED SUCCESSFULLY" success "===============================================" echo "" log "Summary file: /etc/foxhunt/certs/deployment-summary.txt" log "Backup location: $BACKUP_DIR" log "Log file: $LOG_FILE" echo "" warning "IMPORTANT: Update your application configuration to use the new certificates!" warning "IMPORTANT: Restart all services to load the new certificates!" echo "" } # Run main function main "$@"