Setting Up SSH

Before a machine joins the network – a new node in the Proxmox cluster, a Raspberry Pi, whatever – it gets the same treatment. Install OpenSSH, add a key, disable password login, and only then does it get anything interesting to run.

Installing the client and server#

Ubuntu ships neither by default. The client matters even on a workstation that only ever connects out:

sudo apt install openssh-client

The server is what turns a box into something you can reach:

sudo apt install openssh-server

Key-based authentication is the whole point#

A password is a secret you type; a key is a secret you never transmit at all. The server holds the public half, and proving you have the private half doesn’t require sending it anywhere an attacker on the wire could catch it.

Generate one with the ed25519 algorithm – shorter than RSA and cheaper to compute, with no accuracy trade-off at current key sizes:

ssh-keygen -t ed25519

Then copy the public half to the target machine:

ssh-copy-id username@target_machine

If you place a key by hand instead of using ssh-copy-id, the permissions on authorized_keys have to be tightened yourself, or sshd will refuse to trust the file:

chmod go-w .ssh/authorized_keys

Turning passwords off#

Generating a key doesn’t buy anything on its own – the server still takes a password if one’s offered until you tell it not to. That’s the actual hardening step:

PasswordAuthentication no

This goes in /etc/ssh/sshd_config, or in its own file under /etc/ssh/sshd_config.d/. Either works, but not equivalently: OpenSSH takes the first value it finds for a given directive, and the sshd_config.d/ snippets are read before the main file. A setting in a snippet wins over the same setting further down in sshd_config, which matters the day you’re confused about why an edit isn’t taking effect.

Confirm the key actually logs in – in a second terminal, without closing the first – before this line goes live. There’s no password fallback to save the session once it’s set, and a mistyped key path locks out the only way in.

Editing safely: validate before you restart#

sshd_config is not a file to get wrong at 11pm. Back it up before the first edit:

sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.original
sudo chmod a-w /etc/ssh/sshd_config.original

Then, after any change, check the syntax before the running daemon ever sees it:

sudo sshd -t

sshd -t parses the config and exits without touching the live session – a broken directive shows up as an error message, not a dropped connection. Only once that’s clean:

sudo systemctl restart ssh.service

A small extra: hiding the version banner#

By default, the server announces its OS and OpenSSH version to anything that connects, before authentication happens at all. Suppressing it is one line, alongside PasswordAuthentication no:

DebianBanner no

Worth being honest about what this buys: it’s not a real barrier, since the exact version is usually still fingerprintable from how the protocol negotiates. What it removes is the free, zero-effort reconnaissance – an automated scanner sweeping for a known-vulnerable version string gets nothing to match on without doing more work first.

Sources#