#!/bin/bash # ============================================================================= # СОЗДАНИЕ NGINX КОНФИГУРАЦИИ ДЛЯ MY UPLOADER BOT # ============================================================================= if [ $# -lt 2 ]; then echo "Usage: $0 " exit 1 fi DOMAIN="$1" PROJECT_DIR="$2" NGINX_CONFIG="/etc/nginx/sites-available/my-uploader-bot" echo "Создание Nginx конфигурации для $DOMAIN..." cat > "$NGINX_CONFIG" << EOF # ============================================================================= # MY UPLOADER BOT - NGINX CONFIGURATION # ============================================================================= # Domain: $DOMAIN # Generated: $(date) # ============================================================================= # Rate limiting zones limit_req_zone \$binary_remote_addr zone=api_limit:10m rate=10r/s; limit_req_zone \$binary_remote_addr zone=upload_limit:10m rate=2r/s; limit_req_zone \$binary_remote_addr zone=general_limit:10m rate=20r/s; # Upstream для основного приложения upstream my_uploader_app { server 127.0.0.1:15100 max_fails=3 fail_timeout=30s; keepalive 32; } # Upstream для web2-client upstream web2_client { server 127.0.0.1:3000 max_fails=3 fail_timeout=30s; keepalive 16; } # Upstream для converter-module upstream converter_module { server 127.0.0.1:8080 max_fails=3 fail_timeout=30s; keepalive 16; } # Redirect HTTP to HTTPS server { listen 80; listen [::]:80; server_name $DOMAIN www.$DOMAIN; # ACME challenge для Let's Encrypt location /.well-known/acme-challenge/ { root /var/www/html; try_files \$uri =404; } # Redirect всех остальных запросов на HTTPS location / { return 301 https://\$server_name\$request_uri; } } # HTTPS Main Server server { listen 443 ssl http2; listen [::]:443 ssl http2; server_name $DOMAIN www.$DOMAIN; # SSL Configuration ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem; ssl_trusted_certificate /etc/letsencrypt/live/$DOMAIN/chain.pem; # SSL 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 X-Frame-Options "SAMEORIGIN" 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; add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net https://unpkg.com; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com https://cdn.jsdelivr.net; img-src 'self' data: https: blob:; connect-src 'self' https: wss: ws:; media-src 'self' https: blob:; object-src 'none'; base-uri 'self'; form-action 'self';" always; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always; # Basic Settings client_max_body_size 100M; client_body_timeout 60s; client_header_timeout 60s; keepalive_timeout 65s; send_timeout 60s; # Gzip Compression gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json application/ld+json image/svg+xml; # Logging access_log /var/log/nginx/my-uploader-bot.access.log; error_log /var/log/nginx/my-uploader-bot.error.log; # ========================================================================== # ОСНОВНЫЕ МАРШРУТЫ # ========================================================================== # API routes location /api/ { limit_req zone=api_limit burst=20 nodelay; proxy_pass http://my_uploader_app; 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-Forwarded-Host \$host; proxy_set_header X-Forwarded-Port \$server_port; proxy_cache_bypass \$http_upgrade; proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; # Специальные настройки для upload endpoints location /api/upload/ { limit_req zone=upload_limit burst=5 nodelay; client_max_body_size 500M; proxy_read_timeout 300s; proxy_send_timeout 300s; proxy_pass http://my_uploader_app; } } # Health check endpoint location /health { proxy_pass http://my_uploader_app; proxy_http_version 1.1; 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; access_log off; } # Telegram webhook endpoint location /webhook/ { limit_req zone=api_limit burst=50 nodelay; proxy_pass http://my_uploader_app; proxy_http_version 1.1; 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 for main app location /static/ { expires 1y; add_header Cache-Control "public, immutable"; try_files \$uri @app_static; } location @app_static { proxy_pass http://my_uploader_app; proxy_http_version 1.1; proxy_set_header Host \$host; proxy_cache_valid 200 1d; } # ========================================================================== # WEB2-CLIENT (фронтенд интерфейс) # ========================================================================== location /upload/ { limit_req zone=general_limit burst=10 nodelay; proxy_pass http://web2_client/; 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; } location /client/ { limit_req zone=general_limit burst=10 nodelay; proxy_pass http://web2_client/; 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; } # ========================================================================== # CONVERTER-MODULE (конвертер медиа) # ========================================================================== location /convert/ { limit_req zone=upload_limit burst=3 nodelay; client_max_body_size 500M; proxy_pass http://converter_module/; proxy_http_version 1.1; 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_connect_timeout 300s; proxy_send_timeout 300s; proxy_read_timeout 300s; } # ========================================================================== # ОСНОВНОЙ МАРШРУТ (главная страница) # ========================================================================== location / { limit_req zone=general_limit burst=20 nodelay; proxy_pass http://my_uploader_app; 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-Forwarded-Host \$host; proxy_set_header X-Forwarded-Port \$server_port; proxy_cache_bypass \$http_upgrade; } # ========================================================================== # СПЕЦИАЛЬНЫЕ ФАЙЛЫ # ========================================================================== # robots.txt location = /robots.txt { return 200 "User-agent: *\nDisallow: /api/\nDisallow: /webhook/\nAllow: /\n"; add_header Content-Type text/plain; } # favicon.ico location = /favicon.ico { proxy_pass http://my_uploader_app; expires 1y; add_header Cache-Control "public, immutable"; access_log off; } # Защита от доступа к скрытым файлам location ~ /\. { deny all; access_log off; log_not_found off; } # Защита от доступа к конфигурационным файлам location ~* \.(env|conf|config|ini|log|bak|backup|tmp)$ { deny all; access_log off; log_not_found off; } } # ============================================================================= # ДОПОЛНИТЕЛЬНАЯ БЕЗОПАСНОСТЬ # ============================================================================= # Блокировка ботов и сканеров map \$http_user_agent \$blocked_agent { ~*malicious 1; ~*bot 0; ~*crawler 0; ~*spider 0; default 0; } # Блокировка IP по геолокации (опционально) # geo \$blocked_country { # default 0; # CN 1; # Китай # RU 0; # Россия разрешена # } EOF echo "✅ Nginx конфигурация создана: $NGINX_CONFIG" # Создание директории для логов mkdir -p /var/log/nginx # Проверка синтаксиса echo "Проверка синтаксиса Nginx..." nginx -t -c /etc/nginx/nginx.conf echo "✅ Nginx конфигурация готова для $DOMAIN"