From e20f6cf665b6d24ba90fb61ffa9d6287f9c3e9fd Mon Sep 17 00:00:00 2001 From: Antigravity Agent Date: Sat, 3 Oct 2026 00:05:14 -0400 Subject: [PATCH] NetVM: edge provisioning script (sudoers allowlist for operator) --- README.md | 1 + bin/netvm-provision-edge.sh | 52 +++++++++++++++++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100755 bin/netvm-provision-edge.sh diff --git a/README.md b/README.md index da3ecd7..5a79d16 100644 --- a/README.md +++ b/README.md @@ -81,6 +81,7 @@ Tear down: sudo bin/netvm-node-down.sh . - bin/netvm-node-up.sh — bring up a node's egress. - bin/netvm-node-down.sh — tear a node's egress down. - bin/netvm-topology.sh — print the live topology table. +- `bin/netvm-provision-edge.sh` — prepare an edge device (sudoers allowlist, deps, /etc/netvm); run on the node, once. - NODES.md — the registry: node -> netns -> Warp identity -> egress IP. ## Verification checklist diff --git a/bin/netvm-provision-edge.sh b/bin/netvm-provision-edge.sh new file mode 100755 index 0000000..a192439 --- /dev/null +++ b/bin/netvm-provision-edge.sh @@ -0,0 +1,52 @@ +#!/usr/bin/env bash +# netvm-provision-edge.sh — prepare an edge device for operator-managed NetVM. +# Run ON the edge device as a user with sudo (interactive sudo is fine). +# Idempotent: safe to re-run. Every edge device provisioned this way looks +# identical, so the operator uses one command everywhere. +set -euo pipefail + +OPERATOR_USER="${OPERATOR_USER:-$(whoami)}" +REPO="$HOME/Projects/NetVM" +SUDOERS_FILE="/etc/sudoers.d/netvm-operator" + +echo "== NetVM edge provisioning (operator user: $OPERATOR_USER) ==" + +# 1. prerequisites (best-effort install for the common missing piece: wg) +if ! "$REPO/bin/netvm-verify.sh"; then + echo "-- installing missing packages --" + if command -v pacman >/dev/null 2>&1; then + sudo pacman -S --noconfirm --needed wireguard-tools + elif command -v apt-get >/dev/null 2>&1; then + sudo apt-get update && sudo apt-get install -y wireguard + else + echo "install wireguard-tools manually, then re-run"; exit 1 + fi + "$REPO/bin/netvm-verify.sh" +fi + +# 2. repo must be here (sync over Tailscale first on non-laptop nodes) +[ -x "$REPO/bin/netvm-node-up.sh" ] || { echo "NetVM repo not at $REPO — sync it here first"; exit 1; } + +# 3. sudoers allowlist: exact lifecycle scripts only, never blanket root +sudo tee "$SUDOERS_FILE" > /dev/null << SUDOERS +# NetVM operator lifecycle access — managed by netvm-provision-edge.sh. +# Lets the operator user bring node egress up/down and read topology. +# WireGuard configs in /etc/netvm stay root-only; these scripts never print them. +$OPERATOR_USER ALL=(root) NOPASSWD: $REPO/bin/netvm-node-up.sh *, $REPO/bin/netvm-node-down.sh *, $REPO/bin/netvm-topology.sh +SUDOERS +sudo chmod 440 "$SUDOERS_FILE" +sudo visudo -c -f "$SUDOERS_FILE" > /dev/null && echo "ok: sudoers valid" + +# 4. dir for human-placed WireGuard identities +sudo mkdir -p /etc/netvm +sudo chmod 700 /etc/netvm +echo "ok: /etc/netvm ready" + +# 5. tailnet check +tailscale status >/dev/null 2>&1 && echo "ok: tailscale up" || echo "NOTE: tailscale not up — run: tailscale up" + +echo +echo "Done. Human next step: place this node's WireGuard config at" +echo " /etc/netvm/.conf (root-owned, 0600; wgcf-generated)" +echo "Operator usage from anywhere on the tailnet:" +echo " ssh ${OPERATOR_USER}@ 'sudo -n $REPO/bin/netvm-node-up.sh '"