Add wireguard-ui-multi core: multi-server DB, WireGuard manager, REST API, UI, installers
Implements the from-scratch multi-server WireGuard management fork per CLAUDE.md spec: sqlite schema (servers/peers/audit_log/users), Curve25519 key generation, per-interface config rendering + wg-quick/systemd control, nftables hook scaffolding, session+CSRF-protected REST API with QR code and config download endpoints, a minimal vanilla-JS web UI, legacy wg0.conf migration, and both a native installer and a Proxmox LXC provisioning script (with auto-detected latest Debian template). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
3d6608ef80
commit
3b3ffd8ebf
Executable
+177
@@ -0,0 +1,177 @@
|
||||
#!/usr/bin/env bash
|
||||
# Runs on a Proxmox VE host. Creates a privileged LXC container prepared for
|
||||
# WireGuard (kernel module + /dev/net/tun + CAP_NET_ADMIN + nftables), copies
|
||||
# this repo into it, and runs scripts/install.sh inside the container.
|
||||
#
|
||||
# Privileged container is required: WireGuard needs CAP_NET_ADMIN and access
|
||||
# to /dev/net/tun, which unprivileged LXC containers cannot reliably get.
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat >&2 <<EOF
|
||||
Usage: $0 --vmid <id> --hostname <name> [options]
|
||||
|
||||
Required:
|
||||
--vmid <id> numeric LXC container ID (e.g. 200)
|
||||
--hostname <name> container hostname (e.g. wireguard-ui-multi)
|
||||
|
||||
Options:
|
||||
--storage <name> Proxmox storage for rootfs (default: local-lvm)
|
||||
--template <path> LXC template volid (default: auto-detect + download newest debian-* template)
|
||||
--bridge <name> network bridge (default: vmbr0)
|
||||
--ip <cidr|dhcp> static CIDR (e.g. 10.0.0.50/24) or "dhcp" (default: dhcp)
|
||||
--gw <ip> gateway IP, required if --ip is a static CIDR
|
||||
--disk <GB> rootfs size in GB (default: 4)
|
||||
--memory <MB> RAM in MB (default: 512)
|
||||
--cores <n> CPU cores (default: 1)
|
||||
--repo-src <path> path to this repo on the Proxmox host (default: script's own repo root)
|
||||
--start start the container after creation (default: created but stopped, then started to run the installer, left running)
|
||||
EOF
|
||||
exit 1
|
||||
}
|
||||
|
||||
VMID=""
|
||||
HOSTNAME=""
|
||||
STORAGE="local-lvm"
|
||||
TEMPLATE=""
|
||||
BRIDGE="vmbr0"
|
||||
IP="dhcp"
|
||||
GW=""
|
||||
DISK="4"
|
||||
MEMORY="512"
|
||||
CORES="1"
|
||||
REPO_SRC=""
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--vmid) VMID="$2"; shift 2 ;;
|
||||
--hostname) HOSTNAME="$2"; shift 2 ;;
|
||||
--storage) STORAGE="$2"; shift 2 ;;
|
||||
--template) TEMPLATE="$2"; shift 2 ;;
|
||||
--bridge) BRIDGE="$2"; shift 2 ;;
|
||||
--ip) IP="$2"; shift 2 ;;
|
||||
--gw) GW="$2"; shift 2 ;;
|
||||
--disk) DISK="$2"; shift 2 ;;
|
||||
--memory) MEMORY="$2"; shift 2 ;;
|
||||
--cores) CORES="$2"; shift 2 ;;
|
||||
--repo-src) REPO_SRC="$2"; shift 2 ;;
|
||||
-h|--help) usage ;;
|
||||
*) echo "Unknown option: $1" >&2; usage ;;
|
||||
esac
|
||||
done
|
||||
|
||||
[[ -z "$VMID" || -z "$HOSTNAME" ]] && usage
|
||||
|
||||
if [[ "$(id -u)" -ne 0 ]]; then
|
||||
echo "Must run as root on the Proxmox host." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if ! command -v pct >/dev/null 2>&1; then
|
||||
echo "pct not found - this script must run on a Proxmox VE host." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "$REPO_SRC" ]]; then
|
||||
REPO_SRC="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
fi
|
||||
|
||||
if [[ -z "$TEMPLATE" ]]; then
|
||||
echo "No --template given, looking up newest debian-* template..."
|
||||
pveam update >/dev/null
|
||||
TEMPLATE_FILE="$(pveam available --section system \
|
||||
| awk '{print $2}' \
|
||||
| grep -E '^debian-[0-9]+-standard_' \
|
||||
| sort -V \
|
||||
| tail -n1)"
|
||||
if [[ -z "$TEMPLATE_FILE" ]]; then
|
||||
echo "Could not find any debian-* template via 'pveam available'." >&2
|
||||
exit 1
|
||||
fi
|
||||
if ! pveam list "$STORAGE" | grep -q "$TEMPLATE_FILE"; then
|
||||
echo "Downloading $TEMPLATE_FILE to storage $STORAGE..."
|
||||
pveam download "$STORAGE" "$TEMPLATE_FILE"
|
||||
fi
|
||||
TEMPLATE="${STORAGE}:vztmpl/${TEMPLATE_FILE}"
|
||||
echo "Using template: $TEMPLATE"
|
||||
fi
|
||||
|
||||
NET_CONFIG="name=eth0,bridge=${BRIDGE},firewall=1"
|
||||
if [[ "$IP" == "dhcp" ]]; then
|
||||
NET_CONFIG="${NET_CONFIG},ip=dhcp"
|
||||
else
|
||||
if [[ -z "$GW" ]]; then
|
||||
echo "--gw is required when --ip is a static CIDR." >&2
|
||||
exit 1
|
||||
fi
|
||||
NET_CONFIG="${NET_CONFIG},ip=${IP},gw=${GW}"
|
||||
fi
|
||||
|
||||
echo "Creating privileged LXC $VMID ($HOSTNAME)..."
|
||||
pct create "$VMID" "$TEMPLATE" \
|
||||
--hostname "$HOSTNAME" \
|
||||
--storage "$STORAGE" \
|
||||
--rootfs "${STORAGE}:${DISK}" \
|
||||
--memory "$MEMORY" \
|
||||
--cores "$CORES" \
|
||||
--net0 "$NET_CONFIG" \
|
||||
--unprivileged 0 \
|
||||
--features "nesting=1,keyctl=1" \
|
||||
--onboot 1
|
||||
|
||||
echo "Enabling /dev/net/tun and WireGuard kernel module passthrough..."
|
||||
CONF="/etc/pve/lxc/${VMID}.conf"
|
||||
{
|
||||
echo "lxc.cgroup2.devices.allow: c 10:200 rwm"
|
||||
echo "lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file"
|
||||
} >> "$CONF"
|
||||
|
||||
echo "Starting container..."
|
||||
pct start "$VMID"
|
||||
sleep 5
|
||||
|
||||
echo "Installing base dependencies inside container (Go, git, wireguard-tools, nftables)..."
|
||||
pct exec "$VMID" -- bash -c "
|
||||
set -e
|
||||
apt-get update
|
||||
apt-get install -y wireguard-tools nftables curl ca-certificates git
|
||||
if ! command -v go >/dev/null 2>&1; then
|
||||
ARCH=\$(dpkg --print-architecture)
|
||||
curl -fsSL https://go.dev/dl/go1.22.5.linux-\${ARCH}.tar.gz -o /tmp/go.tar.gz
|
||||
tar -C /usr/local -xzf /tmp/go.tar.gz
|
||||
ln -sf /usr/local/go/bin/go /usr/local/bin/go
|
||||
rm -f /tmp/go.tar.gz
|
||||
fi
|
||||
"
|
||||
|
||||
echo "Copying repo into container..."
|
||||
TMP_TAR="$(mktemp)"
|
||||
tar -C "$REPO_SRC" -czf "$TMP_TAR" --exclude=.git .
|
||||
pct push "$VMID" "$TMP_TAR" /tmp/wireguard-ui-multi.tar.gz
|
||||
rm -f "$TMP_TAR"
|
||||
|
||||
pct exec "$VMID" -- bash -c "
|
||||
set -e
|
||||
mkdir -p /opt/wireguard-ui-multi-src
|
||||
tar -C /opt/wireguard-ui-multi-src -xzf /tmp/wireguard-ui-multi.tar.gz
|
||||
rm -f /tmp/wireguard-ui-multi.tar.gz
|
||||
"
|
||||
|
||||
echo "Running native installer inside container..."
|
||||
pct exec "$VMID" -- bash -c "
|
||||
set -e
|
||||
cd /opt/wireguard-ui-multi-src
|
||||
go build -o wireguard-ui-multi ./cmd/wireguard-ui-multi
|
||||
bash scripts/install.sh
|
||||
"
|
||||
|
||||
echo
|
||||
echo "Container $VMID ($HOSTNAME) is set up. wireguard-ui-multi is installed but not started."
|
||||
echo "To enable and start it inside the container, run:"
|
||||
echo
|
||||
echo " pct exec $VMID -- systemctl enable --now wireguard-ui-multi.service"
|
||||
echo
|
||||
echo "Then check status with:"
|
||||
echo
|
||||
echo " pct exec $VMID -- systemctl status wireguard-ui-multi.service"
|
||||
echo " pct exec $VMID -- journalctl -u wireguard-ui-multi.service -f"
|
||||
Reference in New Issue
Block a user