diff --git a/scripts/install_native.sh b/scripts/install_native.sh index fabed31..57e9384 100755 --- a/scripts/install_native.sh +++ b/scripts/install_native.sh @@ -24,6 +24,7 @@ SKIP_BUILD=false DOMAIN="" EMAIL="" SKIP_SSL=false +USE_EXISTING_MONITORING=false while [[ $# -gt 0 ]]; do case $1 in @@ -47,6 +48,14 @@ while [[ $# -gt 0 ]]; do SKIP_SSL=true shift ;; + --use-existing-monitoring) + USE_EXISTING_MONITORING=true + shift + ;; + --non-interactive) + INTERACTIVE=false + shift + ;; --help) echo "Usage: $0 [OPTIONS]" echo "" @@ -54,8 +63,10 @@ while [[ $# -gt 0 ]]; do echo " --with-monitoring Install Prometheus, Grafana, and AlertManager" echo " --skip-build Skip building the application (use existing binary)" echo " --domain DOMAIN Domain name for SSL certificate (e.g., gateway.example.com)" - echo " --email EMAIL Email for Let's Encrypt certificate notifications" + echo " --email EMAIL Email for Let's Encrypt certificate notifications (required for SSL)" echo " --skip-ssl Skip SSL/HTTPS setup (HTTP only)" + echo " --use-existing-monitoring Don't install Prometheus/Grafana (use existing stack)" + echo " --non-interactive Skip all prompts (use command line flags only)" echo " --help Show this help message" echo "" echo "Example:" @@ -70,8 +81,67 @@ while [[ $# -gt 0 ]]; do esac done +# Check for INTERACTIVE variable (add if not exists) +if [ -z "${INTERACTIVE+x}" ]; then + INTERACTIVE=true +fi + +# Interactive setup for monitoring if not specified +if [ "$INTERACTIVE" = true ] && [ "$ENABLE_MONITORING" = false ] && [ "$USE_EXISTING_MONITORING" = false ]; then + echo "" + echo "🔍 Monitoring Setup" + echo "===================" + echo "Do you have an existing Prometheus/Grafana monitoring stack? (y/N)" + read -r HAS_EXISTING + + if [ "${HAS_EXISTING,,}" = "y" ] || [ "${HAS_EXISTING,,}" = "yes" ]; then + USE_EXISTING_MONITORING=true + echo "✅ Will configure for existing monitoring stack" + else + echo "Would you like to install a new Prometheus/Grafana monitoring stack? (Y/n)" + read -r INSTALL_NEW + if [ "${INSTALL_NEW,,}" != "n" ] && [ "${INSTALL_NEW,,}" != "no" ]; then + ENABLE_MONITORING=true + echo "✅ Will install new monitoring stack" + else + echo "✅ Will skip monitoring installation" + fi + fi +fi + +# Interactive domain setup if not specified +if [ "$INTERACTIVE" = true ] && [ -z "$DOMAIN" ] && [ "$SKIP_SSL" = false ]; then + echo "" + echo "🔐 SSL/Domain Setup" + echo "==================" + echo "Do you want to configure SSL/HTTPS with a domain name? (Y/n)" + read -r SETUP_SSL + + if [ "${SETUP_SSL,,}" != "n" ] && [ "${SETUP_SSL,,}" != "no" ]; then + echo "Enter your domain name (e.g., gateway.example.com):" + read -r DOMAIN + + if [ -n "$DOMAIN" ]; then + echo "Enter your email for SSL certificate notifications:" + read -r EMAIL + + if [ -z "$EMAIL" ]; then + echo "⚠️ Email is required for SSL certificates. Skipping SSL setup." + DOMAIN="" + SKIP_SSL=true + fi + else + SKIP_SSL=true + fi + else + SKIP_SSL=true + fi +fi + +echo "" echo "Configuration:" echo " Monitoring: $ENABLE_MONITORING" +echo " Use existing monitoring: $USE_EXISTING_MONITORING" echo " Skip build: $SKIP_BUILD" echo " Domain: ${DOMAIN:-'Not set (HTTP only)'}" echo " Email: ${EMAIL:-'Not set'}" @@ -91,6 +161,8 @@ apt-get install -y \ nginx \ certbot \ python3-certbot-nginx \ + fail2ban \ + ufw \ logrotate \ curl \ jq \ @@ -138,7 +210,13 @@ fi # Step 3: Setup systemd service echo "⚙️ Setting up systemd service..." -./scripts/setup_systemd.sh $([ "$ENABLE_MONITORING" = true ] && echo "--with-monitoring") +MONITORING_FLAG="" +if [ "$ENABLE_MONITORING" = true ] && [ "$USE_EXISTING_MONITORING" = false ]; then + MONITORING_FLAG="--with-monitoring" +elif [ "$USE_EXISTING_MONITORING" = true ]; then + MONITORING_FLAG="--use-existing-monitoring" +fi +./scripts/setup_systemd.sh $MONITORING_FLAG # Step 4: Configure Redis echo "🔧 Optimizing Redis configuration..." @@ -308,34 +386,179 @@ else fi fi -# Step 8: Configure firewall -echo "🔒 Configuring firewall..." +# Step 8: Configure comprehensive firewall +echo "🔒 Configuring comprehensive firewall..." if command -v ufw &> /dev/null; then - # Allow SSH - ufw allow ssh + # Reset UFW to defaults + echo "Resetting UFW to defaults..." + ufw --force reset - # Allow HTTP/HTTPS - ufw allow 80/tcp - ufw allow 443/tcp + # Set default policies + ufw default deny incoming + ufw default allow outgoing - # Allow monitoring ports (only from localhost) + # Allow SSH with rate limiting + ufw limit ssh/tcp comment "SSH with rate limiting" + + # Allow HTTP/HTTPS with rate limiting + ufw limit 80/tcp comment "HTTP with rate limiting" + ufw limit 443/tcp comment "HTTPS with rate limiting" + + # Configure monitoring ports based on setup if [ "$ENABLE_MONITORING" = true ]; then - ufw allow from 127.0.0.1 to any port 9090 # Prometheus - ufw allow from 127.0.0.1 to any port 3000 # Grafana - ufw allow from 127.0.0.1 to any port 9100 # Node Exporter + # New monitoring stack - localhost only + ufw allow from 127.0.0.1 to any port 9090 comment "Prometheus (localhost)" + ufw allow from 127.0.0.1 to any port 3000 comment "Grafana (localhost)" + ufw allow from 127.0.0.1 to any port 9100 comment "Node Exporter (localhost)" + echo "📊 Monitoring ports configured for localhost access only" + elif [ "$USE_EXISTING_MONITORING" = true ]; then + # Existing monitoring stack - allow external access + ufw allow 9090/tcp comment "Prometheus for existing monitoring" + ufw allow 3000/tcp comment "Grafana for existing monitoring" + ufw allow 9100/tcp comment "Node Exporter for existing monitoring" + ufw allow 9877/tcp comment "Gateway metrics for existing monitoring" + echo "📊 Monitoring ports opened for external monitoring server" fi - # Enable firewall (only if not already enabled) - if ! ufw status | grep -q "Status: active"; then - echo "y" | ufw enable - fi + # Allow Redis only from localhost (security) + ufw allow from 127.0.0.1 to any port 6379 comment "Redis (localhost only)" - echo "✅ Firewall configured" + # Block common attack vectors + ufw deny 23/tcp comment "Block Telnet" + ufw deny 135/tcp comment "Block RPC" + ufw deny 445/tcp comment "Block SMB" + ufw deny 1433/tcp comment "Block MSSQL" + ufw deny 3389/tcp comment "Block RDP" + + # Enable logging for security monitoring + ufw logging medium + + # Enable UFW + echo "Enabling UFW firewall..." + ufw --force enable + + # Show final status + echo "📋 Firewall Status:" + ufw status numbered + + echo "✅ Comprehensive firewall configured" else - echo "⚠️ UFW not available, skipping firewall configuration" + echo "❌ UFW not available, firewall configuration failed" + echo "Please install ufw: apt-get install -y ufw" + exit 1 fi -# Step 9: Create maintenance scripts +# Step 9: Configure fail2ban +echo "🛡️ Configuring fail2ban..." + +# Configure fail2ban for nginx and SSH protection +cat > /etc/fail2ban/jail.local << 'EOF' +[DEFAULT] +# Ban hosts for 1 hour (3600 seconds) +bantime = 3600 + +# A host is banned if it has generated "maxretry" during the last "findtime" seconds +findtime = 600 +maxretry = 5 + +# Email settings (optional) +# destemail = your@email.com +# sendername = Fail2Ban +# action = %(action_mwl)s + +[sshd] +enabled = true +port = ssh +logpath = /var/log/auth.log +bantime = 3600 +maxretry = 3 + +[nginx-http-auth] +enabled = true +port = http,https +logpath = /var/log/nginx/error.log +bantime = 3600 +maxretry = 6 + +[nginx-noscript] +enabled = true +port = http,https +logpath = /var/log/nginx/access.log +bantime = 3600 +maxretry = 6 + +[nginx-badbots] +enabled = true +port = http,https +logpath = /var/log/nginx/access.log +bantime = 86400 +maxretry = 2 + +[nginx-noproxy] +enabled = true +port = http,https +logpath = /var/log/nginx/access.log +bantime = 3600 +maxretry = 2 + +[nginx-limit-req] +enabled = true +port = http,https +logpath = /var/log/nginx/error.log +bantime = 3600 +maxretry = 10 +EOF + +# Create custom filter for torrent gateway specific attacks +cat > /etc/fail2ban/filter.d/torrent-gateway.conf << 'EOF' +[Definition] +# Fail regex for torrent gateway API abuse +failregex = ^ .* "(?:GET|POST) /api/.* HTTP/.*" 429 .*$ + ^ .* "(?:GET|POST) /api/upload.* HTTP/.*" 413 .*$ + ^ .* ".*" 4[0-9][0-9] .*$ + +# Ignore successful requests +ignoreregex = ^ .* "(?:GET|POST) .* HTTP/.*" 2[0-9][0-9] .*$ +EOF + +# Add torrent gateway jail +cat >> /etc/fail2ban/jail.local << 'EOF' + +[torrent-gateway] +enabled = true +port = http,https +logpath = /var/log/nginx/access.log +filter = torrent-gateway +bantime = 1800 +maxretry = 15 +EOF + +# Configure fail2ban to work with UFW +cat > /etc/fail2ban/action.d/ufw.conf << 'EOF' +[Definition] +actionstart = +actionstop = +actioncheck = +actionban = ufw insert 1 deny from to any comment "fail2ban " +actionunban = ufw --force delete deny from to any +EOF + +# Update fail2ban to use UFW action +sed -i 's/banaction = iptables-multiport/banaction = ufw/' /etc/fail2ban/jail.local + +# Enable and start fail2ban +systemctl enable fail2ban +systemctl restart fail2ban + +# Wait a moment for fail2ban to start +sleep 3 + +echo "📋 Fail2ban Status:" +fail2ban-client status + +echo "✅ Fail2ban configured with nginx and SSH protection" + +# Step 10: Create maintenance scripts echo "🛠️ Creating maintenance scripts..." # Create backup cron job @@ -438,6 +661,10 @@ if [ $? -eq 0 ]; then if [ "$ENABLE_MONITORING" = true ]; then echo " Prometheus: http://localhost:9090" echo " Grafana: http://localhost:3000 (admin/admin)" + elif [ "$USE_EXISTING_MONITORING" = true ]; then + echo " Node Exporter: http://localhost:9100/metrics (for your Prometheus)" + echo " Gateway Metrics: http://localhost:9877/metrics" + echo " Via nginx: http://localhost/node-metrics" fi echo "" echo "🔧 Management Commands:" @@ -457,6 +684,11 @@ if [ $? -eq 0 ]; then echo " System logs: sudo tail -f /var/log/syslog" echo " Health: sudo /opt/torrent-gateway/scripts/health_check.sh" echo "" + echo "🛡️ Security Features Enabled:" + echo " UFW Firewall: sudo ufw status" + echo " Fail2ban: sudo fail2ban-client status" + echo " SSL Certs: sudo certbot certificates" + echo "" if [ -n "$DOMAIN" ]; then echo "🔐 SSL Certificate:" echo " Status: sudo certbot certificates" diff --git a/scripts/setup_systemd.sh b/scripts/setup_systemd.sh index c3112c8..0f68e0e 100755 --- a/scripts/setup_systemd.sh +++ b/scripts/setup_systemd.sh @@ -23,15 +23,20 @@ fi # Parse command line arguments ENABLE_MONITORING=false +USE_EXISTING_MONITORING=false while [[ $# -gt 0 ]]; do case $1 in --with-monitoring) ENABLE_MONITORING=true shift ;; + --use-existing-monitoring) + USE_EXISTING_MONITORING=true + shift + ;; *) echo "Unknown option: $1" - echo "Usage: $0 [--with-monitoring]" + echo "Usage: $0 [--with-monitoring|--use-existing-monitoring]" exit 1 ;; esac @@ -154,28 +159,48 @@ cat > /etc/logrotate.d/torrent-gateway << 'EOF' } EOF -# Create nginx configuration +# Create enhanced nginx configuration echo "🌐 Configuring nginx..." cat > /etc/nginx/sites-available/torrent-gateway << 'EOF' +# Rate limiting zones +limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s; +limit_req_zone $binary_remote_addr zone=upload:10m rate=1r/s; + +# Upstreams upstream torrent_gateway { server 127.0.0.1:9877 max_fails=3 fail_timeout=30s; keepalive 32; } +upstream prometheus { + server 127.0.0.1:9090 max_fails=3 fail_timeout=30s; +} + +upstream grafana { + server 127.0.0.1:3000 max_fails=3 fail_timeout=30s; +} + server { listen 80; server_name _; - client_max_body_size 5G; + # Large file upload support + client_max_body_size 10G; client_body_timeout 300s; + client_header_timeout 60s; proxy_request_buffering off; - # Security headers - add_header X-Content-Type-Options nosniff; - add_header X-Frame-Options DENY; - add_header X-XSS-Protection "1; mode=block"; + # Enhanced security headers + add_header X-Content-Type-Options nosniff always; + add_header X-Frame-Options SAMEORIGIN 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' 'unsafe-inline' 'unsafe-eval' data: blob:; connect-src 'self' wss: ws:;" always; + # Main application location / { + limit_req zone=api burst=20 nodelay; + proxy_pass http://torrent_gateway; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; @@ -186,19 +211,94 @@ server { proxy_set_header X-Forwarded-Proto $scheme; proxy_cache_bypass $http_upgrade; - # Timeouts for large file uploads and streaming + # Enhanced timeouts for large operations proxy_connect_timeout 60s; - proxy_send_timeout 300s; - proxy_read_timeout 300s; + proxy_send_timeout 600s; + proxy_read_timeout 600s; proxy_buffering off; } - # Health check endpoint (bypass proxy for local checks) + # Upload endpoints with stricter rate limiting + location ~ ^/api/(upload|files) { + limit_req zone=upload burst=5 nodelay; + + proxy_pass http://torrent_gateway; + 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; + + # Extended timeouts for uploads + proxy_connect_timeout 60s; + proxy_send_timeout 1800s; # 30 minutes + proxy_read_timeout 1800s; # 30 minutes + proxy_buffering off; + } + + # Prometheus endpoint (conditional) + location /prometheus/ { + auth_basic "Monitoring"; + auth_basic_user_file /etc/nginx/.htpasswd; + + proxy_pass http://prometheus/; + 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; + } + + # Grafana endpoint (conditional) + location /grafana/ { + proxy_pass http://grafana/; + 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; + + # WebSocket support for Grafana live features + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; + } + + # Health check endpoint location /health { access_log off; - return 200 "healthy\n"; - add_header Content-Type text/plain; + proxy_pass http://torrent_gateway/api/health; + proxy_set_header Host $host; } + + # Node exporter metrics (for existing monitoring) + location /node-metrics { + proxy_pass http://127.0.0.1:9100/metrics; + proxy_set_header Host $host; + access_log off; + } + + # Deny access to sensitive files + location ~ /\. { + deny all; + access_log off; + log_not_found off; + } + + # Enable gzip compression + gzip on; + gzip_vary on; + gzip_min_length 1024; + gzip_proxied any; + gzip_comp_level 6; + gzip_types + text/plain + text/css + text/xml + text/javascript + application/json + application/javascript + application/xml+rss + application/atom+xml + image/svg+xml; } EOF @@ -212,6 +312,65 @@ nginx -t # Install monitoring stack if requested if [ "$ENABLE_MONITORING" = true ]; then echo "📊 Installing monitoring stack..." +elif [ "$USE_EXISTING_MONITORING" = true ]; then + echo "📊 Configuring for existing monitoring stack..." + + # Install Node Exporter for system metrics + NODE_EXPORTER_VERSION="1.7.0" + cd /tmp + wget "https://github.com/prometheus/node_exporter/releases/download/v${NODE_EXPORTER_VERSION}/node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz" + tar -xzf "node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64.tar.gz" + + mkdir -p /opt/node_exporter + cp "node_exporter-${NODE_EXPORTER_VERSION}.linux-amd64/node_exporter" /opt/node_exporter/ + + # Create node_exporter systemd service + cat > /etc/systemd/system/node-exporter.service << 'EOF' +[Unit] +Description=Node Exporter +After=network.target + +[Service] +Type=simple +User=nobody +Group=nogroup +ExecStart=/opt/node_exporter/node_exporter --web.listen-address=:9100 +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target +EOF + + systemctl daemon-reload + systemctl enable node-exporter + systemctl start node-exporter + + echo "✅ Node Exporter configured for existing monitoring" + echo "" + echo "📋 Integration Instructions:" + echo "Add the following to your existing Prometheus configuration:" + echo "" + echo "scrape_configs:" + echo " - job_name: 'torrent-gateway-app'" + echo " static_configs:" + echo " - targets: ['$(curl -s https://api.ipify.org || echo 'YOUR_SERVER_IP'):9877']" + echo " metrics_path: '/metrics'" + echo " scrape_interval: 30s" + echo "" + echo " - job_name: 'torrent-gateway-system'" + echo " static_configs:" + echo " - targets: ['$(curl -s https://api.ipify.org || echo 'YOUR_SERVER_IP'):9100']" + echo " scrape_interval: 30s" + echo "" + echo "Monitoring endpoints available at:" + echo " - Gateway metrics: http://$(curl -s https://api.ipify.org || echo 'YOUR_SERVER_IP'):9877/metrics" + echo " - System metrics: http://$(curl -s https://api.ipify.org || echo 'YOUR_SERVER_IP'):9100/metrics" + echo " - Via nginx: http://$(curl -s https://api.ipify.org || echo 'YOUR_SERVER_IP')/node-metrics" + echo "" +fi + +if [ "$ENABLE_MONITORING" = true ]; then # Install Prometheus PROMETHEUS_VERSION="2.48.0"