546 lines
16 KiB
Bash
546 lines
16 KiB
Bash
#!/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 узел готов к работе!" |