install script fix
Some checks are pending
CI Pipeline / Run Tests (push) Waiting to run
CI Pipeline / Lint Code (push) Waiting to run
CI Pipeline / Security Scan (push) Waiting to run
CI Pipeline / E2E Tests (push) Blocked by required conditions

This commit is contained in:
Enki 2025-08-27 12:29:14 -07:00
parent e701652589
commit fa60d908b0
2 changed files with 424 additions and 33 deletions

View File

@ -24,6 +24,7 @@ SKIP_BUILD=false
DOMAIN="" DOMAIN=""
EMAIL="" EMAIL=""
SKIP_SSL=false SKIP_SSL=false
USE_EXISTING_MONITORING=false
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case $1 in case $1 in
@ -47,6 +48,14 @@ while [[ $# -gt 0 ]]; do
SKIP_SSL=true SKIP_SSL=true
shift shift
;; ;;
--use-existing-monitoring)
USE_EXISTING_MONITORING=true
shift
;;
--non-interactive)
INTERACTIVE=false
shift
;;
--help) --help)
echo "Usage: $0 [OPTIONS]" echo "Usage: $0 [OPTIONS]"
echo "" echo ""
@ -54,8 +63,10 @@ while [[ $# -gt 0 ]]; do
echo " --with-monitoring Install Prometheus, Grafana, and AlertManager" echo " --with-monitoring Install Prometheus, Grafana, and AlertManager"
echo " --skip-build Skip building the application (use existing binary)" echo " --skip-build Skip building the application (use existing binary)"
echo " --domain DOMAIN Domain name for SSL certificate (e.g., gateway.example.com)" 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 " --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 " --help Show this help message"
echo "" echo ""
echo "Example:" echo "Example:"
@ -70,8 +81,67 @@ while [[ $# -gt 0 ]]; do
esac esac
done 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 "Configuration:"
echo " Monitoring: $ENABLE_MONITORING" echo " Monitoring: $ENABLE_MONITORING"
echo " Use existing monitoring: $USE_EXISTING_MONITORING"
echo " Skip build: $SKIP_BUILD" echo " Skip build: $SKIP_BUILD"
echo " Domain: ${DOMAIN:-'Not set (HTTP only)'}" echo " Domain: ${DOMAIN:-'Not set (HTTP only)'}"
echo " Email: ${EMAIL:-'Not set'}" echo " Email: ${EMAIL:-'Not set'}"
@ -91,6 +161,8 @@ apt-get install -y \
nginx \ nginx \
certbot \ certbot \
python3-certbot-nginx \ python3-certbot-nginx \
fail2ban \
ufw \
logrotate \ logrotate \
curl \ curl \
jq \ jq \
@ -138,7 +210,13 @@ fi
# Step 3: Setup systemd service # Step 3: Setup systemd service
echo "⚙️ Setting up 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 # Step 4: Configure Redis
echo "🔧 Optimizing Redis configuration..." echo "🔧 Optimizing Redis configuration..."
@ -308,34 +386,179 @@ else
fi fi
fi fi
# Step 8: Configure firewall # Step 8: Configure comprehensive firewall
echo "🔒 Configuring firewall..." echo "🔒 Configuring comprehensive firewall..."
if command -v ufw &> /dev/null; then if command -v ufw &> /dev/null; then
# Allow SSH # Reset UFW to defaults
ufw allow ssh echo "Resetting UFW to defaults..."
ufw --force reset
# Allow HTTP/HTTPS # Set default policies
ufw allow 80/tcp ufw default deny incoming
ufw allow 443/tcp 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 if [ "$ENABLE_MONITORING" = true ]; then
ufw allow from 127.0.0.1 to any port 9090 # Prometheus # New monitoring stack - localhost only
ufw allow from 127.0.0.1 to any port 3000 # Grafana ufw allow from 127.0.0.1 to any port 9090 comment "Prometheus (localhost)"
ufw allow from 127.0.0.1 to any port 9100 # Node Exporter 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 fi
# Enable firewall (only if not already enabled) # Allow Redis only from localhost (security)
if ! ufw status | grep -q "Status: active"; then ufw allow from 127.0.0.1 to any port 6379 comment "Redis (localhost only)"
echo "y" | ufw enable
fi
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 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 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 = ^<HOST> .* "(?:GET|POST) /api/.* HTTP/.*" 429 .*$
^<HOST> .* "(?:GET|POST) /api/upload.* HTTP/.*" 413 .*$
^<HOST> .* ".*" 4[0-9][0-9] .*$
# Ignore successful requests
ignoreregex = ^<HOST> .* "(?: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 <ip> to any comment "fail2ban <name>"
actionunban = ufw --force delete deny from <ip> 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..." echo "🛠️ Creating maintenance scripts..."
# Create backup cron job # Create backup cron job
@ -438,6 +661,10 @@ if [ $? -eq 0 ]; then
if [ "$ENABLE_MONITORING" = true ]; then if [ "$ENABLE_MONITORING" = true ]; then
echo " Prometheus: http://localhost:9090" echo " Prometheus: http://localhost:9090"
echo " Grafana: http://localhost:3000 (admin/admin)" 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 fi
echo "" echo ""
echo "🔧 Management Commands:" echo "🔧 Management Commands:"
@ -457,6 +684,11 @@ if [ $? -eq 0 ]; then
echo " System logs: sudo tail -f /var/log/syslog" echo " System logs: sudo tail -f /var/log/syslog"
echo " Health: sudo /opt/torrent-gateway/scripts/health_check.sh" echo " Health: sudo /opt/torrent-gateway/scripts/health_check.sh"
echo "" 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 if [ -n "$DOMAIN" ]; then
echo "🔐 SSL Certificate:" echo "🔐 SSL Certificate:"
echo " Status: sudo certbot certificates" echo " Status: sudo certbot certificates"

View File

@ -23,15 +23,20 @@ fi
# Parse command line arguments # Parse command line arguments
ENABLE_MONITORING=false ENABLE_MONITORING=false
USE_EXISTING_MONITORING=false
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case $1 in case $1 in
--with-monitoring) --with-monitoring)
ENABLE_MONITORING=true ENABLE_MONITORING=true
shift shift
;; ;;
--use-existing-monitoring)
USE_EXISTING_MONITORING=true
shift
;;
*) *)
echo "Unknown option: $1" echo "Unknown option: $1"
echo "Usage: $0 [--with-monitoring]" echo "Usage: $0 [--with-monitoring|--use-existing-monitoring]"
exit 1 exit 1
;; ;;
esac esac
@ -154,28 +159,48 @@ cat > /etc/logrotate.d/torrent-gateway << 'EOF'
} }
EOF EOF
# Create nginx configuration # Create enhanced nginx configuration
echo "🌐 Configuring nginx..." echo "🌐 Configuring nginx..."
cat > /etc/nginx/sites-available/torrent-gateway << 'EOF' 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 { upstream torrent_gateway {
server 127.0.0.1:9877 max_fails=3 fail_timeout=30s; server 127.0.0.1:9877 max_fails=3 fail_timeout=30s;
keepalive 32; 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 { server {
listen 80; listen 80;
server_name _; server_name _;
client_max_body_size 5G; # Large file upload support
client_max_body_size 10G;
client_body_timeout 300s; client_body_timeout 300s;
client_header_timeout 60s;
proxy_request_buffering off; proxy_request_buffering off;
# Security headers # Enhanced security headers
add_header X-Content-Type-Options nosniff; add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options DENY; add_header X-Frame-Options SAMEORIGIN always;
add_header X-XSS-Protection "1; mode=block"; 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 / { location / {
limit_req zone=api burst=20 nodelay;
proxy_pass http://torrent_gateway; proxy_pass http://torrent_gateway;
proxy_http_version 1.1; proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade; proxy_set_header Upgrade $http_upgrade;
@ -186,19 +211,94 @@ server {
proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade; proxy_cache_bypass $http_upgrade;
# Timeouts for large file uploads and streaming # Enhanced timeouts for large operations
proxy_connect_timeout 60s; proxy_connect_timeout 60s;
proxy_send_timeout 300s; proxy_send_timeout 600s;
proxy_read_timeout 300s; proxy_read_timeout 600s;
proxy_buffering off; 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 { location /health {
access_log off; access_log off;
return 200 "healthy\n"; proxy_pass http://torrent_gateway/api/health;
add_header Content-Type text/plain; 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 EOF
@ -212,6 +312,65 @@ nginx -t
# Install monitoring stack if requested # Install monitoring stack if requested
if [ "$ENABLE_MONITORING" = true ]; then if [ "$ENABLE_MONITORING" = true ]; then
echo "📊 Installing monitoring stack..." 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 # Install Prometheus
PROMETHEUS_VERSION="2.48.0" PROMETHEUS_VERSION="2.48.0"