uploader-bot/scripts/setup_nginx_ssl.sh

331 lines
10 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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 полностью готов!"