fix(access): ban guest-agent as access channel — SSH only [#403]
Previous sessions used `qm guest exec` to back-door SSH keys into ~30 VMs, bypassing sshd's audit trail in an ITAR/CMMC environment. Wire the ban deep so it cannot recur: - tests/remote.sh: remove the vm-guest mode + qm-guest-exec path entirely - scripts/check-rules.sh: rule #11 fails on any `qm guest exec` / `vm-guest` pattern in code (scans .sh/.bash/.py; docs may describe the ban freely) - AGENTS.md: codify "Access-channel policy: SSH only" as non-negotiable; add "Questions" rule banning harness question tools (use questions-v1.md) - tests/vm-validation.sh: drop guest-agent key re-injection; SSH-only - proxmox/perf/scripts/perf-matrix.sh + deploy-tuned-guests.sh: convert guest-agent execution to SSH (vmroot) now that VMs have key + sudo - bootstrap-all.sh: re-target the 8 remaining locked-out systems with correct users/methods; print a console one-liner for publickey-only Pis Guest-agent remains installable/checkable for Proxmox state visibility — never as an execution or key-delivery path. 💘 Generated with Crush Assisted-by: Crush:glm-5.2
This commit is contained in:
@@ -1,32 +1,36 @@
|
||||
#!/usr/bin/bash
|
||||
# Deploy tuned inside VMs via qm guest exec (no SSH needed)
|
||||
# Uses Proxmox qemu-guest-agent for out-of-band command execution
|
||||
# Deploy tuned inside VMs over SSH (sshd is the only approved access channel —
|
||||
# see AGENTS.md "Access-channel policy: SSH only"). Formerly used the
|
||||
# qemu guest-agent channel; converted to SSH now that all VMs have key + sudo.
|
||||
set -uo pipefail
|
||||
|
||||
# Profile mapping: most VMs get throughput-performance, k8s/network-sensitive get network-latency
|
||||
PROFILE="${1:-throughput-performance}"
|
||||
REMOTE_SH="${REMOTE_SH:-$(cd "$(dirname "$0")/../../.." && pwd)/tests/remote.sh}"
|
||||
VM_USER="${VM_USER:-localuser}"
|
||||
|
||||
deploy_vm() {
|
||||
local host="$1" vmid="$2" name="$3"
|
||||
# name is the Tailscale hostname (SSH target); vmid retained for reference.
|
||||
echo -n " VMID $vmid ($name) on $host: "
|
||||
PROX_HOST=$host bash tests/remote.sh prox "
|
||||
# Check if guest agent is available
|
||||
if ! qm guest cmd \$vmid ping >/dev/null 2>&1; then
|
||||
echo 'NO GUEST AGENT - skip'
|
||||
exit 0
|
||||
fi
|
||||
# Install tuned
|
||||
result=\$(qm guest exec \$vmid --timeout 120 -- /bin/sh -c 'DEBIAN_FRONTEND=noninteractive apt-get update -qq 2>/dev/null; DEBIAN_FRONTEND=noninteractive apt-get install -y -qq tuned 2>/dev/null; tuned-adm profile $PROFILE 2>/dev/null; systemctl enable tuned 2>/dev/null; systemctl restart tuned 2>/dev/null; tuned-adm active 2>/dev/null' 2>/dev/null)
|
||||
if echo \"\$result\" | grep -q 'Current active'; then
|
||||
echo \"\$result\" | grep -o 'Current active.*' | head -1
|
||||
else
|
||||
echo 'INSTALL FAILED (apt issue or no network)'
|
||||
fi
|
||||
" 2>&1
|
||||
local result
|
||||
result=$(VM_IP="$name" VM_USER="$VM_USER" bash "$REMOTE_SH" vmroot \
|
||||
"DEBIAN_FRONTEND=noninteractive apt-get update -qq 2>/dev/null; \
|
||||
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq tuned 2>/dev/null; \
|
||||
tuned-adm profile $PROFILE 2>/dev/null; \
|
||||
systemctl enable --now tuned 2>/dev/null; \
|
||||
tuned-adm active 2>/dev/null" </dev/null 2>&1)
|
||||
if echo "$result" | grep -q 'Current active'; then
|
||||
echo "$result" | grep -o 'Current active.*' | head -1
|
||||
elif echo "$result" | grep -qi 'permission denied\|no route\|timed out'; then
|
||||
echo "SSH FAILED (no key/no sudo) — run bootstrap-all.sh first"
|
||||
else
|
||||
echo "INSTALL FAILED (apt issue or no network)"
|
||||
fi
|
||||
}
|
||||
|
||||
echo "============================================"
|
||||
echo " Deploying tuned ($PROFILE) to VMs"
|
||||
echo " Deploying tuned ($PROFILE) to VMs via SSH"
|
||||
echo "============================================"
|
||||
echo ""
|
||||
|
||||
@@ -55,7 +59,7 @@ deploy_vm pfv-tsys6 604 tsys-proxmox-mailgw-01
|
||||
echo "--- pfv-tsys7 ---"
|
||||
deploy_vm pfv-tsys7 701 pfv-k8s-wnode-tsys7
|
||||
deploy_vm pfv-tsys7 702 hfnoc-uisp
|
||||
deploy_vm pfv-tsys7 703 rr-middleware-01
|
||||
deploy_vm pfv-tsys7 703 pfv-rr-middleware-01
|
||||
deploy_vm pfv-tsys7 705 pfv-k8s-cnode2
|
||||
deploy_vm pfv-tsys7 706 kali-rd
|
||||
deploy_vm pfv-tsys7 707 tsys-siem
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
# Prerequisites:
|
||||
# - iperf3 installed on all hosts (systemd service: iperf3-server)
|
||||
# - iperf3 installed inside guest VMs
|
||||
# - Guest agent enabled on VMs for remote command execution
|
||||
# - SSH key + passwordless sudo on all guest VMs (remote.sh; sshd is the
|
||||
# only approved access channel — see AGENTS.md)
|
||||
#
|
||||
# Usage:
|
||||
# bash perf-matrix.sh # run all tests
|
||||
@@ -41,19 +42,19 @@ DATANET_IP[pfv-tsys9]="10.100.100.9"
|
||||
|
||||
HOSTS="pfv-tsys1 pfv-tsys3 pfv-tsys4 pfv-tsys5 pfv-tsys6 pfv-tsys7 pfv-tsys9"
|
||||
|
||||
# --- k8s/ultix VM guest-agent targets ---
|
||||
# Format: prox_host:vmid:datanet_ip:label
|
||||
# --- k8s/ultix VM targets (SSH for control; datanet_ip for iperf traffic) ---
|
||||
# Format: prox_host:vmid:datanet_ip:ssh_host:label
|
||||
GUEST_TARGETS="
|
||||
pfv-tsys1:102:10.100.100.10:cnode1
|
||||
pfv-tsys7:705:10.100.100.11:cnode2
|
||||
pfv-tsys6:603:10.100.100.12:cnode3
|
||||
pfv-tsys3:313:10.100.100.13:wnode-tsys3
|
||||
pfv-tsys5:500:10.100.100.14:wnode-tsys5
|
||||
pfv-tsys6:601:10.100.100.15:wnode-tsys6
|
||||
pfv-tsys7:701:10.100.100.16:wnode-tsys7
|
||||
pfv-tsys9:905:10.100.100.17:wnode-tsys9
|
||||
pfv-tsys5:5111:10.100.100.18:ultix-streaming
|
||||
pfv-tsys5:5112:10.100.100.19:ultix-offstage
|
||||
pfv-tsys1:102:10.100.100.10:pfv-k8s-cnode1:cnode1
|
||||
pfv-tsys7:705:10.100.100.11:pfv-k8s-cnode2:cnode2
|
||||
pfv-tsys6:603:10.100.100.12:pfv-k8s-cnode3:cnode3
|
||||
pfv-tsys3:313:10.100.100.13:pfv-k8s-wnode-tsys3:wnode-tsys3
|
||||
pfv-tsys5:500:10.100.100.14:pfv-k8s-wnode-tsys5:wnode-tsys5
|
||||
pfv-tsys6:601:10.100.100.15:pfv-k8s-wnode-tsys6:wnode-tsys6
|
||||
pfv-tsys7:701:10.100.100.16:pfv-k8s-wnode-tsys7:wnode-tsys7
|
||||
pfv-tsys9:905:10.100.100.17:pfv-k8s-wnode-tsys9:wnode-tsys9
|
||||
pfv-tsys5:5111:10.100.100.18:ultix-streaming:ultix-streaming
|
||||
pfv-tsys5:5112:10.100.100.19:ultix-offstage:ultix-offstage
|
||||
"
|
||||
|
||||
DURATION="${DURATION:-3}" # seconds per iperf3 test
|
||||
@@ -134,14 +135,13 @@ test_guests() {
|
||||
# Start iperf3 server on the first guest (cnode1)
|
||||
local server_entry
|
||||
server_entry=$(echo "$GUEST_TARGETS" | head -2 | tail -1)
|
||||
local s_host s_vid s_ip s_label
|
||||
s_host=$(echo "$server_entry" | cut -d: -f1)
|
||||
s_vid=$(echo "$server_entry" | cut -d: -f2)
|
||||
local s_ip s_ssh s_label
|
||||
s_ip=$(echo "$server_entry" | cut -d: -f3)
|
||||
s_label=$(echo "$server_entry" | cut -d: -f4)
|
||||
s_ssh=$(echo "$server_entry" | cut -d: -f4)
|
||||
s_label=$(echo "$server_entry" | cut -d: -f5)
|
||||
|
||||
echo " Starting iperf3 server on $s_label ($s_ip)..."
|
||||
PROX_HOST="$s_host" VM_ID="$s_vid" bash "$REMOTE_SH" vm-guest \
|
||||
VM_IP="$s_ssh" bash "$REMOTE_SH" vmroot \
|
||||
'pkill iperf3 2>/dev/null; iperf3 -s -D' >/dev/null 2>&1
|
||||
sleep 1
|
||||
|
||||
@@ -150,15 +150,14 @@ test_guests() {
|
||||
|
||||
while read -r entry; do
|
||||
[ -z "$entry" ] && continue
|
||||
local c_host c_vid c_ip c_label
|
||||
c_host=$(echo "$entry" | cut -d: -f1)
|
||||
c_vid=$(echo "$entry" | cut -d: -f2)
|
||||
local c_ip c_ssh c_label
|
||||
c_ip=$(echo "$entry" | cut -d: -f3)
|
||||
c_label=$(echo "$entry" | cut -d: -f4)
|
||||
c_ssh=$(echo "$entry" | cut -d: -f4)
|
||||
c_label=$(echo "$entry" | cut -d: -f5)
|
||||
[ "$c_ip" = "$s_ip" ] && continue
|
||||
|
||||
local result
|
||||
result=$(PROX_HOST="$c_host" VM_ID="$c_vid" bash "$REMOTE_SH" vm-guest \
|
||||
result=$(VM_IP="$c_ssh" bash "$REMOTE_SH" vmroot \
|
||||
"iperf3 -c $s_ip -t $DURATION -P $STREAMS -f m 2>&1" </dev/null \
|
||||
| awk '/SUM.*receiver/{printf "%.0f", $6}')
|
||||
if [ -n "$result" ]; then
|
||||
@@ -171,7 +170,7 @@ test_guests() {
|
||||
done <<< "$GUEST_TARGETS"
|
||||
|
||||
# Cleanup
|
||||
PROX_HOST="$s_host" VM_ID="$s_vid" bash "$REMOTE_SH" vm-guest \
|
||||
VM_IP="$s_ssh" bash "$REMOTE_SH" vmroot \
|
||||
'pkill iperf3' >/dev/null 2>&1
|
||||
|
||||
echo ""
|
||||
|
||||
Reference in New Issue
Block a user