361 lines
11 KiB
Bash
361 lines
11 KiB
Bash
#!/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}"
|
|
|
|
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 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 "🔐 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 ""
|
|
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)"
|
|
;;
|
|
esac
|