#!/bin/bash # MY Network Bootstrap Node Deployment Script # Домен: my-public-node-3.projscale.dev # Сервер: 2.58.65.188 # Только порт 443 наружу через nginx proxy set -e echo "🚀 MY Network Bootstrap Node Deployment" echo "=======================================" echo "Домен: my-public-node-3.projscale.dev" echo "Сервер: 2.58.65.188" echo "Режим: Bootstrap Node (Primary)" echo "" # Проверка прав root if [[ $EUID -ne 0 ]]; then echo "❌ Этот скрипт должен запускаться от root" echo "Используйте: sudo bash deploy_bootstrap_node.sh" exit 1 fi DOMAIN="my-public-node-3.projscale.dev" EMAIL="admin@projscale.dev" NODE_TYPE="bootstrap" echo "📋 Конфигурация Bootstrap узла:" echo " Домен: $DOMAIN" echo " Email: $EMAIL" echo " Тип: $NODE_TYPE" echo " Внешний порт: 443 (HTTPS только)" echo " Внутренний порт: 15100" echo "" # Обновление системы echo "🔄 Обновление системы..." apt update && apt upgrade -y # Установка пакетов echo "📦 Установка необходимых пакетов..." apt install -y \ docker.io \ docker-compose \ git \ curl \ wget \ unzip \ python3 \ python3-pip \ python3-venv \ nginx \ certbot \ python3-certbot-nginx \ ufw \ fail2ban \ htop \ tree \ nano \ jq # Настройка Docker echo "🐳 Настройка Docker..." systemctl enable docker systemctl start docker usermod -aG docker service # Создание структуры проекта echo "📁 Создание структуры проекта..." PROJECT_DIR="/opt/my-network" mkdir -p $PROJECT_DIR cd $PROJECT_DIR # Создание директорий mkdir -p /opt/storage /opt/logs chmod 755 /opt/storage /opt/logs chown service:service /opt/storage /opt/logs # Клонирование проекта (тут будет запрос git pull) echo "📥 Настройка проекта..." echo "ТРЕБУЕТСЯ: Выполните команду git clone или скопируйте проект в $PROJECT_DIR/my-uploader-bot/" echo "После этого продолжите выполнение скрипта" read -p "Нажмите Enter когда проект будет готов..." cd my-uploader-bot # Создание конфигурации echo "📝 Создание конфигурации bootstrap узла..." cat > .env << EOF # MY Network Bootstrap Node Configuration NODE_ID=bootstrap-node-$(date +%s) NODE_TYPE=bootstrap NODE_PORT=15100 DOMAIN=$DOMAIN EMAIL=$EMAIL # Network Configuration IS_BOOTSTRAP=true BOOTSTRAP_NODES=[] MAX_PEERS=50 SYNC_INTERVAL=300 # Database DB_HOST=localhost DB_PORT=3306 DB_NAME=my_network_bootstrap DB_USER=my_network_user DB_PASSWORD=$(openssl rand -base64 32) # Redis REDIS_HOST=localhost REDIS_PORT=6379 REDIS_PASSWORD=$(openssl rand -base64 32) # Security SECRET_KEY=$(openssl rand -base64 64) JWT_SECRET=$(openssl rand -base64 32) # Storage STORAGE_PATH=/opt/storage LOG_PATH=/opt/logs # API Settings API_RATE_LIMIT=100 MONITOR_RATE_LIMIT=10 ENABLE_PUBLIC_API=true EOF # Создание bootstrap.json конфигурации echo "🌐 Создание bootstrap конфигурации..." cat > bootstrap.json << EOF { "version": "2.0", "network_id": "my-network-main", "bootstrap_nodes": [ { "id": "bootstrap-node-primary", "host": "$DOMAIN", "port": 443, "ssl": true, "public": true, "region": "eu-central", "capacity": "high", "services": ["api", "sync", "monitor", "storage"] } ], "network_config": { "protocol_version": "2.0", "sync_interval": 300, "max_peers": 50, "chunk_size": 1048576, "compression": true, "encryption": true }, "api_endpoints": { "health": "/api/my/health", "node_info": "/api/my/node/info", "peers": "/api/my/node/peers", "sync": "/api/my/sync/status", "monitor": "/api/my/monitor/", "bootstrap": "/api/my/bootstrap/config" } } EOF # Установка Python зависимостей echo "🐍 Установка Python зависимостей..." python3 -m venv venv source venv/bin/activate pip install --upgrade pip pip install -r requirements_new.txt # Настройка базы данных echo "🗄️ Запуск Docker сервисов..." docker-compose -f docker-compose.new.yml up -d # Ожидание запуска БД echo "⏳ Ожидание запуска базы данных..." sleep 30 # Создание systemd сервиса echo "⚙️ Создание systemd сервиса..." cat > /etc/systemd/system/my-network-bootstrap.service << EOF [Unit] Description=MY Network Bootstrap Node After=network.target docker.service Requires=docker.service [Service] Type=simple User=service Group=service WorkingDirectory=$PROJECT_DIR/my-uploader-bot Environment=PATH=$PROJECT_DIR/my-uploader-bot/venv/bin ExecStart=$PROJECT_DIR/my-uploader-bot/venv/bin/python app/main.py Restart=always RestartSec=10 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target EOF # Настройка Nginx для Cloudflare echo "🌐 Настройка Nginx для Cloudflare..." cat > /etc/nginx/sites-available/my-network-bootstrap << EOF # MY Network Bootstrap Node - Cloudflare Compatible server { listen 80; server_name $DOMAIN; return 301 https://\$server_name\$request_uri; } server { listen 443 ssl http2; server_name $DOMAIN; # SSL Configuration для Cloudflare ssl_certificate /etc/letsencrypt/live/$DOMAIN/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/$DOMAIN/privkey.pem; # Cloudflare IP ranges set_real_ip_from 173.245.48.0/20; set_real_ip_from 103.21.244.0/22; set_real_ip_from 103.22.200.0/22; set_real_ip_from 103.31.4.0/22; set_real_ip_from 141.101.64.0/18; set_real_ip_from 108.162.192.0/18; set_real_ip_from 190.93.240.0/20; set_real_ip_from 188.114.96.0/20; set_real_ip_from 197.234.240.0/22; set_real_ip_from 198.41.128.0/17; set_real_ip_from 162.158.0.0/15; set_real_ip_from 104.16.0.0/13; set_real_ip_from 104.24.0.0/14; set_real_ip_from 172.64.0.0/13; set_real_ip_from 131.0.72.0/22; real_ip_header CF-Connecting-IP; # Security headers add_header X-Frame-Options DENY; add_header X-Content-Type-Options nosniff; add_header X-XSS-Protection "1; mode=block"; add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; add_header Referrer-Policy "strict-origin-when-cross-origin"; # Bootstrap Node specific headers add_header X-MY-Network-Node-Type "bootstrap"; add_header X-MY-Network-Version "2.0"; server_tokens off; # Rate limiting для bootstrap узла limit_req_zone \$binary_remote_addr zone=bootstrap_api:10m rate=100r/s; limit_req_zone \$binary_remote_addr zone=bootstrap_monitor:10m rate=10r/s; limit_req_zone \$binary_remote_addr zone=bootstrap_sync:10m rate=50r/s; # Bootstrap configuration endpoint (публичный) location /api/my/bootstrap/ { limit_req zone=bootstrap_api burst=50 nodelay; proxy_pass http://127.0.0.1:15100; 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-MY-Network-Bootstrap "true"; # CORS для bootstrap API add_header Access-Control-Allow-Origin "*"; add_header Access-Control-Allow-Methods "GET, POST, OPTIONS"; add_header Access-Control-Allow-Headers "Content-Type, Authorization"; } # Health check endpoint (публичный) location /api/my/health { limit_req zone=bootstrap_api burst=20 nodelay; proxy_pass http://127.0.0.1:15100; 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; add_header Access-Control-Allow-Origin "*"; } # Node info (публичный для discovery) location /api/my/node/info { limit_req zone=bootstrap_api burst=30 nodelay; proxy_pass http://127.0.0.1:15100; 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; add_header Access-Control-Allow-Origin "*"; } # Sync endpoints (для других узлов) location /api/my/sync/ { limit_req zone=bootstrap_sync burst=100 nodelay; proxy_pass http://127.0.0.1:15100; 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 60s; proxy_send_timeout 300s; proxy_read_timeout 300s; } # Main API location /api/my/ { limit_req zone=bootstrap_api burst=200 nodelay; proxy_pass http://127.0.0.1:15100; 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_http_version 1.1; proxy_set_header Upgrade \$http_upgrade; proxy_set_header Connection "upgrade"; proxy_connect_timeout 60s; proxy_send_timeout 60s; proxy_read_timeout 60s; } # Monitoring interface (защищенный) location /api/my/monitor { limit_req zone=bootstrap_monitor burst=10 nodelay; # Разрешить только определенным IP (настроить по необходимости) allow 127.0.0.1; allow ::1; # allow YOUR_ADMIN_IP; deny all; proxy_pass http://127.0.0.1:15100; 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 location /static/ { alias $PROJECT_DIR/my-uploader-bot/static/; expires 30d; add_header Cache-Control "public, immutable"; } # Блокировка чувствительных путей location ~ /\.(?!well-known) { deny all; } location ~ ^/(config|\.env|requirements|docker-compose) { deny all; } # Root redirect to monitor location = / { return 301 /api/my/monitor/; } } EOF # Активация nginx конфигурации ln -sf /etc/nginx/sites-available/my-network-bootstrap /etc/nginx/sites-enabled/ rm -f /etc/nginx/sites-enabled/default # Проверка nginx конфигурации nginx -t # Получение SSL сертификата echo "🔐 Получение SSL сертификата..." certbot --nginx -d $DOMAIN --email $EMAIL --agree-tos --non-interactive --redirect # Настройка firewall (ТОЛЬКО порт 443!) echo "🔥 Настройка firewall (только порт 443)..." ufw --force reset ufw default deny incoming ufw default allow outgoing # SSH порт (узнаем текущий) SSH_PORT=$(ss -tlnp | grep sshd | grep -o ':[0-9]*' | head -1 | cut -d: -f2) if [[ -n "$SSH_PORT" ]]; then echo "🔑 Разрешение SSH на порту $SSH_PORT..." ufw allow $SSH_PORT/tcp comment 'SSH' fi # ТОЛЬКО HTTP и HTTPS для Cloudflare ufw allow 80/tcp comment 'HTTP for Cloudflare' ufw allow 443/tcp comment 'HTTPS for Cloudflare' # Блокируем прямой доступ к приложению ufw deny 15100 comment 'Block direct app access' ufw --force enable # Настройка fail2ban echo "🚫 Настройка fail2ban..." apt install -y fail2ban cat > /etc/fail2ban/jail.local << EOF [DEFAULT] bantime = 3600 findtime = 600 maxretry = 5 [sshd] enabled = true port = $SSH_PORT filter = sshd logpath = /var/log/auth.log [nginx-http-auth] enabled = true filter = nginx-http-auth logpath = /var/log/nginx/error.log [nginx-limit-req] enabled = true filter = nginx-limit-req logpath = /var/log/nginx/error.log maxretry = 10 EOF systemctl enable fail2ban systemctl start fail2ban # Запуск сервисов echo "🚀 Запуск сервисов..." systemctl daemon-reload systemctl enable my-network-bootstrap systemctl start my-network-bootstrap systemctl enable nginx systemctl start nginx # Создание мониторинг скрипта echo "📊 Настройка мониторинга..." cat > /opt/bootstrap-monitor.sh << 'EOF' #!/bin/bash LOG_FILE="/opt/logs/bootstrap-monitor.log" DATE=$(date '+%Y-%m-%d %H:%M:%S') # Check services BOOTSTRAP_STATUS=$(systemctl is-active my-network-bootstrap) NGINX_STATUS=$(systemctl is-active nginx) DOCKER_STATUS=$(systemctl is-active docker) # Check API API_STATUS=$(curl -s -o /dev/null -w "%{http_code}" https://my-public-node-3.projscale.dev/api/my/health || echo "FAIL") # Check disk space DISK_USAGE=$(df -h /opt | awk 'NR==2 {print $5}' | sed 's/%//') # Log status echo "[$DATE] Bootstrap: $BOOTSTRAP_STATUS, Nginx: $NGINX_STATUS, Docker: $DOCKER_STATUS, API: $API_STATUS, Disk: ${DISK_USAGE}%" >> $LOG_FILE # Alert if critical if [[ "$BOOTSTRAP_STATUS" != "active" || "$NGINX_STATUS" != "active" || "$DOCKER_STATUS" != "active" || "$API_STATUS" != "200" ]]; then echo "[$DATE] ALERT: Bootstrap node has critical issues!" >> $LOG_FILE fi EOF chmod +x /opt/bootstrap-monitor.sh # Добавить в cron (crontab -l 2>/dev/null; echo "*/2 * * * * /opt/bootstrap-monitor.sh") | crontab - # Настройка автообновления SSL (crontab -l 2>/dev/null; echo "0 12 * * * /usr/bin/certbot renew --quiet") | crontab - # Финальная проверка echo "🔍 Финальная проверка bootstrap узла..." sleep 10 echo "📊 Статус сервисов:" systemctl status my-network-bootstrap --no-pager -l systemctl status nginx --no-pager -l systemctl status docker --no-pager -l echo "🔥 Статус firewall:" ufw status numbered echo "🌐 Проверка API:" curl -s https://$DOMAIN/api/my/health || echo "API недоступен" echo "🔐 SSL сертификаты:" certbot certificates # Сохранение конфигурации cat > /opt/bootstrap-node-config.txt << EOF MY Network Bootstrap Node - Конфигурация ======================================= Домен: $DOMAIN Тип: Bootstrap Node (Primary) Внешний порт: 443 (HTTPS only) Внутренний порт: 15100 Cloudflare: Enabled Статус сервисов: systemctl status my-network-bootstrap nginx docker fail2ban Логи: journalctl -u my-network-bootstrap -f tail -f /opt/logs/bootstrap-monitor.log API Endpoints: https://$DOMAIN/api/my/health https://$DOMAIN/api/my/node/info https://$DOMAIN/api/my/bootstrap/config https://$DOMAIN/api/my/monitor/ (restricted) Конфигурационные файлы: $PROJECT_DIR/my-uploader-bot/.env $PROJECT_DIR/my-uploader-bot/bootstrap.json EOF echo "" echo "✅ MY Network Bootstrap Node развернут!" echo "=======================================" echo "🌐 Домен: https://$DOMAIN" echo "🔐 SSL: Активен" echo "🔥 Firewall: Только порт 443" echo "🌍 Cloudflare: Совместимость включена" echo "📊 Мониторинг: Каждые 2 минуты" echo "" echo "🔍 Проверка работы:" echo " curl https://$DOMAIN/api/my/health" echo " curl https://$DOMAIN/api/my/node/info" echo " curl https://$DOMAIN/api/my/bootstrap/config" echo "" echo "📚 Конфигурация: /opt/bootstrap-node-config.txt" echo "" echo "🎯 Bootstrap узел готов к работе!"