Sign in
← Linux: security
12 min · easy · Lesson 1 of 5

SSH keys and authentication

How key-based login replaces passwords: the key pair, authorized_keys, ssh-agent. Why it is more secure and how to set it up.

How key-based login replaces a password: the key pair, authorized_keys, ssh-agent. Why it's more secure and how to set it up.

Why use keys if you already have a password

Logging in to a server with a password works, but it scales badly and breaks easily. A password can be brute-forced, it leaks into logs and shell history, and you end up typing it by hand or storing it in plain text in scripts. On a production server, dozens of people and automated systems (CI, Ansible, backups) connect over SSH, and a password quickly turns into a hole.

Key-based authentication solves this. You don't show up at the server with a secret that has to be handed over; you show up with proof that you hold a private key. The private key itself never leaves your machine: the server checks a signature, it never receives the key.

The key pair: private and public

An SSH key is two linked files:

The math works so that the public key can verify a signature made by the private one, but you can't reconstruct the private key from the public one. That's why publishing the public half is safe.

Create a pair:

$ ssh-keygen -t ed25519 -C "deploy@laptop"
Generating public/private ed25519 key pair.
Enter file in which to save the key (/home/user/.ssh/id_ed25519):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_ed25519
Your public key has been saved in /home/user/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:3buXJPW3ZuRNZDOU3yOrTa/Xj6WTNh60v8hlMye6u50 deploy@laptop
...

-t ed25519 picks a modern algorithm: short keys, fast, strong. RSA still works too. Without -b, ssh-keygen makes a 3072-bit RSA key, and many people take 4096 out of habit (-t rsa -b 4096). -C adds a label comment, handy later for figuring out whose key this is.

The passphrase encrypts the private key itself. If your laptop gets stolen, a key with no passphrase can be used right away. With a passphrase, the key has to be decrypted first. ssh-agent (more on it below) saves you from typing it on every connection.

authorized_keys: who the server lets in

The server lets in anyone whose public key is listed in the ~/.ssh/authorized_keys file of the target user. One line corresponds to one allowed key.

The easiest way to put your key on a server is this command:

ssh-copy-id deploy@server

It logs in to the server by password once and appends your id_ed25519.pub to the ~/.ssh/authorized_keys of the user deploy. After that, ssh deploy@server lets you in without a password.

On the first connection to a new server, ssh asks whether you trust its host key (Are you sure you want to continue connecting). After yes, the server's fingerprint gets written to ~/.ssh/known_hosts on your machine, and ssh checks it on every login after that.

Permissions on ~/.ssh

Permissions on these files matter a lot. As long as the StrictModes setting is on (and it's on by default), sshd checks the home directory, ~/.ssh and authorized_keys. If anyone besides the owner can write to them, or the owner is someone else, sshd ignores that user's keys. The usual permissions are:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

One thing is strictly required: write access only for the owner. With 644 on authorized_keys the login still works, but with 664 or 777 on ~/.ssh it stops. Another trap: a file created as root belongs to root. If it has 600 permissions, sshd can't read it on behalf of the user.

The client checks permissions too, but only on the private key. If ~/.ssh/id_ed25519 is readable by others, ssh refuses to use it:

@         WARNING: UNPROTECTED PRIVATE KEY FILE!          @
Permissions 0644 for '/home/dev/.ssh/id_ed25519' are too open.
...
This private key will be ignored.

If a key login "silently doesn't work" and ssh asks for a password again, the first thing to check is the permissions and owner of ~/.ssh. The client won't show the reason. sshd writes it to its log on the server:

Authentication refused: bad ownership or modes for directory /home/deploy/.ssh

ssh-agent: enter the passphrase once

ssh-agent keeps the decrypted key in memory for the session. You type the passphrase once when you add the key, and connections after that go through without asking.

$ eval "$(ssh-agent -s)"
Agent pid 4123

$ ssh-add ~/.ssh/id_ed25519
Enter passphrase for /home/user/.ssh/id_ed25519:
Identity added: /home/user/.ssh/id_ed25519 (deploy@laptop)

ssh-add -l shows which keys are currently in the agent.

On a desktop, the system usually already has an agent running. Inside CI you start the agent by hand and feed it a key from a protected variable, so the pipeline connects over SSH without printing the key to the log.

The same key works for git

GitLab and GitHub use exactly the same mechanism. You add your public key in your profile settings, and git push to a git@... address goes through without a password. Check the connection:

$ ssh -T git@gitlab.com
Welcome to GitLab, @username!

GitHub answers similarly to ssh -T git@github.com: Hi username! You've successfully authenticated, but GitHub does not provide shell access.

One key covers both servers and git hosting. You don't need a separate password for each service.

Common mistakes

What to remember

The private key never leaves your machine; only the public key goes to servers and hosting providers.

The server lets in whoever has their public key in ~/.ssh/authorized_keys. Only the owner should be able to write to ~/.ssh and authorized_keys, or sshd will ignore the key. Usual permissions: 700 on the directory and 600 on the file.

ssh-agent holds the decrypted key so you don't enter the passphrase on every connection. The same key works for git over SSH too.

The next lesson covers how ~/.ssh/config and a bastion make access to many servers easier.

What you'll need for the tasks

Done reading?

Mark the lesson as read to move your track progress forward.

Go through it with an AI agent

The agent explains anything unclear in plain words, gives you 2 labs for this lesson and drills you on interview questions. $49 one-time, lifetime access.

Get access for $49

Tell the agent: use MCP izi, give me lesson linux-security-01-ssh-keys