LINUX TUTORIAL

SSH keys explained (and ditching passwords)

How key login works and why it beats passwords, then the real steps: generate a key, install the public half, log in with no password, hold the passphrase in the agent, and turn password login off.

What we're doing

We generate an SSH key pair and put the public half in this VM's authorized_keys. Then we log in to localhost with no password, and turn password login off so keys are the only way in. The whole demo runs against localhost (the VM to itself), so there is nothing to lock ourselves out of.

Watch the video first, then run these as we go. The key steps run as our normal user; we use sudo only at the end, to change the SSH server config.

How key login works

SSH (Secure Shell) logs us in over the network. A key comes as a pair:

  • Private key (~/.ssh/id_ed25519): the secret half. Stays on our machine, never sent anywhere.
  • Public key (~/.ssh/id_ed25519.pub): safe to share. Goes on the server in ~/.ssh/authorized_keys.

At login the server sends a challenge, our machine signs it with the private key, and the server checks the signature against the public key. No password and no secret ever crosses the network, which is why keys beat passwords (nothing to guess, brute-force, phish, or reuse).

Step 1: generate a key pair

ssh-keygen -t ed25519 -C "me@prepare-vm"   # -t = algorithm (ed25519, modern); -C = a label
# press Enter for the default path; set a passphrase or press Enter to skip
ls -l ~/.ssh                                # two files now
cat ~/.ssh/id_ed25519.pub                   # the public half (one line, safe to share)
-rw------- 1 preparesh preparesh 411 ... id_ed25519       (private, perms 600)
-rw-r--r-- 1 preparesh preparesh  97 ... id_ed25519.pub   (public)
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIH8k...2pQ me@prepare-vm

The private key must stay -rw------- (only us). The .pub is the half we put on the server.

Step 2: install the public key

mkdir -p ~/.ssh && chmod 700 ~/.ssh
cat ~/.ssh/id_ed25519.pub >> ~/.ssh/authorized_keys   # append (>>), do not overwrite
chmod 600 ~/.ssh/authorized_keys                       # ssh ignores it if perms are too open

authorized_keys is the server's list of trusted public keys. (On a real remote server we'd use ssh-copy-id me@server instead, which does this append for us and asks for our password that one last time.)

Step 3: log in with the key

ssh localhost      # first time: confirm the fingerprint with "yes"; then no password
exit               # come back to the original shell
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
preparesh@prepare-vm:~$

No password prompt, the key logged us in.

Step 4: hold the passphrase in the agent (if we set one)

eval "$(ssh-agent -s)"        # start the agent, apply its settings to this shell
ssh-add ~/.ssh/id_ed25519     # load the key (asks the passphrase once)

The SSH agent keeps the unlocked key in memory for the session, so we type the passphrase once instead of every login.

Step 5: turn password login off

echo "PasswordAuthentication no" | sudo tee /etc/ssh/sshd_config.d/00-prepare-ssh.conf
sudo sshd -t                  # test the config FIRST (catches typos before they break logins)
sudo systemctl reload ssh     # apply without dropping existing connections
# verify passwords are refused (force a password attempt, key off):
ssh -o PubkeyAuthentication=no -o PreferredAuthentications=password localhost
preparesh@localhost: Permission denied (publickey).

"Permission denied (publickey)" = the server only accepts keys now. Plain ssh localhost (with the key) still works.

Cheat sheet

ssh-keygen -t ed25519 -C "label"           # make a key pair
cat ~/.ssh/id_ed25519.pub                   # the public half (share this)
ssh-copy-id me@server                       # install our public key on a remote server
cat id_ed25519.pub >> ~/.ssh/authorized_keys ; chmod 600 ~/.ssh/authorized_keys   # or by hand
ssh localhost                               # log in with the key
eval "$(ssh-agent -s)" ; ssh-add            # hold the passphrase for the session
# keys-only:
echo "PasswordAuthentication no" | sudo tee /etc/ssh/sshd_config.d/00-prepare-ssh.conf
sudo sshd -t && sudo systemctl reload ssh

In short: a key is a pair. The private half stays on our machine and the public half goes in the server's authorized_keys; login is a signature check, so no secret crosses the network. Make the pair with ssh-keygen, install the public half, and set PasswordAuthentication no so keys are the only way in. Always run sshd -t before reloading, so a typo can't lock anyone out.

Next tutorial: hardening the SSH server, no root login, limited users, fail2ban, and reloading safely with a fallback session open.


What's next

Just hit Start and go try this out in a live environment !

Start LINUX
Spec 2 CPU / 4 GiB ·Disk 25 GiB ·Lifetime 7 days
Sign in to launch this environment
Required 1 VM · 2 CPU · 4 GB · 25 GiB disk
Available 1 VM · 1 CPU · 2 GB · 10 GiB disk
Sign in