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
Start LINUX