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.
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.
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.
# 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
ssh -p 2222 sut@127.0.0.1sudo apt update && sudo apt upgrade -ybaseline-ubuntu-sshkeys# 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)'
| VM user | sut |
| VM hostname | sut-ubuntu (example) |
| SSH model | Port forward on host: 127.0.0.1:2222 → guest: :22 |
| Snapshot name | baseline-ubuntu-sshkeys |
# 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
# 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
sut.ip a
Expected: interface enp0s3 shows an IP (often 10.0.2.x on NAT).
ip -4 -br a
ip route
sudo systemctl enable --now ssh
systemctl status ssh
sudo ss -tlnp | grep ':22'
Expected: ssh.service active/running and port 22 listening.
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
# 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
lsof -iTCP:2222 -sTCP:LISTEN
Expected: a VirtualBox process is listening on localhost:2222.
ssh -p 2222 sut@127.0.0.1
sudo apt update
sudo apt upgrade -y
# inside VM
sudo apt update
sudo apt upgrade -y
sudo apt autoremove -y
# optional proof
uname -r
If ~/.ssh/id_ed25519 already exists on the host, reuse it. Do not overwrite.
ssh-copy-id -p 2222 sut@127.0.0.1
ssh -p 2222 sut@127.0.0.1
Expected: login succeeds without a password prompt.
# 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)
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
# 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'
baseline-ubuntu-sshkeysLesson: if you ever have to “wonder what changed,” you missed a snapshot. Baseline snapshots are the lab’s equivalent of “golden AMI” discipline.
Usually indicates the host port forward is missing, wrong, or not bound. Check:
lsof -iTCP:2222 -sTCP:LISTEN and confirm the VM is running.
Host is reachable but nothing is listening on 2222. Confirm the port-forward rule, then reboot the VM and re-check lsof.
Username mismatch (sut vs another user) or key not installed. Re-run:
ssh-copy-id -p 2222 sut@127.0.0.1
VM prompt typically looks like sut@sut-ubuntu:~$. macOS host prompt is different. Run host commands on the host.
# 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
Back: Runbooks