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_keysby hand when needed - Use
ssh-agentto 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?
| Situation | Technique |
|---|---|
| Log in to a server without a password | ssh-keygen + ssh-copy-id |
| Run Ansible without being interrupted | key without passphrase, or ssh-agent |
| Reach GitHub / GitLab over SSH | dedicated key + ~/.ssh/config |
| RHCSA exam, "configure key-based auth" task | ssh-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.
Ed25519, recommended
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_ed25519Your public key has been saved in /home/bob/.ssh/id_ed25519.pubThe key fingerprint is:SHA256:wzADwtgppDzS9xC3BfogrcBzlncuuUHV7l0+w0Y1n+I bob@workstationRSA 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.
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.
# Key dedicated to the backup serverssh-keygen -t ed25519 -f ~/.ssh/id_ed25519_backup -C "backup@workstation"
# Key for GitHubssh-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.
With ssh-copy-id (recommended method)
ssh-copy-id bob@192.168.1.10ssh-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:
ssh-copy-id -p 2222 bob@192.168.1.10ssh-copy-id -i ~/.ssh/id_ed25519_backup.pub bob@backup.example.comCheck that it works:
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:
-
Print the public key on the client machine
Terminal window cat ~/.ssh/id_ed25519.pubCopy the whole line (it starts with
ssh-ed25519). -
On the remote server, prepare
authorized_keysTerminal window mkdir -p ~/.sshchmod 700 ~/.sshecho "ssh-ed25519 AAAA... bob@workstation" >> ~/.ssh/authorized_keyschmod 600 ~/.ssh/authorized_keys -
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:
# SSH directorychmod 700 ~/.ssh
# Private key: readable by the owner onlychmod 600 ~/.ssh/id_ed25519
# Public key: can be read by everyonechmod 644 ~/.ssh/id_ed25519.pub
# Authorised keys file: criticalchmod 600 ~/.ssh/authorized_keys
# Client configuration filechmod 600 ~/.ssh/config
# Known hostschmod 644 ~/.ssh/known_hostsQuick check:
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 configssh-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.
# Start the agent (if the desktop has not already started it)eval "$(ssh-agent -s)"
# Add the key: asks for the passphrase only oncessh-add ~/.ssh/id_ed25519
# Check the loaded keysssh-add -lThe 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.
# Key remembered for 4 hoursssh-add -t 4h ~/.ssh/id_ed25519Manage several keys
When you use several keys (production servers, backup servers, GitHub, GitLab), declare them in ~/.ssh/config:
# GitHubHost github.com User git IdentityFile ~/.ssh/id_ed25519_github
# Backup serversHost 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_prodWithout 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:
# On the serverecho 'PasswordAuthentication no' | sudo tee /etc/ssh/sshd_config.d/10-hardening.confsudo sshd -t # syntax: no output if all is wellsudo sshd -T | grep -i '^passwordauthentication' # effective value: no# Reload the servicesudo systemctl reload ssh # Debian/Ubuntusudo systemctl reload sshd # RHEL/FedoraTroubleshooting
| Symptom | Likely cause | Action |
|---|---|---|
Permission denied (publickey) | Wrong ~/.ssh/ permissions | Fix with chmod 700 ~/.ssh && chmod 600 authorized_keys |
Permission denied (publickey) | Public key missing from authorized_keys | Check with cat ~/.ssh/authorized_keys on the server |
| SSH still asks for the password | PasswordAuthentication yes read first in sshd_config.d/ | sudo sshd -T | grep -i passwordauthentication, then a 10-*.conf drop-in |
Too many authentication failures | Too many keys tried | Add IdentitiesOnly yes in ~/.ssh/config |
ssh-add -l: "Could not open a connection to your authentication agent" | ssh-agent not started | eval "$(ssh-agent -s)" |
| Key accepted in the lab but refused on RHEL | Wrong 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:700on the directory,600onauthorized_keysand private keys ssh-copy-idis the quick method; the manual copy intoauthorized_keysis for when the tool is missing, for example from WindowsPasswordAuthentication nogoes in a drop-in read first, and is checked withsshd -Tssh-agentremoves the repeated passphrase typing without sacrificing security- On RHEL, think of
restoreconif 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
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
Review
(0/0)Score by domain
A domain groups several guides and gets several questions, so its score is more reliable than a per-topic score, which often rests on a single question.
Summary
Strengths
No topic passed at 80% on at least two questions yet.
Weak areas
No topic below the pass mark.
Recommended next
Hints before you try again?
Continue the course: Connect over SSH: the OpenSSH client guide
A new full quiz with random questions
Work again only on the questions you missed