← Back to Notes

How to Set Up SSH Keys on a Raspberry Pi 5 (or Any Server)

Set up SSH key authentication on a Raspberry Pi 5 (or any Linux server), test it safely, and harden the SSH service by disabling password logins — with a troubleshooting section for when things go sideways.

Using SSH keys instead of passwords is the standard way to manage a Raspberry Pi or any other server. It's significantly more secure against brute-force attacks, and it saves you the hassle of typing a password every time you want to check on your Docker containers.

This guide walks through generating a key pair, installing it on your server, testing it safely, and then locking down the SSH service so password logins are disabled entirely.

N
NOTE

This guide is written around a Raspberry Pi 5, but every step works identically on any Linux server — a VPS, a repurposed laptop, a homelab box. Wherever you see the Pi's username or IP, substitute your own.


How SSH keys actually work (the 30-second version)

Before the steps, it helps to understand what you're setting up, because it makes the rest of the guide make sense.

An SSH key comes as a pair of files that belong together:

  • A private key, which stays on your local machine and never leaves it. Think of it as the physical key in your pocket.
  • A public key, which you copy onto the server. Think of it as the lock you bolt onto the server's door.

When you connect, the server uses the public key (the lock) to issue a challenge that only the matching private key (your key) can answer. You prove you hold the private key without ever sending it across the network. Anyone can have your public key — it's useless without the private half — which is why it's safe to copy it around freely.

The whole security model rests on one rule: your private key stays secret and stays on your machine. Everything else follows from that.


Prerequisites

  • A Raspberry Pi 5 (running Raspberry Pi OS or Ubuntu), or any other Linux server.
  • A local machine (Linux, macOS, or Windows 10/11).
  • The IP address of your Pi. If you don't know it, run hostname -I on the Pi, or check your router's device list.
  • SSH already enabled on the Pi. On Raspberry Pi OS you can enable it with sudo raspi-config → Interface Options → SSH, or by placing an empty file named ssh in the boot partition before first boot.

Step 1: Generate the SSH Key Pair

First, create the "lock and key" on your local computer. We'll use the Ed25519 algorithm, which is faster and more secure than the older RSA standard.

Open your terminal and run:

ssh-keygen -t ed25519 -C "my-laptop-key"
Command PartWhat it does
ssh-keygenThe standard tool for creating and managing authentication keys — the "engine" that generates the pair.
-t ed25519Specifies the type (algorithm). Ed25519 is the modern gold standard: faster, more secure, and much shorter than RSA.
-C "..."A comment — a text label added to the end of the public key so you can identify which device it belongs to later.

You'll be prompted for a file location (press Enter to accept the default, ~/.ssh/id_ed25519) and an optional passphrase.

T
TIP

Set a passphrase if this key protects anything you care about. It encrypts the private key on disk, so even if someone copies the file off your machine, it's useless without the passphrase. Combined with the SSH agent (covered in troubleshooting), you only type it once per session — you get the security without the repetition.

Why Ed25519 instead of the default?

If you run ssh-keygen with no flags, it typically defaults to RSA. RSA still works fine, but Ed25519 is preferred today because:

  • It's secure: strong security with a much smaller mathematical footprint.
  • It's fast: generates and authenticates faster than RSA.
  • It's clean: an RSA public key is a big block of text; an Ed25519 public key is a single short line.

Do I have to use my real email in the comment?

No. The comment can be anything — it's purely for your own organization. Common choices are labels like "work-laptop", "gaming-pc", or "my-pi-key". When you look at the server's list of authorized keys later, that comment sits at the end of the line so you can remember which device each key belongs to.

W
WARN

Using a real email address here isn't a security risk exactly, but since the comment can end up in files you might share or publish, a neutral device label is the tidier habit.


Step 2: Copy the Public Key to Your Pi

Now tell the Raspberry Pi that your local machine is an authorized visitor by copying your public key to it.

On Linux or macOS

Run this from your local machine, replacing <IP_ADDRESS> with your Pi's actual IP:

ssh-copy-id -i ~/.ssh/id_ed25519.pub pi@<IP_ADDRESS>
N
NOTE

If you changed your default username from pi to something else during setup, use that username instead.

You'll be asked for your Pi's user password one last time. Once entered, the script automatically creates the ~/.ssh folder on the server, adds your key to authorized_keys, and sets the correct permissions.

On Windows

Windows' built-in OpenSSH client does not include ssh-copy-id, so the command above won't work. Instead, copy the key manually with this one-liner in PowerShell (replace the username and IP):

type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh pi@<IP_ADDRESS> "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

This pipes your public key over SSH and appends it to the server's authorized_keys file, creating the folder and setting permissions in the same step. You'll be prompted for your Pi password once.


Step 3: Test the Login

Before changing any settings, confirm the key actually works. Try to log in:

ssh pi@<IP_ADDRESS>

If you set a passphrase, you'll be prompted for it (this is your local key's passphrase, not the Pi's password). If not, you should be dropped straight into the Pi's command prompt with no password request at all. Success.

W
WARN

Do not proceed to Step 4 until key-based login works. If you disable passwords before confirming your key works, you can lock yourself out of the server entirely.


Step 4: Disable Password Authentication (Hardening)

Once you've confirmed the keys work, disable password logins entirely. Now nobody can guess their way in — they must physically possess your private key.

  1. Open the SSH config file on the Pi:

    sudo nano /etc/ssh/sshd_config
  2. Find and change these lines. Remove the # at the start of a line if it's commented out:

    • PasswordAuthentication → set to no
    • PubkeyAuthentication → ensure it's set to yes
    • KbdInteractiveAuthentication → set to no
    N
    NOTE

    On older guides you'll see ChallengeResponseAuthentication no. That option was renamed to KbdInteractiveAuthentication in modern OpenSSH (Raspberry Pi OS Bookworm, Ubuntu 24.04, and newer). The old name still works as an alias for now but produces deprecation warnings — use the new name.

  3. Test the config before applying it. This is the step that saves you from a lockout caused by a typo:

    sudo sshd -t

    If this command prints nothing, the config is valid. If it reports an error, fix it before continuing — do not restart SSH with a broken config.

  4. Save and exit nano: Ctrl+O, Enter, then Ctrl+X.

  5. Restart the SSH service:

    sudo systemctl restart ssh
    N
    NOTE

    On some systems the service is called sshd rather than ssh — if the command above errors, try sudo systemctl restart sshd. On Ubuntu 24.04+ with socket activation, you may also need sudo systemctl restart ssh.socket.

W
WARN

Keep your current session open. Do not close the terminal you're already logged in with until you've opened a second terminal and successfully logged in using your key. If there's a mistake in the config, your existing session stays alive as a safety net while you fix it — but a new login will reveal the problem before you're locked out.


Optional: Go One Step Further

Once the basics work, a few extra sshd_config settings meaningfully raise the bar. All of these go in /etc/ssh/sshd_config, followed by the same sudo sshd -t test and service restart:

  • Require keys explicitly: AuthenticationMethods publickey — makes public-key auth mandatory, belt-and-braces alongside disabling passwords.
  • Disable root login: PermitRootLogin no — nobody should SSH in directly as root; log in as your normal user and use sudo.
  • Change the default port (optional, minor benefit): Port 2222 (or any unused port) — doesn't stop a determined attacker but dramatically cuts the automated brute-force noise in your logs. Remember to connect with ssh -p 2222 pi@<IP_ADDRESS> afterward.
T
TIP

For remote access from outside your home network, resist the urge to forward SSH straight to the internet. A mesh VPN like Tailscale or WireGuard lets you reach the Pi securely without exposing the SSH port publicly at all — a much safer pattern than port-forwarding 22.


Summary of Files and Permissions

If you ever need to set this up manually without ssh-copy-id, make sure these permissions are set on the Pi — the SSH server will reject the connection if the files are "too open":

File/FolderRecommended PermissionCommand
~/.ssh700 (drwx------)chmod 700 ~/.ssh
~/.ssh/authorized_keys600 (-rw-------)chmod 600 ~/.ssh/authorized_keys

The ~/.ssh folder must be accessible only by you, and authorized_keys must be readable/writable only by you. SSH deliberately ignores keys in world-readable locations as a security measure — which is a common cause of the "it just keeps asking for a password" problem below.


Troubleshooting: "Permission Denied" or Connection Issues

Even with keys set up, things can go sideways. If you're still being prompted for a password or getting errors, check these common culprits.

1. Incorrect permissions

The SSH server is very picky about security. If your folders or files are too open, it ignores the keys entirely and falls back to password auth (or rejects you). Re-run the chmod commands from the summary table above, on the server.

2. The SSH agent isn't running

If you set a passphrase and don't want to type it every single time, add your key to the SSH agent on your local machine:

# Start the agent
eval "$(ssh-agent -s)"

# Add your private key
ssh-add ~/.ssh/id_ed25519

3. Mismatched usernames

If your username on your local computer is admin but your Pi user is pi, then simply running ssh <IP_ADDRESS> tries to log in as admin and fails. Always specify the user:

ssh pi@<IP_ADDRESS>

4. Still stuck? Ask SSH to explain itself

Run the connection with the verbose flag to see exactly where the handshake is failing — it shows which keys are offered, which are accepted, and where it falls back to a password:

ssh -v pi@<IP_ADDRESS>

For even more detail, use -vv or -vvv. The output is verbose but it almost always pinpoints the problem — look for lines mentioning your key file and whether the server accepted or rejected it.

5. Locked yourself out despite everything?

If you disabled passwords, broke the config, and closed all your sessions, you can still recover by connecting a keyboard and monitor directly to the Pi (or pulling the SD card / NVMe and editing sshd_config on another machine). This is exactly the scenario the "keep a second session open" warnings are designed to prevent — but it's recoverable if it happens.