Files
infmap/setup-remote.sh
j db5cbf99e1
All checks were successful
Build-Publish / build (linux/amd64) (push) Successful in 16s
Build-Publish / build (linux/arm64) (push) Successful in 38s
Build-Publish / create-manifest (push) Successful in 2s
Build-Publish / publish-template (push) Successful in 16s
Add GPU utilization monitoring (NVIDIA/Intel) and dropshell service discovery
2026-03-18 22:34:46 +13:00

259 lines
8.2 KiB
Bash
Executable File

#!/bin/bash
# Setup a remote server for infmap monitoring.
# Run as root: curl -fsSL <url>/setup-remote.sh | bash -s <public-key-url>
#
# What this does:
# 1. Creates a locked-down 'infmap' user (no password, no login shell abuse)
# 2. Downloads your public key and installs it with SSH restrictions
# 3. Disables password auth for the infmap user
# 4. Installs lm-sensors, pciutils, iproute2, util-linux for full gather coverage
set -euo pipefail
BUILD_DATE="__BUILD_DATE__"
echo "infmap setup-remote (built: ${BUILD_DATE})"
# --- Args ---
KEY_URL="${1:-https://getbin.xyz/infmap-pub}"
# --- Must be root ---
if [ "$(id -u)" -ne 0 ]; then
echo "Error: must run as root"
exit 1
fi
# --- Detect OS ---
detect_os() {
if [ -f /etc/os-release ]; then
. /etc/os-release
case "$ID" in
debian|ubuntu|raspbian) echo "debian" ;;
alpine) echo "alpine" ;;
openwrt) echo "openwrt" ;;
unraid-os|slackware) echo "unraid" ;;
*) echo "unknown" ;;
esac
elif [ -f /etc/openwrt_release ]; then
echo "openwrt"
else
echo "unknown"
fi
}
OS=$(detect_os)
echo "Detected OS: $OS"
# --- Create user ---
USERNAME="infmap"
create_user() {
if id "$USERNAME" &>/dev/null; then
echo "User '$USERNAME' already exists"
else
case "$OS" in
debian)
adduser --system --group --shell /bin/bash --home "/home/$USERNAME" "$USERNAME"
;;
alpine)
adduser -D -s /bin/bash -h "/home/$USERNAME" "$USERNAME" 2>/dev/null || \
adduser -D -s /bin/sh -h "/home/$USERNAME" "$USERNAME"
;;
openwrt)
# OpenWrt uses busybox adduser
grep -q "^$USERNAME:" /etc/passwd || \
echo "$USERNAME:x:1000:1000:infmap:/home/$USERNAME:/bin/ash" >> /etc/passwd
mkdir -p "/home/$USERNAME"
chown "$USERNAME" "/home/$USERNAME"
;;
unraid)
useradd -m -s /bin/bash "$USERNAME" 2>/dev/null || true
;;
*)
useradd --system --create-home --shell /bin/bash "$USERNAME" 2>/dev/null || \
adduser --system --group --shell /bin/bash --home "/home/$USERNAME" "$USERNAME"
;;
esac
echo "Created user '$USERNAME'"
fi
# Lock password - prevents password login, key auth still works
case "$OS" in
openwrt)
sed -i "s|^$USERNAME:[^:]*:|$USERNAME:*:|" /etc/passwd
;;
*)
passwd -l "$USERNAME" 2>/dev/null || usermod -L "$USERNAME" 2>/dev/null || true
;;
esac
}
create_user
# --- Download and install public key ---
HOMEDIR=$(eval echo "~$USERNAME")
SSH_DIR="$HOMEDIR/.ssh"
AUTH_KEYS="$SSH_DIR/authorized_keys"
mkdir -p "$SSH_DIR"
chmod 700 "$SSH_DIR"
echo "Downloading public key from $KEY_URL ..."
PUBKEY=$(curl -fsSL "$KEY_URL") || { echo "Error: failed to download key from $KEY_URL"; exit 1; }
# Validate it looks like an SSH public key
if ! echo "$PUBKEY" | grep -qE '^(ssh-(ed25519|rsa)|ecdsa-sha2)'; then
echo "Error: downloaded content doesn't look like an SSH public key"
echo "Got: $(echo "$PUBKEY" | head -c 80)"
exit 1
fi
# Restrict: only allow bash -s (stdin script execution), no forwarding/pty
RESTRICTED_KEY="command=\"/bin/bash -s\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty $PUBKEY"
# Replace any existing infmap key or append
if [ -f "$AUTH_KEYS" ]; then
# Remove old entries for this key (match on key data)
KEY_DATA=$(echo "$PUBKEY" | awk '{print $2}')
grep -v "$KEY_DATA" "$AUTH_KEYS" > "$AUTH_KEYS.tmp" 2>/dev/null || true
mv "$AUTH_KEYS.tmp" "$AUTH_KEYS"
fi
echo "$RESTRICTED_KEY" >> "$AUTH_KEYS"
chmod 600 "$AUTH_KEYS"
chown -R "$USERNAME" "$SSH_DIR"
# If the OS uses a group, fix group ownership
GID=$(id -g "$USERNAME" 2>/dev/null) && chgrp -R "$GID" "$SSH_DIR" 2>/dev/null || true
echo "Public key installed with restrictions"
# --- Ensure key-only SSH for this user ---
SSHD_CONFIG="/etc/ssh/sshd_config"
if [ -f "$SSHD_CONFIG" ]; then
MATCH_BLOCK="Match User $USERNAME
PasswordAuthentication no
KbdInteractiveAuthentication no"
if grep -q "Match User $USERNAME" "$SSHD_CONFIG"; then
echo "SSH Match block for '$USERNAME' already exists"
else
printf '\n%s\n' "$MATCH_BLOCK" >> "$SSHD_CONFIG"
echo "Added SSH Match block: key-only auth for '$USERNAME'"
fi
# Reload sshd
if command -v systemctl &>/dev/null; then
systemctl reload sshd 2>/dev/null || systemctl reload ssh 2>/dev/null || true
elif command -v service &>/dev/null; then
service sshd reload 2>/dev/null || service ssh reload 2>/dev/null || true
elif [ -f /etc/init.d/sshd ]; then
/etc/init.d/sshd reload 2>/dev/null || true
fi
echo "sshd reloaded"
elif [ "$OS" = "openwrt" ] && [ -f /etc/config/dropbear ]; then
echo "Note: OpenWrt uses dropbear. Password auth is controlled via /etc/config/dropbear"
echo " Ensure 'option PasswordAuth off' or rely on the locked password."
fi
# --- Install dependencies ---
install_packages() {
echo "Installing dependencies..."
case "$OS" in
debian)
export DEBIAN_FRONTEND=noninteractive
apt-get update -qq
apt-get install -y -qq sudo lm-sensors pciutils iproute2 util-linux intel-gpu-tools >/dev/null 2>&1 || \
apt-get install -y -qq sudo lm-sensors pciutils iproute2 util-linux >/dev/null
# Auto-detect sensor modules
sensors-detect --auto </dev/null >/dev/null 2>&1 || true
;;
alpine)
apk update --quiet
apk add --quiet sudo lm-sensors pciutils iproute2 util-linux bash intel-gpu-tools 2>/dev/null || \
apk add --quiet sudo lm-sensors pciutils iproute2 util-linux bash
# Auto-detect sensor modules
sensors-detect --auto </dev/null >/dev/null 2>&1 || true
;;
openwrt)
opkg update >/dev/null 2>&1
# Best-effort - not all packages exist on all architectures
opkg install sudo lm-sensors pciutils ip-full coreutils-stat 2>/dev/null || true
;;
unraid)
# Unraid ships with most tools pre-installed
echo "Unraid detected - tools are pre-installed"
;;
*)
echo "Warning: unknown OS, skipping package install"
echo "Manually install: lm-sensors pciutils iproute2 util-linux"
return
;;
esac
echo "Dependencies installed"
}
install_packages
# --- Grant read access to hardware info ---
# Some sensor/DMI files need group access
if [ "$OS" != "openwrt" ]; then
# Add infmap to common hardware-access groups if they exist
for group in i2c sensors docker; do
getent group "$group" &>/dev/null && usermod -aG "$group" "$USERNAME" 2>/dev/null || true
done
fi
# --- Sudoers for container/VM commands ---
SUDOERS_FILE="/etc/sudoers.d/infmap"
SUDO_CMDS=""
# Detect which hypervisor tools are present (check common sbin paths too)
for cmd in pct qm lxc virsh docker intel_gpu_top; do
cmd_path=$(command -v "$cmd" 2>/dev/null || true)
# Also check sbin paths not always in PATH
if [ -z "$cmd_path" ]; then
for p in /usr/sbin/$cmd /usr/local/sbin/$cmd /sbin/$cmd; do
if [ -x "$p" ]; then
cmd_path="$p"
break
fi
done
fi
if [ -n "$cmd_path" ]; then
SUDO_CMDS="${SUDO_CMDS}${USERNAME} ALL=(root) NOPASSWD: ${cmd_path}\n"
fi
done
if [ -n "$SUDO_CMDS" ]; then
printf "%b" "$SUDO_CMDS" > "$SUDOERS_FILE"
chmod 440 "$SUDOERS_FILE"
echo "Sudoers rules added for container/VM commands"
else
echo "No hypervisor tools found, skipping sudoers"
fi
# --- Summary ---
echo ""
echo "=== Setup complete ==="
echo " User: $USERNAME"
echo " Home: $HOMEDIR"
echo " Auth: key-only (password disabled)"
echo " SSH key: restricted to 'bash -s' (no shell, no forwarding)"
echo " Packages: lm-sensors, pciutils, iproute2"
if [ -n "$SUDO_CMDS" ]; then
echo " Sudo: container/VM commands (pct, qm, lxc, virsh)"
fi
echo ""
echo "Add to your infrastructure.conf:"
echo " $(hostname)"