Skip to content
Français
Account: not signed in, sync available My learning
Select theme
Français

Create and manage SSH keys

By updated

Improve this page

SSH key authentication is safer than a password and makes it possible to automate connections. It is the prerequisite for everything that follows in the SSH path: without a configured key, no password-free login, no reliable Ansible, no CI/CD pipeline.

It is a direct RHCSA objective (Manage security domain, "Configure key-based authentication for SSH") and LFCS objective (Networking domain, "Configure the OpenSSH server and client").

What you will learn

  • Generate an Ed25519 key pair (or RSA 4096) with a passphrase
  • Deploy the public key to a server with ssh-copy-id
  • Manage authorized_keys by hand when needed
  • Use ssh-agent to remember the passphrase for the session
  • Fix the permissions of ~/.ssh/ that silently block authentication
  • Work with several keys for several servers or roles

In which context?

SituationTechnique
Log in to a server without a passwordssh-keygen + ssh-copy-id
Run Ansible without being interruptedkey without passphrase, or ssh-agent
Reach GitHub / GitLab over SSHdedicated key + ~/.ssh/config
RHCSA exam, "configure key-based auth" taskssh-keygen + authorized_keys
Client without ssh-copy-id (Windows OpenSSH)manual copy of the public key

Generate a key pair

ssh-keygen produces two files: the private key, which never leaves your workstation, and the public key in .pub, meant to be copied to the servers. The algorithm is chosen here and cannot be changed afterwards.

Terminal window
ssh-keygen -t ed25519 -C "bob@workstation"

The command asks two questions. At Enter file, press Enter to keep the default location (~/.ssh/id_ed25519). At Enter passphrase, type a passphrase: it encrypts the private key on disk, so stealing the file is no longer enough to log in. Output measured on Debian 13 (OpenSSH 10.0), the fingerprint being specific to each key:

Generating public/private ed25519 key pair.
Your identification has been saved in /home/bob/.ssh/id_ed25519
Your public key has been saved in /home/bob/.ssh/id_ed25519.pub
The key fingerprint is:
SHA256:wzADwtgppDzS9xC3BfogrcBzlncuuUHV7l0+w0Y1n+I bob@workstation

RSA 4096, maximum compatibility

RSA remains useful with old equipment that does not know Ed25519: the key is slower to generate and heavier to verify, but it is accepted everywhere.

Terminal window
ssh-keygen -t rsa -b 4096 -C "bob@workstation"

Named key for a specific use

The -f option chooses the file name: one key per use limits the damage if one of them leaks, and lets you revoke it without touching the others. The -C comment reminds what the key is for in authorized_keys.

Terminal window
# Key dedicated to the backup server
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_backup -C "backup@workstation"
# Key for GitHub
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_github -C "bob@github"

Deploy the public key to a server

Deploying a key means adding its public content to the ~/.ssh/authorized_keys file of the target account. The permissions of this file and of its directory matter as much as its content: too open, and the SSH server refuses the key without telling the client.

Terminal window
ssh-copy-id bob@192.168.1.10

ssh-copy-id logs in with the password, creates ~/.ssh/authorized_keys on the server if needed, and adds your public key to it.

With a non-standard port or a specific key:

Terminal window
ssh-copy-id -p 2222 bob@192.168.1.10
ssh-copy-id -i ~/.ssh/id_ed25519_backup.pub bob@backup.example.com

Check that it works:

Terminal window
ssh bob@192.168.1.10
# must log in without asking for a password (or with the key's passphrase)

By hand (RHCSA, without ssh-copy-id)

ssh-copy-id ships with the OpenSSH client, in openssh-client on Debian and openssh-clients on RHEL (measured on Debian 13 and AlmaLinux 10). The manual method is still worth knowing: a client without ssh-copy-id, such as the OpenSSH client of Windows, or a server where password login is already closed, forces you to write authorized_keys yourself:

  1. Print the public key on the client machine

    Terminal window
    cat ~/.ssh/id_ed25519.pub

    Copy the whole line (it starts with ssh-ed25519).

  2. On the remote server, prepare authorized_keys

    Terminal window
    mkdir -p ~/.ssh
    chmod 700 ~/.ssh
    echo "ssh-ed25519 AAAA... bob@workstation" >> ~/.ssh/authorized_keys
    chmod 600 ~/.ssh/authorized_keys
  3. Check the connection

    Terminal window
    ssh bob@192.168.1.10

Required permissions of ~/.ssh/

It is the first thing to check if key authentication fails:

Terminal window
# SSH directory
chmod 700 ~/.ssh
# Private key: readable by the owner only
chmod 600 ~/.ssh/id_ed25519
# Public key: can be read by everyone
chmod 644 ~/.ssh/id_ed25519.pub
# Authorised keys file: critical
chmod 600 ~/.ssh/authorized_keys
# Client configuration file
chmod 600 ~/.ssh/config
# Known hosts
chmod 644 ~/.ssh/known_hosts

Quick check:

Terminal window
ls -la ~/.ssh/

Expected result:

drwx------ 2 bob bob 4096 Apr 9 10:00 .
-rw------- 1 bob bob 411 Apr 9 10:00 id_ed25519
-rw-r--r-- 1 bob bob 97 Apr 9 10:00 id_ed25519.pub
-rw------- 1 bob bob 582 Apr 9 10:00 authorized_keys
-rw------- 1 bob bob 180 Apr 9 10:00 config

ssh-agent: remember the passphrase for the session

If your key is protected by a passphrase, SSH asks for it at every connection. ssh-agent keeps the unlocked key for the whole session.

Terminal window
# Start the agent (if the desktop has not already started it)
eval "$(ssh-agent -s)"
# Add the key: asks for the passphrase only once
ssh-add ~/.ssh/id_ed25519
# Check the loaded keys
ssh-add -l

The output of ssh-add -l gives the key's size, its fingerprint, its comment and its type. Measured on Debian 13:

256 SHA256:wzADwtgppDzS9xC3BfogrcBzlncuuUHV7l0+w0Y1n+I bob@workstation (ED25519)

Limited lifetime

A key loaded in the agent can be used by any process of your session. The -t option bounds this exposure: after the delay, the agent forgets the key and the passphrase will be asked again.

Terminal window
# Key remembered for 4 hours
ssh-add -t 4h ~/.ssh/id_ed25519

Manage several keys

When you use several keys (production servers, backup servers, GitHub, GitLab), declare them in ~/.ssh/config:

# GitHub
Host github.com
User git
IdentityFile ~/.ssh/id_ed25519_github
# Backup servers
Host backup.example.com
User backupuser
IdentityFile ~/.ssh/id_ed25519_backup
# Production servers (every IP of the subnet)
Host 10.0.1.*
User admin
IdentityFile ~/.ssh/id_ed25519_prod

Without this configuration, SSH tries the default keys (id_ed25519, id_rsa...) in order. With several keys, the explicit declaration avoids "Too many authentication failures" errors.


Turn off password authentication (server side)

Once the keys are deployed, turn off password logins to reduce the attack surface. The trap is where to write it: sshd_config starts with Include /etc/ssh/sshd_config.d/*.conf, and the first value read wins. A file of that directory saying PasswordAuthentication yes cancels the line added further down in sshd_config: measured on Debian 13 and AlmaLinux 10 with such a file, sshd -T still prints yes. The case is not exotic: the AlmaLinux 10 image already ships a 25-permitrootlogin.conf that sets PermitRootLogin yes. So write the rule in a file with a low number, read first:

Terminal window
# On the server
echo 'PasswordAuthentication no' | sudo tee /etc/ssh/sshd_config.d/10-hardening.conf
sudo sshd -t # syntax: no output if all is well
sudo sshd -T | grep -i '^passwordauthentication' # effective value: no
Terminal window
# Reload the service
sudo systemctl reload ssh # Debian/Ubuntu
sudo systemctl reload sshd # RHEL/Fedora

Troubleshooting

SymptomLikely causeAction
Permission denied (publickey)Wrong ~/.ssh/ permissionsFix with chmod 700 ~/.ssh && chmod 600 authorized_keys
Permission denied (publickey)Public key missing from authorized_keysCheck with cat ~/.ssh/authorized_keys on the server
SSH still asks for the passwordPasswordAuthentication yes read first in sshd_config.d/sudo sshd -T | grep -i passwordauthentication, then a 10-*.conf drop-in
Too many authentication failuresToo many keys triedAdd IdentitiesOnly yes in ~/.ssh/config
ssh-add -l: "Could not open a connection to your authentication agent"ssh-agent not startedeval "$(ssh-agent -s)"
Key accepted in the lab but refused on RHELWrong SELinux context on ~/.ssh/restorecon -Rv ~/.ssh

Put it into practice

Setting up key access for your own account is one thing; doing it properly for a service user is another. On a VM, this lab makes you generate an Ed25519 pair, deploy the public key in authorized_keys with the right permissions, then harden that account's connection.

Key points

  • Ed25519 is the recommended choice in 2026: compact, fast, safe
  • The ~/.ssh/ permissions are not negotiable: 700 on the directory, 600 on authorized_keys and private keys
  • ssh-copy-id is the quick method; the manual copy into authorized_keys is for when the tool is missing, for example from Windows
  • PasswordAuthentication no goes in a drop-in read first, and is checked with sshd -T
  • ssh-agent removes the repeated passphrase typing without sacrificing security
  • On RHEL, think of restorecon if SELinux is active and blocks key authentication

Knowledge check

Check that the essentials of this guide stuck. The questions cover only what has just been explained here.

Knowledge check

Check what you have learned with this interactive quiz

6 questions
6 min
70% to pass

How it works

  • The timer starts when you click Start
  • Multiple choice, true/false and short answer questions
  • You can move between questions
  • Detailed results are shown at the end

Starts the quiz and the timer

Is this project useful to you?

The guides, courses, quizzes and labs stay free. If you use them regularly, you can contribute to their upkeep and development.

Become a supporting member (new tab) One-time support (new tab) Learn more

Follow the project on LinkedIn