Hook

Passwords are easy to reuse, easy to guess, and easy to steal. SSH keys replace that weak link with a stronger identity check that scales from one laptop to a whole fleet of servers.

If you administer servers, deploy code, or log in to remote machines even a few times a week, SSH keys are not a nice-to-have. They are the default sane way to do remote access.

Problem

SSH still looks simple from the outside: type a username, connect to a server, enter a password, done. The trouble starts when that password becomes the same one used elsewhere, gets shared with a teammate, or gets brute-forced by bots that scan the internet all day.

SSH keys solve a different problem than passwords. Instead of proving who you are by something you know, you prove it by something you have. The server checks whether your Public Key is allowed, and your machine proves it owns the matching Private Key.

That sounds neat until people use keys badly. Common failure modes are everywhere:

The tool is solid. The discipline around it is what usually breaks.

Why it matters

A good SSH setup changes daily work in three useful ways.

First, it reduces the blast radius of a leaked password. If a password is phished or reused, the attacker may get in from anywhere. A properly protected private key is harder to steal and easier to revoke.

Second, it makes access easier to manage. Keys can be assigned to a person, a laptop, a bot, or a CI job. That means you can remove one key without kicking everyone else out.

Third, it makes server access more auditable. If you know which Public Key belongs to which person or system, you can answer basic questions fast: who has access, where it is stored, and what to remove when someone leaves.

The same logic applies to automation. Human keys and machine keys should not be mixed casually. A bot key that lives in CI should be treated very differently from the key on your personal laptop.

How to

1. Generate a modern key pair

Use ed25519 unless you have a specific reason not to. It is fast, widely supported, and a better default than old RSA setups.

ssh-keygen -t ed25519 -C "yura@laptop"

You will be asked where to save the key. The default is usually fine:

/home/you/.ssh/id_ed25519

Add a strong Passphrase when prompted. That way, if someone copies your private key file, they still need the Passphrase to use it.

If you already have an old key and want to inspect it:

ls -la ~/.ssh
ssh-keygen -lf ~/.ssh/id_ed25519.pub

The fingerprint gives you a compact way to verify which key you are dealing with.

2. Copy the Public Key to the server

The easiest path is ssh-copy-id:

ssh-copy-id user@server.example.com

That appends your Public Key to the server’s authorized_keys file for that user.

If ssh-copy-id is not available, you can do it manually.

On your laptop:

cat ~/.ssh/id_ed25519.pub

Copy the output.

On the server, log in with your current method, then:

mkdir -p ~/.ssh
chmod 700 ~/.ssh
nano ~/.ssh/authorized_keys

Paste the Public Key on a single line, save the file, and fix permissions:

chmod 600 ~/.ssh/authorized_keys

SSH is picky about file permissions. If they are too open, authentication may fail.

After that, test a new session:

ssh user@server.example.com

If it works without asking for the server password, the key is active.

3. Use SSH agent for convenience

Typing the Passphrase for every connection gets old fast. That is what SSH Agent is for.

Start the agent:

eval "$(ssh-agent -s)"

Add your key:

ssh-add ~/.ssh/id_ed25519

Check what the agent knows:

ssh-add -l

Now your unlocked key stays in memory for the session, so repeated logins are less annoying.

On desktop Linux, this often integrates with the keyring automatically. On servers or minimal systems, you may need to start the agent manually in each shell session.

4. Make SSH easier with config

When you connect to the same host over and over, define a short alias in ~/.ssh/config.

Host prod
    HostName server.example.com
    User deploy
    IdentityFile ~/.ssh/id_ed25519
    IdentitiesOnly yes

Then connect with:

ssh prod

A few useful options:

If you manage multiple environments, keep them separate:

Host staging
    HostName staging.example.com
    User deploy
    IdentityFile ~/.ssh/id_ed25519_staging

Host backup-box
    HostName 192.0.2.50
    User root
    IdentityFile ~/.ssh/id_ed25519_backup

This reduces mistakes and makes the intent obvious.

5. Verify fingerprints before trusting a key

Never blindly accept a host key or a new server key just because the terminal told you to. Check the Key Fingerprint through a trusted channel.

If someone hands you a server fingerprint, compare it with what you see on first connect:

ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub

For your own client key, you can inspect the Public Key fingerprint:

ssh-keygen -lf ~/.ssh/id_ed25519.pub

Fingerprints matter when you rotate keys, reimage a server, or validate that the machine in front of you is really the one you meant to connect to.

6. Revoke or rotate access cleanly

If a laptop is lost, a teammate leaves, or a bot credential is compromised, do not wait.

Remove the relevant line from the server’s authorized_keys file:

nano ~/.ssh/authorized_keys

If the key is shared across several machines, remove it everywhere. Then generate a fresh key pair and redeploy access only where needed.

A safe rotation looks like this:

  1. generate a new key
  2. add the new Public Key
  3. test the new login
  4. remove the old Public Key
  5. confirm the old key no longer works

That sequence avoids lockouts.

7. Lock down the server side

SSH keys work best when password login is not the fallback forever.

On the server, edit:

sudo nano /etc/ssh/sshd_config

Useful settings often include:

PasswordAuthentication no
PubkeyAuthentication yes
PermitRootLogin no

Then reload SSH carefully:

sudo systemctl reload ssh

Do not disable password login until you have confirmed a working key-based login session. Locking yourself out of a remote server is a very avoidable hobby.

Anti-patterns

One key forever

A single key pair used for years becomes a tiny pile of risk. If it leaks, every system that trusts it is exposed. Rotate keys on a schedule that fits your environment.

No Passphrase

An unprotected private key on a laptop is too convenient for an attacker. A Passphrase adds friction for theft without adding much friction for you once SSH Agent is set up.

Mixing human and bot keys

Your personal laptop key and your deployment key should not be the same thing. When a CI job needs access, give it a separate identity and separate permissions.

Copying the Private Key to a server

That defeats the whole model. A server should store Public Keys in authorized_keys, not your secret material. If you copy the Private Key over “just for now,” you are creating a second place to lose it.

Leaving password auth on forever

Passwords can be a fallback during migration. They should not be a permanent habit on internet-facing systems. The less your server accepts passwords, the less it can be guessed.

Not documenting keys

If nobody knows which key belongs to which person or system, revocation turns into archaeology. Keep a small inventory: owner, purpose, date created, and where it is installed.

Skipping fingerprint checks

Trusting a key without checking its fingerprint is like signing a package without opening the box. It might be fine. It might also be the wrong thing entirely.

Conclusion

SSH keys are not complicated, but they reward good habits.

Generate an ed25519 key pair. Protect the Private Key with a Passphrase. Install the Public Key on the server. Use SSH Agent to avoid retyping. Add a clean SSH config so you stop remembering long hostnames. Verify fingerprints when trust matters. Remove old keys when they are no longer needed.

If you want a simple baseline, use this:

ssh-keygen -t ed25519 -C "you@laptop"
ssh-copy-id user@server
ssh user@server

Then harden the setup: enable the agent, document the key, and turn off password login once key-based access is confirmed.

Good SSH hygiene is boring in the best possible way. It keeps the doors open for you and closed for everyone else.