Guide

How to set up passwordless SSH with keys (ssh-keygen and ssh-copy-id)

Passwordless SSH means signing in with a key pair instead of a password. Create a key with ssh-keygen -t ed25519, copy its public half to the server with ssh-copy-id user@server (on Windows, one PowerShell line does the same), and from then on ssh user@server signs you in with the key.

The private key never leaves your computer. Give it a passphrase and let ssh-agent remember it, so you type the passphrase once per session instead of a password for every server.

  • Ed25519 and RSA keys
  • Windows, Mac and Linux
  • Key permissions that work

Updated · OpenSSH on Linux, macOS and Windows 10 and 11

How SSH keys work

An SSH key is a pair: a private key that stays on your computer, and a public key you can give to any server. The server keeps the public keys it accepts in ~/.ssh/authorized_keys in your user's home folder. When you connect, your computer proves it holds the matching private key, without ever sending it. Nothing guessable crosses the network, which is why keys are safer than passwords.

Which type? Ed25519 for anything current: short keys, fast, and accepted by current SSH servers. RSA (4096 bits) for old servers and devices that don't know Ed25519. ECDSA works too. DSA keys are obsolete and current SSH software refuses them. (An old server that refuses your RSA key with "no mutual signature supported", or won't connect at all with "no matching host key type found", needs a per-host exception for ssh-rsa.)

Step-by-step: set up passwordless SSH

  1. Step 1: Create a key pair

    On Linux or macOS open a terminal; on Windows 10 or 11 open PowerShell. The command is the same everywhere:

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

    Press Enter to keep the usual file name, then choose a passphrase. You get two files in the .ssh folder of your home directory (C:\Users\you\.ssh on Windows): id_ed25519, the private key, and id_ed25519.pub, the public key. The -C comment just labels the key, so you can tell your keys apart later.

  2. Step 2: Copy the public key to the server

    On Linux and macOS, ssh-copy-id does it in one go. It asks for your password one last time:

    ssh-copy-id admin@server.example.com
    ssh-copy-id -i ~/.ssh/id_ed25519.pub admin@server.example.com   # a specific key
    ssh-copy-id -p 2222 admin@server.example.com                    # another port

    Windows doesn't include ssh-copy-id. In PowerShell, this line does the same for a Linux or macOS server:

    type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh admin@server.example.com "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"

    You can also paste the one line from the .pub file into ~/.ssh/authorized_keys on the server yourself, or into the SSH keys box of your hosting provider's control panel before you create a server.

  3. Step 3: Sign in with the key

    Run ssh admin@server.example.com. It signs you in without the account password (it asks for the key's passphrase, if you set one). If it still asks for the password, see SSH key permissions below.

Use a specific key: ssh -i

ssh tries the usual key files (id_ed25519, id_ecdsa, id_rsa) by itself. For a key with another name, point to it:

ssh -i ~/.ssh/work_ed25519 admin@server.example.com

Or save it per server in your SSH config file with IdentityFile, and add IdentitiesOnly yes so ssh offers only that key. That also cures "Too many authentication failures", which happens when ssh offers several keys before the right one.

Keep the passphrase in ssh-agent

ssh-agent holds your unlocked key in memory, so you type the passphrase once rather than at every connection.

# Linux (most desktops already run an agent; then only the second line is needed)
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519

# macOS: remember the passphrase in the keychain
ssh-add --apple-use-keychain ~/.ssh/id_ed25519

# Windows: once, in PowerShell as administrator
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
# then, in a normal PowerShell
ssh-add $env:USERPROFILE\.ssh\id_ed25519

On a Mac, adding AddKeysToAgent yes and UseKeychain yes under Host * in ~/.ssh/config loads the key from the keychain by itself after a restart. Using your agent on a server you've signed in to (agent forwarding) is covered in what an SSH tunnel is.

SSH key permissions

The SSH server ignores authorized_keys if other users could change it, and ssh refuses a private key that other users can read. These are the permissions that work, on the server and on your own Linux or Mac computer:

Permissions for SSH keys and folders
File or folderPermissionCommand
~/.ssh (folder)700chmod 700 ~/.ssh
~/.ssh/authorized_keys (server)600chmod 600 ~/.ssh/authorized_keys
Private key, such as ~/.ssh/id_ed25519600chmod 600 ~/.ssh/id_ed25519
Public key, such as ~/.ssh/id_ed25519.pub644chmod 644 ~/.ssh/id_ed25519.pub
~/.ssh/config600chmod 600 ~/.ssh/config
Your home folderNot writable by otherschmod go-w ~

The files must also belong to the user who signs in. If you set them up as root, hand them over with sudo chown -R admin:admin /home/admin/.ssh (with that user's name).

"WARNING: UNPROTECTED PRIVATE KEY FILE!" on Linux or macOS means the private key is readable by others: run chmod 600 on it. On Windows, the same error is fixed by removing other users' access to the key file, in PowerShell:

icacls $env:USERPROFILE\.ssh\id_ed25519 /inheritance:r /grant:r "$($env:USERNAME):(R)"

Keys on a Windows server

For a standard user, the public key goes in C:\Users\username\.ssh\authorized_keys. For accounts in the Administrators group, Windows' OpenSSH Server reads C:\ProgramData\ssh\administrators_authorized_keys instead, and only if just Administrators and SYSTEM can access it: icacls.exe "C:\ProgramData\ssh\administrators_authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"

Turn off password sign-in on the server

Once your key works, and the key of everyone else who needs the server, stop accepting passwords. Put these lines in /etc/ssh/sshd_config (or a new file in /etc/ssh/sshd_config.d/):

PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password

Check what the server will really use with sudo sshd -T | grep -E 'passwordauthentication|kbdinteractive|permitrootlogin'. For each setting the first value the server reads wins, so if a file in sshd_config.d (cloud images often have one) still says PasswordAuthentication yes, change it there. Then restart SSH (sudo systemctl restart ssh, or sshd on Fedora and RHEL) and test from a new terminal before closing the old one.

Use SSH keys in RemoteAccessApp

The RemoteAccessApp SSH client signs in with keys too, for free, in the Console for Windows and Linux:

  1. Step 1: Edit the host and choose Key

    On Connections, right-click a saved host and choose Edit (or add a new one). Under Sign in with, pick Key.

  2. Step 2: Pick or bring in a key

    Use id_ed25519 (found on this PC) takes the key from your .ssh folder. Import file… takes OpenSSH, PEM or .ppk files (Ed25519, RSA or ECDSA), and Paste key… a key's text. A key with a passphrase asks for it once; then you choose to remember it or be asked each time.

  3. Step 3: Or create a new key

    Create a new key makes an Ed25519 key for the host. Copy public key puts its public half on the clipboard, ready for ~/.ssh/authorized_keys on the server or your provider's control panel.

Keys stay on your PC. With Pro, the Windows Console's Vault can also take them, end-to-end encrypted, to your other PCs and the website's browser terminal. Details are in the help article sign in to servers with SSH keys. New to the client? Download RemoteAccessApp; it's free for up to 5 saved hosts.

Good habits for SSH key management

  • One key per device, not one per server: a lost laptop then means removing one line from each server.
  • Never copy a private key to another computer. Make a new key there and add its public key instead.
  • Use a passphrase, and ssh-agent so it isn't a chore.
  • Label keys with -C (you@laptop) so authorized_keys tells you whose each line is.
  • When someone leaves or a device is gone, delete its line from authorized_keys on every server.
  • Check a key's fingerprint with ssh-keygen -lf ~/.ssh/id_ed25519.pub when you need to tell keys apart.

Haven't got an SSH server yet? Enable SSH on Ubuntu first, and if it runs on a non-standard port, see connecting on another SSH port. Once your key works, sftp, scp and rsync use it too: see how to use SFTP.

Questions, answered

Related