#!/bin/bash set -e # NexusGuard Server Installer # Installs server-core, dashboard-ui, and configures systemd + nginx # Defaults SERVER_PORT=8080 WEB_PORT=80 DB_HOST=127.0.0.1 DB_PORT=5432 DB_USER=nexusguard DB_PASSWORD=nexusguard DB_NAME=nexusguard CONF_DIR="/etc/nexusguard" CONF_FILE="$CONF_DIR/nexusguard.conf" SERVICE_NAME="nexusguard-server" NGINX_CONF="/etc/nginx/conf.d/nexusguard.conf" DASHBOARD_DIR="/usr/share/nexusguard/dashboard" BINARY_DIR="/usr/local/bin" # Colors RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' NC='\033[0m' info() { echo -e "${GREEN}[INFO]${NC} $1"; } warn() { echo -e "${YELLOW}[WARN]${NC} $1"; } error() { echo -e "${RED}[ERROR]${NC} $1"; exit 1; } usage() { cat << EOF NexusGuard Server Installer Usage: $0 [OPTIONS] Options: --server-port PORT API server port (default: 8080) --web-port PORT Nginx web port (default: 80) --db-host HOST PostgreSQL host (default: 127.0.0.1) --db-port PORT PostgreSQL port (default: 5432) --db-user USER PostgreSQL user (default: nexusguard) --db-pass PASS PostgreSQL password (default: nexusguard) --db-name NAME PostgreSQL database name (default: nexusguard) --help Show this help message Prerequisites: - nginx installed and running - PostgreSQL installed and running - Redis installed and running - WireGuard tools (will be auto-installed if missing) - Pre-built binaries in ./bin/ directory This script will: 1. Create PostgreSQL database and user 2. Copy server-core binary to /usr/local/bin/ 3. Copy dashboard dist to /usr/share/nexusguard/dashboard/ 4. Create /etc/nexusguard/nexusguard.conf 5. Run database migration 6. Create systemd service 7. Configure nginx EOF exit 0 } # Parse arguments while [[ "$#" -gt 0 ]]; do case $1 in --server-port) SERVER_PORT="$2"; shift ;; --web-port) WEB_PORT="$2"; shift ;; --db-host) DB_HOST="$2"; shift ;; --db-port) DB_PORT="$2"; shift ;; --db-user) DB_USER="$2"; shift ;; --db-pass) DB_PASSWORD="$2"; shift ;; --db-name) DB_NAME="$2"; shift ;; --help) usage ;; *) error "Unknown parameter: $1" ;; esac shift done # Check root if [ "$EUID" -ne 0 ]; then error "Please run as root" fi # Check dependencies command -v nginx >/dev/null 2>&1 || error "nginx is not installed" command -v systemctl >/dev/null 2>&1 || error "systemctl is not installed" command -v psql >/dev/null 2>&1 || error "PostgreSQL client (psql) is not installed" command -v redis-cli >/dev/null 2>&1 || error "Redis client (redis-cli) is not installed" # Check and install WireGuard if ! command -v wg >/dev/null 2>&1; then warn "WireGuard tools not found. Installing..." if command -v apt >/dev/null 2>&1; then apt update -qq && apt install -y -qq wireguard-tools elif command -v dnf >/dev/null 2>&1; then dnf install -y -q wireguard-tools elif command -v yum >/dev/null 2>&1; then yum install -y -q wireguard-tools elif command -v pacman >/dev/null 2>&1; then pacman -S --noconfirm wireguard-tools else error "Cannot auto-install WireGuard. Please install wireguard-tools manually." fi info "WireGuard tools installed: $(wg --version)" fi # Check WireGuard kernel module if ! lsmod 2>/dev/null | grep -q wireguard; then warn "WireGuard kernel module not loaded. Loading..." modprobe wireguard 2>/dev/null || warn "Could not load wireguard module (may need manual load or reboot)" fi # Check for pre-built binaries SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SERVER_BINARY="$SCRIPT_DIR/bin/server-core" DASHBOARD_DIST="$SCRIPT_DIR/apps/dashboard-ui/dist" if [ ! -f "$SERVER_BINARY" ]; then error "Server binary not found at $SERVER_BINARY. Build first: cd apps/server-core && go build -o ../../bin/server-core ." fi if [ ! -d "$DASHBOARD_DIST" ]; then error "Dashboard dist not found at $DASHBOARD_DIST. Build first: cd apps/dashboard-ui && npm run build" fi # Check PostgreSQL connection if ! psql -h "$DB_HOST" -p "$DB_PORT" -U "$DB_USER" -d postgres -c "SELECT 1" >/dev/null 2>&1; then warn "Cannot connect to PostgreSQL with current credentials. Trying with postgres user..." if ! psql -h "$DB_HOST" -p "$DB_PORT" -U postgres -d postgres -c "SELECT 1" >/dev/null 2>&1; then error "Cannot connect to PostgreSQL. Please ensure PostgreSQL is running and accessible." fi PG_SUPERUSER="postgres" else PG_SUPERUSER="$DB_USER" fi # Check Redis connection if ! redis-cli -h "${DB_HOST}" -p 6379 ping >/dev/null 2>&1; then error "Cannot connect to Redis. Please ensure Redis is running." fi info "Installing NexusGuard Server..." # Create directories info "Creating directories..." mkdir -p "$CONF_DIR" mkdir -p "$DASHBOARD_DIR" mkdir -p "$BINARY_DIR" # Setup PostgreSQL database info "Setting up PostgreSQL database..." DB_EXISTS=$(psql -h "$DB_HOST" -p "$DB_PORT" -U "$PG_SUPERUSER" -d postgres -tAc "SELECT 1 FROM pg_roles WHERE rolname='$DB_USER'" 2>/dev/null || echo "") if [ "$DB_EXISTS" != "1" ]; then info "Creating database user: $DB_USER" psql -h "$DB_HOST" -p "$DB_PORT" -U "$PG_SUPERUSER" -d postgres -c "CREATE USER $DB_USER WITH PASSWORD '$DB_PASSWORD';" >/dev/null 2>&1 || warn "User $DB_USER may already exist" fi DB_EXISTS=$(psql -h "$DB_HOST" -p "$DB_PORT" -U "$PG_SUPERUSER" -d postgres -tAc "SELECT 1 FROM pg_database WHERE datname='$DB_NAME'" 2>/dev/null || echo "") if [ "$DB_EXISTS" != "1" ]; then info "Creating database: $DB_NAME" psql -h "$DB_HOST" -p "$DB_PORT" -U "$PG_SUPERUSER" -d postgres -c "CREATE DATABASE $DB_NAME OWNER $DB_USER;" >/dev/null 2>&1 || warn "Database $DB_NAME may already exist" fi # Copy server binary info "Installing server-core binary..." cp "$SERVER_BINARY" "$BINARY_DIR/$SERVICE_NAME" chmod +x "$BINARY_DIR/$SERVICE_NAME" # Copy dashboard dist info "Installing dashboard files..." cp -r "$DASHBOARD_DIST"/* "$DASHBOARD_DIR/" # Create config file (only if not exists) if [ ! -f "$CONF_FILE" ]; then info "Creating config file with auto-generated secrets..." RANDOM_JWT=$(openssl rand -hex 32) RANDOM_SALT=$(openssl rand -hex 32) cat << EOF > "$CONF_FILE" # NexusGuard Configuration # Generated by install.sh on $(date) # Database DB_HOST=$DB_HOST DB_PORT=$DB_PORT DB_USER=$DB_USER DB_PASSWORD=$DB_PASSWORD DB_NAME=$DB_NAME # Redis REDIS_ADDR=127.0.0.1:6379 # Security (auto-generated) JWT_SECRET=$RANDOM_JWT SERVER_SALT=$RANDOM_SALT # Network NFTABLES_TABLE=nexusguard IPAM_POOL=10.8.0.0/16 # Server GIN_MODE=release PORT=$SERVER_PORT # Dashboard CORS_ALLOWED_ORIGINS=http://localhost:$WEB_PORT SHARE_LINK_TTL=24h EOF chmod 600 "$CONF_FILE" info "Config file created at $CONF_FILE" else info "Config file already exists, skipping..." fi # Run database migration info "Running database migration..." set +e "$BINARY_DIR/$SERVICE_NAME" -migrate-prod 2>&1 | tail -5 set -e info "Database migration completed." # Create systemd service info "Creating systemd service..." cat << EOF > "/etc/systemd/system/$SERVICE_NAME.service" [Unit] Description=NexusGuard SD-WAN Server After=network.target postgresql.service redis.service Wants=postgresql.service redis.service [Service] Type=simple User=root WorkingDirectory=$BINARY_DIR EnvironmentFile=$CONF_FILE ExecStart=$BINARY_DIR/$SERVICE_NAME Restart=always RestartSec=5 StandardOutput=journal StandardError=journal # Security hardening NoNewPrivileges=false ProtectSystem=false ProtectHome=false [Install] WantedBy=multi-user.target EOF # Create nginx config info "Creating nginx configuration..." cat << EOF > "$NGINX_CONF" server { listen $WEB_PORT; listen [::]:$WEB_PORT; server_name localhost; # Inject runtime config into HTML responses sub_filter '' ''; sub_filter_once on; sub_filter_types text/html; location /api/ { proxy_pass http://127.0.0.1:$SERVER_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; } location / { root $DASHBOARD_DIR; try_files \$uri \$uri/ /index.html; } error_page 500 502 503 504 /50x.html; location = /50x.html { root $DASHBOARD_DIR; } } EOF # Enable and start service info "Enabling and starting service..." systemctl daemon-reload systemctl enable "$SERVICE_NAME" systemctl start "$SERVICE_NAME" # Reload nginx info "Reloading nginx..." nginx -t && systemctl reload nginx info "Installation complete!" echo "" info "Access URL: http://localhost:$WEB_PORT" info "Config file: $CONF_FILE" info "Service status: systemctl status $SERVICE_NAME" echo "" info "Secrets were auto-generated. Edit $CONF_FILE to customize if needed." info "Restart after changes: systemctl restart $SERVICE_NAME" echo "" info "To create admin user: $BINARY_DIR/$SERVICE_NAME -create-admin -user admin -pass 'YourPassword!'"