#!/bin/bash # MY Network Nginx + SSL Setup # Настройка nginx с SSL сертификатами через certbot set -e DOMAIN="my-public-node-3.projscale.dev" EMAIL="admin@projscale.dev" SERVICE_PORT="15100" echo "🔒 MY Network Nginx + SSL Setup" echo "===============================" echo "Домен: $DOMAIN" echo "Email: $EMAIL" echo "Сервис порт: $SERVICE_PORT" echo "" # Проверка root прав if [[ $EUID -ne 0 ]]; then echo "❌ Запустите от root: sudo bash setup_nginx_ssl.sh" exit 1 fi # Обновление системы echo "🔄 Обновление системы..." apt update # Установка необходимых пакетов echo "📦 Установка nginx, certbot, ufw..." apt install -y nginx certbot python3-certbot-nginx ufw curl # Остановка nginx для получения сертификата echo "🛑 Остановка nginx..." systemctl stop nginx || true # Настройка firewall echo "🔥 Настройка firewall..." ufw --force reset ufw default deny incoming ufw default allow outgoing # SSH ufw allow 22/tcp comment 'SSH' # HTTP/HTTPS ufw allow 80/tcp comment 'HTTP' ufw allow 443/tcp comment 'HTTPS' # Внутренний порт сервиса (только локально) ufw allow from 127.0.0.1 to any port $SERVICE_PORT comment 'MY Network Local' ufw --force enable # Получение SSL сертификата echo "🔐 Получение SSL сертификата..." certbot certonly \ --standalone \ --non-interactive \ --agree-tos \ --email $EMAIL \ -d $DOMAIN # Проверка что сертификат получен if [[ ! -f "/etc/letsencrypt/live/$DOMAIN/fullchain.pem" ]]; then echo "❌ Не удалось получить SSL сертификат!" exit 1 fi echo "✅ SSL сертификат получен" # Создание конфигурации nginx echo "🌐 Настройка nginx..." # Удаление дефолтного сайта rm -f /etc/nginx/sites-enabled/default # Создание конфигурации MY Network cat > /etc/nginx/sites-available/my-network << EOF # MY Network Bootstrap Node - Nginx Configuration # HTTP -> HTTPS redirect server { listen 80; server_name $DOMAIN; # Certbot renewal location /.well-known/acme-challenge/ { root /var/www/html; } # Redirect all HTTP to HTTPS location / { return 301 https://\$server_name\$request_uri; } } # HTTPS server server { listen 443 ssl http2; server_name $DOMAIN; # SSL Configuration ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem; # SSL Security ssl_protocols TLSv1.2 TLSv1.3; ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384; ssl_prefer_server_ciphers on; ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; # 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; add_header X-MY-Network-Version "2.0" always; add_header X-MY-Network-Node "bootstrap" always; # Hide nginx version server_tokens off; # Gzip compression gzip on; gzip_vary on; gzip_min_length 1024; gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; # Rate limiting limit_req_zone \$binary_remote_addr zone=api:10m rate=10r/s; limit_req_zone \$binary_remote_addr zone=monitor:10m rate=1r/s; # Main application proxy location / { # Rate limiting limit_req zone=api burst=20 nodelay; proxy_pass http://127.0.0.1:$SERVICE_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-Forwarded-Host \$host; proxy_set_header X-Forwarded-Port \$server_port; # Timeouts proxy_connect_timeout 5s; proxy_send_timeout 10s; proxy_read_timeout 10s; # Buffering proxy_buffering on; proxy_buffer_size 4k; proxy_buffers 8 4k; # CORS headers add_header Access-Control-Allow-Origin "*" always; add_header Access-Control-Allow-Methods "GET, POST, OPTIONS" always; add_header Access-Control-Allow-Headers "Content-Type, Authorization" always; # Handle preflight requests if (\$request_method = 'OPTIONS') { add_header Access-Control-Allow-Origin "*"; add_header Access-Control-Allow-Methods "GET, POST, OPTIONS"; add_header Access-Control-Allow-Headers "Content-Type, Authorization"; add_header Access-Control-Max-Age 86400; add_header Content-Length 0; add_header Content-Type text/plain; return 204; } } # Monitor endpoint with stricter rate limiting location /api/my/monitor/ { limit_req zone=monitor burst=5 nodelay; proxy_pass http://127.0.0.1:$SERVICE_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; # Cache static content expires 30s; add_header Cache-Control "public, no-transform"; } # Health check endpoint location /api/my/health { proxy_pass http://127.0.0.1:$SERVICE_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; # No caching for health checks add_header Cache-Control "no-cache, no-store, must-revalidate"; add_header Pragma "no-cache"; add_header Expires "0"; } # Block access to sensitive files location ~ /\. { deny all; access_log off; log_not_found off; } # Custom error pages error_page 404 /404.html; error_page 500 502 503 504 /50x.html; location = /404.html { return 404 '{"error": "Not Found", "message": "MY Network endpoint not found"}'; add_header Content-Type application/json; } location = /50x.html { return 500 '{"error": "Server Error", "message": "MY Network temporarily unavailable"}'; add_header Content-Type application/json; } } EOF # Активация сайта ln -sf /etc/nginx/sites-available/my-network /etc/nginx/sites-enabled/ # Проверка конфигурации nginx echo "🔍 Проверка конфигурации nginx..." nginx -t if [[ $? -ne 0 ]]; then echo "❌ Ошибка в конфигурации nginx!" exit 1 fi # Настройка автообновления сертификатов echo "🔄 Настройка автообновления сертификатов..." cat > /etc/cron.d/certbot-renew << EOF # Автообновление SSL сертификатов MY Network 0 12 * * * root certbot renew --quiet --post-hook "systemctl reload nginx" EOF # Запуск nginx echo "🚀 Запуск nginx..." systemctl enable nginx systemctl start nginx # Проверка статуса sleep 2 if systemctl is-active --quiet nginx; then echo "✅ Nginx запущен успешно" else echo "❌ Ошибка запуска nginx" systemctl status nginx exit 1 fi # Проверка MY Network сервиса echo "🔍 Проверка MY Network сервиса..." if pgrep -f "python3 app/main.py" > /dev/null; then echo "✅ MY Network сервис работает" else echo "⚠️ MY Network сервис не запущен, запускаем..." cd /home/service/my-uploader-bot sudo -u service ./run_my_network.sh sleep 3 fi # Финальная проверка echo "🎯 Финальная проверка..." echo "" # Проверка HTTP -> HTTPS redirect echo "📡 Проверка HTTP redirect..." HTTP_RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" http://$DOMAIN/ || echo "000") if [[ "$HTTP_RESPONSE" == "301" ]]; then echo "✅ HTTP -> HTTPS redirect работает" else echo "⚠️ HTTP redirect: $HTTP_RESPONSE" fi # Проверка HTTPS echo "🔒 Проверка HTTPS..." HTTPS_RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" https://$DOMAIN/api/my/health || echo "000") if [[ "$HTTPS_RESPONSE" == "200" ]]; then echo "✅ HTTPS работает" else echo "❌ HTTPS не работает: $HTTPS_RESPONSE" fi # Проверка SSL сертификата echo "🔐 Проверка SSL сертификата..." SSL_INFO=$(echo | openssl s_client -servername $DOMAIN -connect $DOMAIN:443 2>/dev/null | openssl x509 -noout -dates 2>/dev/null || echo "SSL check failed") if [[ "$SSL_INFO" != "SSL check failed" ]]; then echo "✅ SSL сертификат валиден" echo "$SSL_INFO" else echo "⚠️ Не удалось проверить SSL сертификат" fi echo "" echo "🎉 MY Network Bootstrap Node с SSL настроен!" echo "============================================" echo "" echo "🌐 Доступ:" echo " https://$DOMAIN" echo " https://$DOMAIN/api/my/health" echo " https://$DOMAIN/api/my/bootstrap/config" echo " https://$DOMAIN/api/my/monitor/" echo "" echo "🔒 Безопасность:" echo " ✅ SSL/TLS сертификат от Let's Encrypt" echo " ✅ HTTP -> HTTPS redirect" echo " ✅ Security headers" echo " ✅ Rate limiting" echo " ✅ Firewall (UFW)" echo "" echo "🔄 Автообновление:" echo " ✅ SSL сертификаты (cron)" echo " ✅ MY Network сервис (cron)" echo "" echo "📊 Мониторинг:" echo " systemctl status nginx" echo " systemctl status my-network" echo " tail -f /var/log/nginx/access.log" echo " tail -f /var/log/nginx/error.log" echo "" echo "🎯 MY Network Bootstrap Node полностью готов!"