#!/usr/bin/bash # access-matrix.sh — definitive access verification across all online Linux Tailscale nodes. # Uses the correct SSH user per system type, checks sudo where applicable. # Routes through remote.sh (the only allowed ssh path). set -u cd /home/reachableceo/projects/PFVCluster || exit 1 # Policy-excluded systems (never attempt access) EXCLUDE=':tsys-cloudron:pfv-bms:tsys-umbrel:stlpc-bizoffice:ultix-highside:' # Determine the SSH user for a given hostname. # Returns "user:sudo" where sudo is "yes" or "no". user_for() { local name="$1" case "$name" in pfv-tsys[0-9]) echo "root:no" ;; *-proxmox-datacenter) echo "root:no" ;; *-proxmox-pve) echo "root:no" ;; *-proxmox-pbs) echo "root:no" ;; *-proxmox-mailgw*) echo "root:no" ;; *-proxmox-backup*) echo "root:no" ;; stlpc-*) echo "labuser:no" ;; subopi*) echo "subodev:yes" ;; *) echo "localuser:yes" ;; esac } printf '%-32s %-16s %-12s %-8s\n' "NAME" "TS-IP" "ACCESS" "SUDO" printf '%-32s %-16s %-12s %-8s\n' "----" "-----" "------" "----" tailscale status 2>/dev/null | awk '$4=="linux" && $0 !~ /offline/ {print $2, $1}' | sort | while read -r name ip; do [ -n "$name" ] || continue case "$EXCLUDE" in *":$name:"*) printf '%-32s %-16s %-12s\n' "$name" "$ip" "EXCLUDED"; continue;; esac map=$(user_for "$name") user="${map%%:*}"; expect_sudo="${map##*:}" out=$(VM_IP="$ip" VM_USER="$user" bash tests/remote.sh vm 'echo SSHOK; id -un' &1 | tr '\n' '/') case "$out" in *SSHOK*) if [ "$expect_sudo" = "yes" ]; then sudo=$(VM_IP="$ip" VM_USER="$user" bash tests/remote.sh vm 'sudo -n true 2>/dev/null && echo SUDOOK || echo SUDONO' &1 | tr -d '\n') printf '%-32s %-16s %-12s %-8s\n' "$name" "$ip" "${user}-SSH" "${sudo:-?}" else printf '%-32s %-16s %-12s %-8s\n' "$name" "$ip" "${user}-SSH" "n/a" fi ;; *keyboard-interactive*) printf '%-32s %-16s %-12s\n' "$name" "$ip" "2FA-blocked" ;; *Connection\ refused*) printf '%-32s %-16s %-12s\n' "$name" "$ip" "NO-SSH(22)" ;; *Permission\ denied*) printf '%-32s %-16s %-12s\n' "$name" "$ip" "NO-KEY" ;; *No\ route*) printf '%-32s %-16s %-12s\n' "$name" "$ip" "UNREACHABLE" ;; *) printf '%-32s %-16s %-12s\n' "$name" "$ip" "NO-KEY" ;; esac done