174 lines
5.4 KiB
Bash
Executable File
174 lines
5.4 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# NX9-WG Live Test - Preflight Only
|
|
# This script performs a safe, non-destructive preflight for Phase 5 LIVE verification.
|
|
# It MUST NOT perform any kernel/network mutations unless LIVE is exactly 1.
|
|
|
|
set -Eeuo pipefail
|
|
|
|
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
LIVE="${LIVE:-0}"
|
|
BIN="${BIN:-$ROOT/target/release/nx9-wg}"
|
|
|
|
# Default TEST_ROOT under /tmp if not provided
|
|
if [[ -z "${TEST_ROOT:-}" ]]; then
|
|
TEST_ROOT="/tmp/nx9-wg-live-test.$(date +%s).$$"
|
|
fi
|
|
|
|
# Resolve absolute path and forbid dangerous locations
|
|
real_test_root=$(realpath -m "$TEST_ROOT")
|
|
forbidden=("/" "/etc" "/var" "/var/lib" "/home" "/root" "$ROOT")
|
|
for f in "${forbidden[@]}"; do
|
|
if [[ "$f" == "/" ]]; then
|
|
if [[ "$real_test_root" == "/" ]]; then
|
|
echo "ERROR: TEST_ROOT $real_test_root is forbidden (matches /)." >&2
|
|
exit 1
|
|
fi
|
|
else
|
|
if [[ "$real_test_root" == "$f" || "$real_test_root" == "$f/"* ]]; then
|
|
echo "ERROR: TEST_ROOT $real_test_root is forbidden (matches $f)." >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
done
|
|
|
|
BASELINE_DIR="$real_test_root/baseline"
|
|
mkdir -p "$BASELINE_DIR"
|
|
|
|
KEEP_TEST_ROOT=1
|
|
|
|
cleanup() {
|
|
rc=$?
|
|
echo
|
|
echo "================================================================"
|
|
echo " NX9-WG LIVE preflight finished (LIVE=$LIVE)"
|
|
echo "================================================================"
|
|
echo " BASELINE DIRECTORY: $BASELINE_DIR"
|
|
echo " TEST_ROOT: $real_test_root"
|
|
echo " EXIT CODE: $rc"
|
|
echo
|
|
if [[ "$KEEP_TEST_ROOT" -eq 1 ]]; then
|
|
echo "Preserving TEST_ROOT for inspection: $real_test_root"
|
|
else
|
|
echo "Removing TEST_ROOT..."
|
|
rm -rf "$real_test_root"
|
|
fi
|
|
exit "$rc"
|
|
}
|
|
|
|
trap cleanup EXIT INT TERM
|
|
|
|
# Safety: never perform mutations unless LIVE==1
|
|
require_live_for_mutation() {
|
|
if [[ "$LIVE" != "1" ]]; then
|
|
echo "ERROR: Mutating operation requires LIVE=1. Current LIVE=$LIVE" >&2
|
|
exit 2
|
|
fi
|
|
}
|
|
|
|
# Helper to run a command and save output
|
|
run_and_save() {
|
|
local label="$1"
|
|
shift
|
|
local out_file="$BASELINE_DIR/$label"
|
|
echo "--- Running: $*" >"$out_file"
|
|
if ! "$@" >>"$out_file" 2>&1; then
|
|
echo "--- Command exit non-zero: $?" >>"$out_file"
|
|
fi
|
|
}
|
|
|
|
# Validate binary (be resilient: if release binary missing, fall back to debug, or mark as unavailable)
|
|
if [[ ! -x "$BIN" ]]; then
|
|
alt_debug="$ROOT/target/debug/nx9-wg"
|
|
if [[ -x "$alt_debug" ]]; then
|
|
BIN="$alt_debug"
|
|
echo "Note: release binary missing; falling back to debug binary at $BIN"
|
|
else
|
|
echo "Warning: nx9-wg binary not found at $BIN or $alt_debug; application-level checks will be skipped." >&2
|
|
BIN=""
|
|
fi
|
|
fi
|
|
|
|
echo "Preflight mode: LIVE=$LIVE"
|
|
echo "Baseline directory: $BASELINE_DIR"
|
|
|
|
# Collect host info
|
|
run_and_save "uname.txt" uname -a
|
|
run_and_save "identity.txt" id
|
|
run_and_save "hostname.txt" hostname
|
|
run_and_save "architecture.txt" uname -m
|
|
|
|
# Networking baseline
|
|
run_and_save "ip-link.txt" ip link
|
|
run_and_save "ip-addr.txt" ip addr
|
|
run_and_save "ip-route.txt" ip route
|
|
run_and_save "ip6-route.txt" ip -6 route || true
|
|
|
|
# WireGuard and sockets
|
|
run_and_save "wg-show.txt" wg show || echo "wg not present or no permission" >"$BASELINE_DIR/wg-show.txt"
|
|
run_and_save "ss-lun.txt" ss -lun || true
|
|
|
|
# Forwarding and nft
|
|
run_and_save "ipv4-forwarding.txt" sysctl net.ipv4.ip_forward || true
|
|
run_and_save "ipv6-forwarding.txt" sysctl net.ipv6.conf.all.forwarding || true
|
|
run_and_save "nft-ruleset.txt" nft list ruleset || echo "nft not present or no permission" >"$BASELINE_DIR/nft-ruleset.txt"
|
|
|
|
# Application-level checks (non-destructive)
|
|
run_and_save "nx9-version.txt" "$BIN" version --format json || "$BIN" version >"$BASELINE_DIR/nx9-version.txt" 2>&1
|
|
run_and_save "nx9-system-info.txt" "$BIN" system info --format json || true
|
|
run_and_save "nx9-system-health.txt" "$BIN" system health --format json || true
|
|
|
|
# Diagnostics: capture JSON where possible
|
|
if "$BIN" diagnostics all --format json >"$BASELINE_DIR/nx9-diagnostics.json" 2>"$BASELINE_DIR/nx9-diagnostics.err"; then
|
|
echo "Diagnostics collected" >"$BASELINE_DIR/nx9-diagnostics.status"
|
|
else
|
|
echo "Diagnostics non-fatal failure (check nx9-diagnostics.err)" >"$BASELINE_DIR/nx9-diagnostics.status"
|
|
fi
|
|
|
|
# Metadata JSON
|
|
metadata_file="$BASELINE_DIR/metadata.json"
|
|
cat >"$metadata_file" <<EOF
|
|
{
|
|
"timestamp": "$(date --iso-8601=seconds)",
|
|
"hostname": "$(hostname)",
|
|
"kernel": "$(uname -r)",
|
|
"architecture": "$(uname -m)",
|
|
"nx9_wg_version": $(jq -n --rawfile v "$BASELINE_DIR/nx9-version.txt" '$v' 2>/dev/null || echo 'null'),
|
|
"LIVE": "$LIVE",
|
|
"TEST_ROOT": "$real_test_root"
|
|
}
|
|
EOF
|
|
|
|
# Safety validation summary
|
|
echo
|
|
echo "PRE-FLIGHT SAFETY VALIDATION"
|
|
echo "- LIVE default is: $LIVE"
|
|
if [[ "$LIVE" != "1" ]]; then
|
|
echo "- Mutation mode disabled (safe). No kernel/network mutations will be performed by this run."
|
|
fi
|
|
|
|
# Detect existing WireGuard interfaces (list names)
|
|
if command -v wg >/dev/null 2>&1; then
|
|
wg show interfaces 2>/dev/null | tee "$BASELINE_DIR/wg-interfaces.txt" || true
|
|
else
|
|
ip -o link | grep -E 'wg|wireguard' || true
|
|
fi
|
|
|
|
# Print preflight summary to stdout
|
|
cat <<EOF
|
|
|
|
PREFLIGHT SUMMARY
|
|
-----------------
|
|
BASELINE DIRECTORY: $BASELINE_DIR
|
|
NX9-WG BINARY: $BIN
|
|
LIVE: $LIVE
|
|
|
|
Collected baseline files:
|
|
$(ls -1 "$BASELINE_DIR")
|
|
|
|
To proceed with Phase 5 LIVE tests, re-run this script with LIVE=1 and confirm operator preconditions outside this script.
|
|
|
|
EOF
|
|
|
|
# End of preflight: do not perform any mutations
|
|
exit 0
|