Skip to main content

Architecture, Safety, and Basic Commands

Two machines, two responsibilities​

[LOCAL: WSL2] [REMOTE: VPS]
Initiates SSH Runs sshd
Stores the user private key Stores authorized_keys
Tests public and Tailscale addresses Configures the system, UFW, and Docker
Do not apply server changes here Must not depend on implicit local state

Label command blocks in your operations notes so you can tell where each command belongs. Check hostname, whoami, and the IP address before trusting the prompt; a window title alone is not enough.

The stages of an SSH connection​

When you run ssh user@host from WSL2, the connection must pass at least these checks in order:

  1. The local machine can route packets to the destination address.
  2. The destination firewall allows traffic to TCP 22.
  3. sshd is listening and responding.
  4. The SSH host key matches what the client expects.
  5. The server accepts the user's public key, and the client can sign with the matching private key.
  6. The Linux user is allowed to start a shell.

A successful ping therefore proves only that part of the network path works; it does not prove that SSH will work. An old SSH session that remains open does not prove that the firewall allows new connections either.

For a website or API, the request lifecycle provides the corresponding checks for DNS, connection establishment, TLS, and HTTP.

Read-only identity checks​

[LOCAL: WSL2]
whoami
hostname
uname -a
command -v ssh
ssh -V
ssh-keygen -lf "$LOCAL_SSH_PUBLIC_KEY"
[REMOTE: VPS]
whoami
id
hostnamectl
cat /etc/os-release
uname -a
nproc
free -h
df -h /
ip -brief addr
ip route
systemctl --failed --no-pager

These commands identify the current user and machine, the operating system, available resources, network interfaces, and any services that have failed. Continue only when the specifications match the provider’s console.

How to plan a change​

  1. Inspect the current state: the tool, file, rule, or user may already exist.
  2. Define the desired state: for example, “only tailscale0 can reach port 22,” rather than “run this command.”
  3. Plan the verification: what will demonstrate success, and which access path will remain if the change fails?
  4. Apply small changes: add the replacement path before removing the old one.
  5. Retest with a fresh client session: connection tracking and caches can make a broken setup appear to work.

An operation is idempotent if repeating it does not create duplicate configuration. mkdir -p, checking before adding a rule, and using a dedicated configuration snippet are easier to maintain than blindly overwriting an entire file.

Hostname, time zone, and packages​

[REMOTE: VPS]
sudo hostnamectl set-hostname infra-01
sudo timedatectl set-timezone America/Toronto
sudo apt update
sudo apt-get -s dist-upgrade
# Review proposed removals and service changes before the real upgrade.
sudo apt full-upgrade
sudo apt install -y git curl ca-certificates jq ufw
  • apt update refreshes the index of available versions; it does not install upgrades.
  • The apt-get manual documents -s as a simulation and explains that dist-upgrade can remove packages to resolve dependencies. Inspect the simulation first, then run apt full-upgrade and read the actual installation/removal summary before confirming.
  • Do not add -y or force noninteractive configuration for this first manual upgrade. The plan may change between simulation and execution, so keep the confirmation prompt.
  • Check /var/run/reboot-required afterward. If it exists, a new kernel or core component needs a reboot to take full effect.

Ubuntu's phased updates roll ordinary updates out to machines in stages. A package deferred by phasing has not failed to install; security updates do not use this phased rollout. Understand the reason; do not bypass the release policy just to clear every pending-update message.

When to stop​

  • The machine’s identity, specifications, system version, or IP address clearly differ from what you expect.
  • Continuing would require printing or otherwise exposing a private key, password, or token.
  • The package manager proposes removing critical system packages.
  • A fresh SSH connection fails verification.
  • The meaning of a firewall rule is unclear.
  • The disk or existing infrastructure conflicts with the plan.

Stopping is not a failure: it protects a recoverable state, which matters more than finishing a checklist. On a remote machine, the most costly mistake is often a command that “succeeds” and leaves you unable to reconnect.

Explore connectionsOpen network