Files
drone-detector/ssl/nginx-ssl-setup.sh
2025-09-12 23:06:34 +02:00

436 lines
14 KiB
Bash
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# Nginx SSL Configuration Script
# Automatically configures nginx with SSL certificates for dev.uggla.uamils.com
set -e
# Configuration
DOMAIN="${DOMAIN:-dev.uggla.uamils.com}"
CERT_PATH="/etc/letsencrypt/live/$DOMAIN"
SITES_AVAILABLE="/etc/nginx/sites-available"
SITES_ENABLED="/etc/nginx/sites-enabled"
CONFIG_NAME="$DOMAIN"
# Backend and frontend ports (from docker-compose)
BACKEND_PORT="${BACKEND_PORT:-3002}"
FRONTEND_PORT="${FRONTEND_PORT:-3001}"
MANAGEMENT_PORT="${MANAGEMENT_PORT:-3003}"
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
check_prerequisites() {
log "Checking prerequisites..."
# Check if running as root
if [[ $EUID -ne 0 ]]; then
log "ERROR: This script must be run as root (use sudo)"
exit 1
fi
# Check if nginx is installed
if ! command -v nginx >/dev/null 2>&1; then
log "ERROR: Nginx is not installed. Install with: sudo apt install nginx"
exit 1
fi
# Check if certificates exist
if [[ ! -f "$CERT_PATH/fullchain.pem" || ! -f "$CERT_PATH/privkey.pem" ]]; then
log "ERROR: SSL certificates not found at $CERT_PATH"
log "Please run SSL certificate generation first:"
log " cd ssl && ./certbot-manager.sh renew"
exit 1
fi
log "Prerequisites check passed"
}
create_nginx_config() {
log "Creating nginx configuration for $DOMAIN..."
cat > "$SITES_AVAILABLE/$CONFIG_NAME" << EOF
# Nginx configuration for $DOMAIN
# Multi-tenant drone detection system with SSL
# HTTP to HTTPS redirect
server {
listen 80;
server_name $DOMAIN *.$DOMAIN;
# ACME challenge location for Let's Encrypt
location /.well-known/acme-challenge/ {
root /var/www/html;
try_files \$uri =404;
}
# Redirect all other traffic to HTTPS
location / {
return 301 https://\$server_name\$request_uri;
}
}
# HTTPS server for main domain
server {
listen 443 ssl http2;
server_name $DOMAIN;
# SSL Configuration
ssl_certificate $CERT_PATH/fullchain.pem;
ssl_certificate_key $CERT_PATH/privkey.pem;
# SSL Security Settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_stapling on;
ssl_stapling_verify on;
# Security Headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Root location - serve frontend
location / {
proxy_pass http://127.0.0.1:$FRONTEND_PORT;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_cache_bypass \$http_upgrade;
# Timeouts
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
# API routes - proxy to backend
location /api/ {
proxy_pass http://127.0.0.1:$BACKEND_PORT;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_cache_bypass \$http_upgrade;
# Timeouts
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
# Health check endpoint
location /health {
proxy_pass http://127.0.0.1:$BACKEND_PORT;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
# WebSocket support for real-time features
location /ws {
proxy_pass http://127.0.0.1:$BACKEND_PORT;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
}
# Static files (if served directly by nginx)
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)\$ {
proxy_pass http://127.0.0.1:$FRONTEND_PORT;
expires 1y;
add_header Cache-Control "public, immutable";
}
}
# HTTPS server for management subdomain
server {
listen 443 ssl http2;
server_name management.$DOMAIN;
# SSL Configuration
ssl_certificate $CERT_PATH/fullchain.pem;
ssl_certificate_key $CERT_PATH/privkey.pem;
# SSL Security Settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_stapling on;
ssl_stapling_verify on;
# Security Headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Management portal - serve from management container
location / {
proxy_pass http://127.0.0.1:$MANAGEMENT_PORT;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_cache_bypass \$http_upgrade;
# Timeouts
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
# API routes - proxy to backend (management uses same API)
location /api/ {
proxy_pass http://127.0.0.1:$BACKEND_PORT;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_cache_bypass \$http_upgrade;
# Timeouts
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
# Static files for management portal
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)\$ {
proxy_pass http://127.0.0.1:$MANAGEMENT_PORT;
expires 1y;
add_header Cache-Control "public, immutable";
}
}
# HTTPS server for wildcard subdomains (multi-tenant)
server {
listen 443 ssl http2;
server_name *.$DOMAIN;
# SSL Configuration (same certificates work for wildcard)
ssl_certificate $CERT_PATH/fullchain.pem;
ssl_certificate_key $CERT_PATH/privkey.pem;
# SSL Security Settings (same as main domain)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384;
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_stapling on;
ssl_stapling_verify on;
# Security Headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Frame-Options DENY always;
add_header X-Content-Type-Options nosniff always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
# Multi-tenant routing - pass subdomain to backend
location / {
proxy_pass http://127.0.0.1:$FRONTEND_PORT;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header X-Tenant-Domain \$host;
proxy_cache_bypass \$http_upgrade;
# Timeouts
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
# API routes for multi-tenant
location /api/ {
proxy_pass http://127.0.0.1:$BACKEND_PORT;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header X-Tenant-Domain \$host;
proxy_cache_bypass \$http_upgrade;
# Timeouts
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
# Health check for subdomains
location /health {
proxy_pass http://127.0.0.1:$BACKEND_PORT;
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header X-Tenant-Domain \$host;
}
# WebSocket support for multi-tenant
location /ws {
proxy_pass http://127.0.0.1:$BACKEND_PORT;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host \$host;
proxy_set_header X-Real-IP \$remote_addr;
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto \$scheme;
proxy_set_header X-Tenant-Domain \$host;
}
}
EOF
log "Nginx configuration created at $SITES_AVAILABLE/$CONFIG_NAME"
}
enable_site() {
log "Enabling nginx site..."
# Remove default site if it exists
if [[ -f "$SITES_ENABLED/default" ]]; then
log "Removing default nginx site"
rm -f "$SITES_ENABLED/default"
fi
# Enable our site
ln -sf "$SITES_AVAILABLE/$CONFIG_NAME" "$SITES_ENABLED/"
log "Site enabled"
}
test_and_reload() {
log "Testing nginx configuration..."
if nginx -t; then
log "✅ Nginx configuration is valid"
log "Reloading nginx..."
systemctl reload nginx
log "✅ Nginx reloaded successfully"
else
log "❌ Nginx configuration has errors"
log "Configuration file: $SITES_AVAILABLE/$CONFIG_NAME"
exit 1
fi
}
show_results() {
log "SSL Configuration Complete! 🎉"
echo ""
echo "======================================"
echo "Nginx SSL Configuration Summary"
echo "======================================"
echo ""
echo "🌐 Your site is now available at:"
echo " https://$DOMAIN"
echo ""
echo "<22> Management portal:"
echo " https://management.$DOMAIN"
echo ""
echo "<22>🔐 Multi-tenant subdomains:"
echo " https://tenant1.$DOMAIN"
echo " https://tenant2.$DOMAIN"
echo " https://any-name.$DOMAIN"
echo ""
echo "🔗 API endpoints:"
echo " https://$DOMAIN/api/health"
echo " https://$DOMAIN/api/"
echo ""
echo "🔒 SSL Features enabled:"
echo " ✅ HTTP to HTTPS redirect"
echo " ✅ SSL/TLS encryption"
echo " ✅ Security headers"
echo " ✅ Wildcard certificate support"
echo " ✅ Multi-tenant routing"
echo " ✅ Dedicated management portal"
echo ""
echo "📝 Configuration file:"
echo " $SITES_AVAILABLE/$CONFIG_NAME"
echo ""
echo "🔄 Auto-renewal:"
echo " SSL certificates will auto-renew via cron/systemd"
echo "======================================"
}
# Main execution
main() {
log "Starting Nginx SSL configuration for $DOMAIN"
check_prerequisites
create_nginx_config
enable_site
test_and_reload
show_results
}
# Handle command line arguments
case "${1:-setup}" in
"setup"|"configure")
main
;;
"test")
nginx -t
;;
"reload")
systemctl reload nginx
;;
"status")
systemctl status nginx
;;
*)
echo "Nginx SSL Configuration Script"
echo "============================="
echo ""
echo "Usage: $0 [command]"
echo ""
echo "Commands:"
echo " setup Setup SSL configuration (default)"
echo " test Test nginx configuration"
echo " reload Reload nginx"
echo " status Show nginx status"
echo ""
echo "Environment variables:"
echo " DOMAIN Domain name (default: dev.uggla.uamils.com)"
echo " BACKEND_PORT Backend port (default: 3002)"
echo " FRONTEND_PORT Frontend port (default: 3001)"
echo " MANAGEMENT_PORT Management portal port (default: 3003)"
;;
esac