Add setup-remote.sh script and publish it via getbin.xyz CI
This commit is contained in:
@@ -96,7 +96,19 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Publish template
|
||||
env:
|
||||
SOS_WRITE_TOKEN: ${{ secrets.SOS_WRITE_TOKEN }}
|
||||
run: |
|
||||
if [ "$GITHUB_REF" = "refs/heads/main" ]; then
|
||||
SOS_WRITE_TOKEN=${{ secrets.SOS_WRITE_TOKEN }} ~/.local/bin/dropshell publish --all ./
|
||||
~/.local/bin/dropshell publish --all ./
|
||||
fi
|
||||
|
||||
- name: Publish setup script to getbin.xyz
|
||||
env:
|
||||
SOS_WRITE_TOKEN: ${{ secrets.SOS_WRITE_TOKEN }}
|
||||
run: |
|
||||
if [ "$GITHUB_REF" = "refs/heads/main" ]; then
|
||||
curl -L -s -o /tmp/sos "https://getbin.xyz/sos:latest"
|
||||
chmod +x /tmp/sos
|
||||
/tmp/sos upload "getbin.xyz" "./setup-remote.sh" "infmap-setup:latest"
|
||||
fi
|
||||
|
||||
36
README.md
36
README.md
@@ -13,9 +13,10 @@ A Dropshell template that provides a web dashboard showing the status of your se
|
||||
- **Network**: all interfaces with IPv4/IPv6, MAC, state, speed, driver
|
||||
- **Routing**: default gateway and interface
|
||||
- **DNS**: configured nameservers
|
||||
- **Temperatures**: CPU/chipset temps via lm-sensors or thermal zones
|
||||
- **Tailscale**: IP and hostname (if installed)
|
||||
|
||||
All information is gathered without root access using `/sys/class/dmi/id/`, `lscpu`, `/proc/meminfo`, `lspci`, `ip addr`, etc.
|
||||
All information is gathered without root access using `/sys/class/dmi/id/`, `lscpu`, `/proc/meminfo`, `lspci`, `ip addr`, `sensors`, etc.
|
||||
|
||||
## Architecture
|
||||
|
||||
@@ -50,13 +51,13 @@ Edit `infrastructure.conf` to define your servers:
|
||||
|
||||
```
|
||||
Production
|
||||
root@prod-web-01 https://web01.example.com
|
||||
root@prod-db-01
|
||||
deploy@prod-app-01 https://app01.example.com:8080
|
||||
infmap@prod-web-01 https://web01.example.com
|
||||
infmap@prod-db-01
|
||||
infmap@prod-app-01 https://app01.example.com:8080
|
||||
|
||||
Development
|
||||
deploy@dev-01
|
||||
deploy@dev-02
|
||||
infmap@dev-01
|
||||
infmap@dev-02
|
||||
```
|
||||
|
||||
- Group names are freeform labels (no indentation)
|
||||
@@ -64,7 +65,28 @@ Development
|
||||
- An optional URL after the host adds a clickable link on the dashboard
|
||||
- Lines starting with `#` are comments
|
||||
|
||||
### 3. Install
|
||||
### 3. Setup remote servers
|
||||
|
||||
Run the setup script on each server you want to monitor. It creates a locked-down `infmap` user, installs your public key with SSH restrictions, and installs dependencies (lm-sensors, pciutils, etc.):
|
||||
|
||||
```bash
|
||||
curl -fsSL https://getbin.xyz/infmap-setup | bash
|
||||
```
|
||||
|
||||
To use a custom public key URL instead of the default (`https://getbin.xyz/infmap-pub`):
|
||||
|
||||
```bash
|
||||
curl -fsSL https://getbin.xyz/infmap-setup | bash -s https://example.com/my-key.pub
|
||||
```
|
||||
|
||||
The script:
|
||||
- Creates an `infmap` user with no password (locked)
|
||||
- Installs the SSH key restricted to `bash -s` only (no shell, no forwarding)
|
||||
- Disables password auth for the user via sshd Match block
|
||||
- Installs lm-sensors, pciutils, iproute2 for full data collection
|
||||
- Supports Debian/Ubuntu, Alpine, and OpenWrt
|
||||
|
||||
### 4. Install
|
||||
|
||||
```bash
|
||||
dropshell install <server> <service-name>
|
||||
|
||||
212
setup-remote.sh
Executable file
212
setup-remote.sh
Executable file
@@ -0,0 +1,212 @@
|
||||
#!/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
|
||||
|
||||
# --- 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" ;;
|
||||
*) 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"
|
||||
;;
|
||||
*)
|
||||
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 lm-sensors pciutils iproute2 util-linux >/dev/null
|
||||
# Auto-detect sensor modules
|
||||
sensors-detect --auto >/dev/null 2>&1 || true
|
||||
;;
|
||||
alpine)
|
||||
apk update --quiet
|
||||
apk add --quiet lm-sensors pciutils iproute2 util-linux bash
|
||||
# Auto-detect sensor modules
|
||||
sensors-detect --auto >/dev/null 2>&1 || true
|
||||
;;
|
||||
openwrt)
|
||||
opkg update >/dev/null 2>&1
|
||||
# Best-effort - not all packages exist on all architectures
|
||||
opkg install lm-sensors pciutils ip-full coreutils-stat 2>/dev/null || true
|
||||
;;
|
||||
*)
|
||||
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; do
|
||||
getent group "$group" &>/dev/null && usermod -aG "$group" "$USERNAME" 2>/dev/null || true
|
||||
done
|
||||
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"
|
||||
echo ""
|
||||
echo "Add to your infrastructure.conf:"
|
||||
echo " ${USERNAME}@$(hostname)"
|
||||
Reference in New Issue
Block a user