308 lines
9.0 KiB
Bash
308 lines
9.0 KiB
Bash
#!/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 '</head>' '<script>window.__CONFIG__ = { apiBaseUrl: "/api/v1" };</script></head>';
|
|
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!'"
|