Files
nx9-wg/scripts/install.sh
T

206 lines
6.1 KiB
Bash
Executable File

#!/usr/bin/env bash
# ==============================================================================
# nx9-wg Production Installer
# ==============================================================================
# Installs nx9-wg binary, systemd service, configuration template, and
# state directories with strict Linux filesystem permissions.
# ==============================================================================
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
RELEASE_ROOT="$(cd "${SCRIPT_DIR}/.." && pwd)"
# Target installation paths
BIN_DIR="/usr/local/bin"
CONF_DIR="/etc/nx9-wg"
DATA_DIR="/var/lib/nx9-wg"
BACKUP_DIR="${DATA_DIR}/backups"
LOG_DIR="/var/log/nx9-wg"
SYSTEMD_DIR="/etc/systemd/system"
DRY_RUN=0
NO_SERVICE=0
NO_INIT=0
usage() {
cat <<EOF
nx9-wg Production Installer
Usage:
sudo bash install.sh [OPTIONS]
Options:
--dry-run Validate environment and simulate installation actions
--no-service Skip systemd unit installation and service enablement
--no-init Skip initial administrator account generation
-h, --help Show this help message
EOF
exit 0
}
while [[ $# -gt 0 ]]; do
case "$1" in
--dry-run)
DRY_RUN=1
shift
;;
--no-service)
NO_SERVICE=1
shift
;;
--no-init)
NO_INIT=1
shift
;;
-h|--help)
usage
;;
*)
echo "Unknown option: $1" >&2
usage
;;
esac
done
log() {
echo -e "\033[1;34m[INFO]\033[0m $*"
}
warn() {
echo -e "\033[1;33m[WARN]\033[0m $*"
}
error() {
echo -e "\033[1;31m[ERROR]\033[0m $*" >&2
exit 1
}
run_cmd() {
if [[ "${DRY_RUN}" -eq 1 ]]; then
echo " [DRY-RUN] $*"
else
"$@"
fi
}
# 1. Privilege Verification
if [[ "${EUID}" -ne 0 && "${DRY_RUN}" -eq 0 ]]; then
error "This installer must be run as root (or via sudo)."
fi
# 2. Host Architecture & Kernel Verification
ARCH="$(uname -m)"
OS="$(uname -s)"
if [[ "${OS}" != "Linux" ]]; then
error "nx9-wg production deployment requires Linux (detected: ${OS})."
fi
log "Detected platform: ${OS} (${ARCH})"
# 3. Locate nx9-wg release binary
BIN_SOURCE=""
if [[ -f "${SCRIPT_DIR}/nx9-wg" ]]; then
BIN_SOURCE="${SCRIPT_DIR}/nx9-wg"
elif [[ -f "${RELEASE_ROOT}/nx9-wg" ]]; then
BIN_SOURCE="${RELEASE_ROOT}/nx9-wg"
elif [[ -f "${RELEASE_ROOT}/target/release/nx9-wg" ]]; then
BIN_SOURCE="${RELEASE_ROOT}/target/release/nx9-wg"
else
error "Could not find nx9-wg binary in package or target/release."
fi
log "Using binary source: ${BIN_SOURCE}"
# 4. Dependency Checks
log "Verifying runtime dependencies..."
if ! command -v ldd >/dev/null 2>&1; then
warn "ldd utility not found, skipping dynamic link check."
else
if ldd "${BIN_SOURCE}" 2>&1 | grep -q "not found"; then
warn "Missing dynamic dependencies detected in ldd check:"
ldd "${BIN_SOURCE}" | grep "not found" || true
warn "Please ensure libnftables.so.1 is installed on this system."
else
log "All dynamic linkages resolved successfully."
fi
fi
# 5. Create Filesystem Layout
log "Creating filesystem layout with secure permissions..."
run_cmd install -d -m 0750 "${CONF_DIR}"
run_cmd install -d -m 0700 "${DATA_DIR}"
run_cmd install -d -m 0700 "${BACKUP_DIR}"
run_cmd install -d -m 0750 "${LOG_DIR}"
# 6. Install Binary
log "Installing binary to ${BIN_DIR}/nx9-wg..."
run_cmd install -m 0755 "${BIN_SOURCE}" "${BIN_DIR}/nx9-wg"
# 7. Install Configuration Template
CONF_SOURCE=""
if [[ -f "${RELEASE_ROOT}/config.example.toml" ]]; then
CONF_SOURCE="${RELEASE_ROOT}/config.example.toml"
elif [[ -f "${SCRIPT_DIR}/config.example.toml" ]]; then
CONF_SOURCE="${SCRIPT_DIR}/config.example.toml"
fi
if [[ -f "${CONF_DIR}/config.toml" ]]; then
log "Existing configuration found at ${CONF_DIR}/config.toml (preserving)."
else
if [[ -n "${CONF_SOURCE}" && -f "${CONF_SOURCE}" ]]; then
log "Installing configuration template to ${CONF_DIR}/config.toml..."
run_cmd install -m 0640 "${CONF_SOURCE}" "${CONF_DIR}/config.toml"
else
warn "Configuration template config.example.toml not found, skipping."
fi
fi
# 8. Bootstrap Initial Administrator (if not already initialized)
if [[ "${NO_INIT}" -eq 0 && "${DRY_RUN}" -eq 0 ]]; then
PW_FILE="${DATA_DIR}/admin-initial-password"
log "Checking administrator account initialization..."
if "${BIN_DIR}/nx9-wg" --config "${CONF_DIR}/config.toml" --data-dir "${DATA_DIR}" admin status >/dev/null 2>&1; then
log "Administrator account already initialized in database."
else
log "Initializing administrator account with secure random credentials..."
"${BIN_DIR}/nx9-wg" --config "${CONF_DIR}/config.toml" --data-dir "${DATA_DIR}" init --generate-password --write-password-file "${PW_FILE}" || true
if [[ -f "${PW_FILE}" ]]; then
chmod 0600 "${PW_FILE}"
log "Initial administrator password written to: ${PW_FILE} (mode 0600)"
fi
fi
fi
# 9. Install systemd Service
if [[ "${NO_SERVICE}" -eq 0 && -d "${SYSTEMD_DIR}" ]]; then
SERVICE_SOURCE=""
if [[ -f "${RELEASE_ROOT}/nx9-wg.service" ]]; then
SERVICE_SOURCE="${RELEASE_ROOT}/nx9-wg.service"
elif [[ -f "${SCRIPT_DIR}/nx9-wg.service" ]]; then
SERVICE_SOURCE="${SCRIPT_DIR}/nx9-wg.service"
fi
if [[ -n "${SERVICE_SOURCE}" && -f "${SERVICE_SOURCE}" ]]; then
log "Installing systemd service unit to ${SYSTEMD_DIR}/nx9-wg.service..."
run_cmd install -m 0644 "${SERVICE_SOURCE}" "${SYSTEMD_DIR}/nx9-wg.service"
if command -v systemctl >/dev/null 2>&1 && [[ "${DRY_RUN}" -eq 0 ]]; then
log "Reloading systemd daemon..."
systemctl daemon-reload
log "Enabling and starting nx9-wg service..."
systemctl enable --now nx9-wg || warn "Could not start nx9-wg.service automatically."
fi
else
warn "nx9-wg.service unit file not found, skipping service installation."
fi
fi
log "================================================================="
log "nx9-wg installation completed successfully!"
log " Binary: ${BIN_DIR}/nx9-wg"
log " Configuration: ${CONF_DIR}/config.toml"
log " Database & Data:${DATA_DIR}/nx9-wg.db"
log " Backups: ${BACKUP_DIR}"
log "================================================================="