← Back to Runbooks
Mode: Public
Runbook 00

Golden VM baseline — Ubuntu Server + SSH keys + snapshot

This runbook establishes a repeatable baseline VM for the lab: a clean Ubuntu Server install, patched to current updates, reachable via SSH using keys, with a snapshot used as the permanent rollback point.

Deterministic access (no guessing which creds work) Known-good rollback (no “what changed?” debugging) Repeatable rebuild (new VM behaves like the last one) Lab-safe defaults (nothing fragile or clever)
Private : evidence bundle guidance

Operator mode is where raw outputs and exact environment notes (hostnames, LAN IPs, screenshots, key fingerprints). Public pages stay sanitized. For true secrecy, I will keep operator pages in a private repo.

Scope (sanitized)

Examples use localhost port-forwarding (NAT mode) to avoid publishing home LAN specifics. This mirrors CI and recording-safe operation. In a private lab, the same checks apply when switching to bridged networking and a LAN IP/hostname.

Private : topology notes
# Fill with actuals
# Hypervisor: VirtualBox
# Adapter: NAT (baseline) OR Bridged (lab)
# Host NIC (example): en6 (Belkin USB-C LAN)
# Guest NIC: enp0s3
# Snapshot name: baseline-ubuntu-sshkeys

Objective

Success criteria

Private : proof checklist (copy/paste evidence)
# Capture and keep these blocks for “proof of baseline”
uname -a
lsb_release -a || cat /etc/os-release
ip -4 -br a
sudo systemctl status ssh --no-pager | sed -n '1,14p'
sudo ss -lntp | grep -E '(:22\s)'

Baseline contract (keep consistent)

VM usersut
VM hostnamesut-ubuntu (example)
SSH modelPort forward on host: 127.0.0.1:2222 → guest: :22
Snapshot namebaseline-ubuntu-sshkeys
Private : stable naming conventions
# Recommended operator convention (adjust once, then keep stable)
# VM name: sut-ubuntu (baseline-ubuntu-24.04.3-sshkeys)
# Snapshot: baseline-ubuntu-sshkeys
# SSH host alias (optional): Host ~/.ssh/config uses localhost:2222

Procedure

1) VirtualBox VM creation

Private : bridged adapter evidence (if used)
# To switch to Bridged, record adapter selection:
# VirtualBox → Network → Attached to: Bridged Adapter
# Name: (host NIC) e.g. en6: Belkin USB-C LAN
# Promiscuous Mode: Deny
# Cable Connected: checked

2) Ubuntu Server install (inside installer)

3) Confirm network address (inside VM)

ip a

Expected: interface enp0s3 shows an IP (often 10.0.2.x on NAT).

Private : capture actual IP block
ip -4 -br a
ip route

4) Ensure SSH is running (inside VM)

sudo systemctl enable --now ssh
systemctl status ssh
sudo ss -tlnp | grep ':22'

Expected: ssh.service active/running and port 22 listening.

5) Add port forwarding in VirtualBox (host UI)

VirtualBox → VM Settings → Network → Advanced → Port Forwarding

Name: ssh
Protocol: TCP
Host IP: 127.0.0.1
Host Port: 2222
Guest IP: (blank)   
Guest Port: 22
Private : proof that 2222 is bound
# Host-side proof (macOS)
  ssh -p 2222 sut@127.0.0.1


# If nothing is listening:
# - confirm the VM is running
# - re-check the VirtualBox port-forward rule

6) Verify the host is listening on 2222 (host terminal)

lsof -iTCP:2222 -sTCP:LISTEN

Expected: a VirtualBox process is listening on localhost:2222.

7) Test SSH password login (host → VM)

ssh -p 2222 sut@127.0.0.1

8) Patch baseline (inside VM)

sudo apt update
sudo apt upgrade -y
Private : prove patch state
# inside VM
sudo apt update
sudo apt upgrade -y
sudo apt autoremove -y

# optional proof
uname -r

9) Install SSH key (host → VM)

If ~/.ssh/id_ed25519 already exists on the host, reuse it. Do not overwrite.

ssh-copy-id -p 2222 sut@127.0.0.1

10) Verify passwordless SSH

ssh -p 2222 sut@127.0.0.1

Expected: login succeeds without a password prompt.

Private : key fingerprint capture
# Host key / known_hosts hygiene (host)
ssh-keygen -R '[127.0.0.1]:2222' || true
ssh -p 2222 sut@127.0.0.1

# Record fingerprint once accepted (will not publish)
# (fingerprint shown at first connect)

11) Optional: disable password authentication (after keys work)

Safety rule: keep current session open; validate changes in a separate terminal before closing anything.

sudo nano /etc/ssh/sshd_config

# Set:
# PasswordAuthentication no
# PermitRootLogin no

sudo systemctl restart ssh
Private : post-change verification
# Keep one session open.
# In a second terminal on host:
ssh -p 2222 sut@127.0.0.1

# Confirm sshd is still healthy (inside VM):
sudo systemctl status ssh --no-pager | sed -n '1,14p'

12) Snapshot baseline

Private : snapshot discipline note

Lesson: if you ever have to “wonder what changed,” you missed a snapshot. Baseline snapshots are the lab’s equivalent of “golden AMI” discipline.

Common failure modes

SSH timeout

Usually indicates the host port forward is missing, wrong, or not bound. Check: lsof -iTCP:2222 -sTCP:LISTEN and confirm the VM is running.

Connection refused

Host is reachable but nothing is listening on 2222. Confirm the port-forward rule, then reboot the VM and re-check lsof.

Permission denied

Username mismatch (sut vs another user) or key not installed. Re-run: ssh-copy-id -p 2222 sut@127.0.0.1

Confusing host vs guest terminal

VM prompt typically looks like sut@sut-ubuntu:~$. macOS host prompt is different. Run host commands on the host.

Private : rapid triage commands
# Host side
lsof -nP -iTCP:2222 -sTCP:LISTEN || true
ssh -vvv -p 2222 sut@127.0.0.1 || true

# Guest side (inside VM)
sudo systemctl status ssh --no-pager | sed -n '1,18p'
sudo ss -lntp | grep -E '(:22\s)' || true

Why this baseline matters

Back: Runbooks