How to Set Up SSH Login Without a Password (SSH Keys): Step-by-Step Guide
Typing a password every time you connect to a server is slow, and passwords are the weakest link in most SSH setups. SSH key authentication fixes both problems.
With keys, your computer proves who you are using a cryptographic key pair, so you can log in over SSH without typing the account password, and you can switch password logins off entirely to block brute-force attacks. This guide shows the full setup on Linux, macOS and Windows, including a Windows Server target, and explains the safety checks that keep you from locking yourself out.
⚡ Quick Summary
- 1. Generate a key pair on your computer:
ssh-keygen -t ed25519. - 2. Copy the public key to the server:
ssh-copy-id user@server. - 3. Test the login, and use
ssh-agentso you enter your key passphrase only once per session. - 4. Optionally disable password login with
PasswordAuthentication no, after confirming key login works. - Golden rule: never close your working session until a second, fresh session proves the new configuration is safe.
- How passwordless SSH works
- Before you start
- Step 1: Generate an SSH key pair
- Step 2: Copy the public key to the server
- Step 3: Test the login
- Step 4: Use ssh-agent and a config file
- Step 5: Disable password login (recommended)
- Keys for scripts and automation
- Troubleshooting
- Security best practices
- Command cheat sheet
- FAQ
- Sources
How passwordless SSH works
SSH public-key authentication uses a key pair: a private key that stays on your computer and a public key that you place on the server.
| Part | Where it lives | Share it? |
|---|---|---|
Private key (id_ed25519) | Your computer, in ~/.ssh | Never. Treat it like a password. |
Public key (id_ed25519.pub) | The server, in ~/.ssh/authorized_keys | Yes, it is safe to share. |
When you connect, the server challenges your client to prove it holds the private key matching a public key listed in authorized_keys. The private key itself is never sent over the network.
ssh-agent remembers it for the session. You never type the server account password at all. A key with no passphrase gives true zero-prompt login but is riskier, so keep it for tightly restricted automation (see below).Before you start
- An SSH server you can already log in to with a password (OpenSSH on Linux, or OpenSSH Server on Windows).
- An SSH client: built in on Linux, macOS and current Windows 10 and 11 (PowerShell or Command Prompt).
- A second way into the server, such as a console or hypervisor access, in case you make a configuration mistake. This matters most before Step 5.
- The server hostname or IP address and your username.
Step 1: Generate an SSH key pair
Run this on the computer you will connect from. Ed25519 is the recommended modern key type: its keys are short, fast and strong. Use RSA 4096 only if you must support a very old system that lacks Ed25519.
# Linux, macOS, or Windows PowerShell
ssh-keygen -t ed25519 -C "khurram@work-laptop"
# Only for very old servers without Ed25519 support
ssh-keygen -t rsa -b 4096 -C "khurram@work-laptop"
- Accept the default file location by pressing Enter. The key is saved as
~/.ssh/id_ed25519(on Windows,C:\Users\<you>\.ssh\id_ed25519). - Enter a strong passphrase when asked. This encrypts the private key on disk, so a stolen laptop or backup does not hand over server access.
- Confirm the two files exist: the private key and the
.pubpublic key.
# Check the files were created
ls -l ~/.ssh/id_ed25519 ~/.ssh/id_ed25519.pub
# Show the public key (this is the part you copy to servers)
cat ~/.ssh/id_ed25519.pub
.pub). If it leaks, remove its public key from every server and generate a new pair.Step 2: Copy the public key to the server
Option A: ssh-copy-id (Linux and macOS, easiest)
This tool appends your public key to ~/.ssh/authorized_keys on the server and sets sensible permissions. You will be asked for the account password one last time.
ssh-copy-id user@server_ip_or_hostname
# If you have several keys, choose one
ssh-copy-id -i ~/.ssh/id_ed25519.pub user@server_ip_or_hostname
# Non-standard SSH port
ssh-copy-id -p 2222 user@server_ip_or_hostname
Option B: Manual copy (when ssh-copy-id is missing)
# From Linux or macOS
cat ~/.ssh/id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
# From Windows PowerShell to a Linux server
type $env:USERPROFILE\.ssh\id_ed25519.pub | ssh user@server "mkdir -p ~/.ssh && chmod 700 ~/.ssh && cat >> ~/.ssh/authorized_keys && chmod 600 ~/.ssh/authorized_keys"
Option C: Windows Server or Windows 11 as the SSH target
If the server is Windows running OpenSSH Server, the key location depends on the account type. Microsoft documents that administrator accounts use a shared file, while standard users use their own profile folder.
# Standard user: add the key to the user's own file (run as that user on the server)
New-Item -ItemType Directory -Force -Path "$env:USERPROFILE\.ssh"
Add-Content -Force -Path "$env:USERPROFILE\.ssh\authorized_keys" -Value "ssh-ed25519 AAAA... your-comment"
# Administrator account: use the shared file and lock down its permissions
Add-Content -Force -Path "$env:ProgramData\ssh\administrators_authorized_keys" -Value "ssh-ed25519 AAAA... your-comment"
icacls.exe "$env:ProgramData\ssh\administrators_authorized_keys" /inheritance:r /grant "Administrators:F" /grant "SYSTEM:F"
Get-Service sshd. If key login still fails for an administrator, the usual cause is that the key was put in the user’s profile instead of administrators_authorized_keys, or that file’s permissions are too open.Step 3: Test the login
ssh user@server_ip_or_hostname
# Force a specific key and show verbose output if something is wrong
ssh -i ~/.ssh/id_ed25519 -v user@server_ip_or_hostname
If you set a passphrase, you are asked for the key passphrase, not the server account password. If you see a shell prompt, key authentication works.
Step 4: Use ssh-agent and a config file
Typing the passphrase for every connection defeats the point. ssh-agent keeps your decrypted key in memory so you unlock it once per session.
Linux and macOS
# Start the agent (many desktops start it for you) and add your key
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# macOS: store the passphrase in the Keychain
ssh-add --apple-use-keychain ~/.ssh/id_ed25519
Windows (PowerShell, run as administrator once)
Get-Service ssh-agent | Set-Service -StartupType Automatic
Start-Service ssh-agent
ssh-add $env:USERPROFILE\.ssh\id_ed25519
Create a shortcut in ~/.ssh/config
A config file saves you from typing long commands and tells SSH which key to use for each host.
# ~/.ssh/config
Host myserver
HostName 192.168.1.50
User admin
Port 22
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
AddKeysToAgent yes
# macOS only, add inside the Host block:
# UseKeychain yes
Now connect with just ssh myserver. Set strict permissions on the file with chmod 600 ~/.ssh/config.
Step 5: Disable password login (recommended)
Key login is already working, but the server still accepts passwords, which means attackers can still try to guess them. Turning password authentication off removes that entire attack path.
- Confirm key login works from a fresh terminal (Step 3).
- Create a hardening file on the server. On modern distributions, drop-in files in
/etc/ssh/sshd_config.d/are read in alphabetical order and the first value found wins, so name yours so it sorts early. - Test the configuration syntax before restarting.
- Restart the SSH service and test again from a new session.
- Verify the effective settings.
# /etc/ssh/sshd_config.d/01-key-auth-only.conf
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin prohibit-password
# Check syntax (no output means OK)
sudo sshd -t
# Restart the service
sudo systemctl restart ssh # Debian and Ubuntu
sudo systemctl restart sshd # RHEL, Fedora, Rocky, AlmaLinux
# Show the settings sshd is really using
sudo sshd -T | grep -i -E 'passwordauthentication|pubkeyauthentication|kbdinteractive|permitrootlogin'
50-cloud-init.conf that sets PasswordAuthentication yes. Because the first value wins, a file named 99-... would be ignored. Always confirm with sshd -T, and check both the main sshd_config and the drop-in folder.Windows Server
On Windows, the server configuration lives in C:\ProgramData\ssh\sshd_config. Set PasswordAuthentication no there, copy your public key first, and restart the service with Restart-Service sshd.
Keys for scripts and automation
Backups, monitoring and deployment jobs often need a key without a passphrase, since nobody is there to type it. That is acceptable only if you limit what the key can do. Use options at the start of the line in authorized_keys.
# ~/.ssh/authorized_keys on the server (all on one line)
from="10.0.0.5",command="/usr/local/bin/backup.sh",restrict ssh-ed25519 AAAA... backup-job
from="..."allows the key only from the listed addresses.command="..."forces one specific command, whatever the client asks to run.restrictturns off port forwarding, agent forwarding, X11 and terminal allocation unless you re-enable them.
Troubleshooting
| Symptom | Likely cause and fix |
|---|---|
Permission denied (publickey) | The server does not accept your key. Check you copied the public key to the right user, then run ssh -v to see which keys are offered. |
| Still asks for the account password | Permissions are too loose on the server. Run chmod 700 ~/.ssh and chmod 600 ~/.ssh/authorized_keys, and make sure your home directory is not writable by other users. |
UNPROTECTED PRIVATE KEY FILE | Your private key is readable by others. Run chmod 600 ~/.ssh/id_ed25519 on the client. |
Too many authentication failures | The agent offers many keys before the right one. Add IdentitiesOnly yes and IdentityFile to the host entry in ~/.ssh/config. |
| Passphrase prompt every time | The agent is not running or the key is not loaded. Run ssh-add, or add AddKeysToAgent yes to your config. |
| Works for a normal user, not for root | PermitRootLogin may block it. prohibit-password allows root with a key. Prefer a normal account plus sudo. |
| SELinux systems (RHEL family) | Wrong security context on ~/.ssh. Run restorecon -Rv ~/.ssh. |
| Windows admin account keeps failing | The key must be in C:\ProgramData\ssh\administrators_authorized_keys with the permissions shown earlier. |
| Server rejects it and the logs explain why | Read the server log: sudo journalctl -u ssh (Debian and Ubuntu), sudo journalctl -u sshd (RHEL family), or /var/log/auth.log and /var/log/secure. |
| “Remote host identification has changed” warning | The server’s host key differs from the saved one. Do not just delete the entry. Verify the change is expected (rebuild, reinstall) before updating known_hosts. |
Security best practices
- Always set a passphrase on keys that live on laptops and workstations.
- Use Ed25519, and use a separate key per device or purpose so you can revoke one without affecting others.
- Back up private keys securely, and never email or paste them into chats or tickets.
- Remove keys when people leave or devices are lost. Delete the matching line from
authorized_keys. Note that this does not end sessions that are already open. - Disable password login and root password access once keys work, and limit who can log in with
AllowUsersorAllowGroups. - Consider hardware-backed keys such as FIDO2 security keys (
ssh-keygen -t ed25519-sk) for high-value servers. They require a physical device on login. - Keep OpenSSH updated and review
authorized_keysfiles regularly for keys nobody recognises. - Add rate limiting or a tool such as Fail2Ban if the server is exposed to the internet. Changing the port reduces noise but is not real protection.
Command cheat sheet
| Task | Command |
|---|---|
| Generate an Ed25519 key | ssh-keygen -t ed25519 -C "comment" |
| Copy the key to a server | ssh-copy-id user@server |
| Log in with a specific key | ssh -i ~/.ssh/id_ed25519 user@server |
| Debug a connection | ssh -v user@server |
| Load the key into the agent | ssh-add ~/.ssh/id_ed25519 |
| List loaded keys | ssh-add -l |
| Change a key passphrase | ssh-keygen -p -f ~/.ssh/id_ed25519 |
| Test server config | sudo sshd -t |
| Show effective server settings | sudo sshd -T |
| Fix permissions | chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys |
If you administer Windows Server, Azure and Linux hybrid environments, more practical guides are on VMoreCloud.
Frequently asked questions
How do I SSH without a password?
Generate a key pair with ssh-keygen -t ed25519, copy the public key to the server with ssh-copy-id user@server, and connect. Use ssh-agent so you enter the key passphrase only once per session.
Is passwordless SSH secure?
Yes, when done properly. Key-based authentication is stronger than passwords because the private key never leaves your computer. Protect the key with a passphrase and disable password login on the server.
Should I use RSA or Ed25519?
Ed25519 is the recommended default because it is compact, fast and strong. Use RSA 4096 only for legacy systems that do not support Ed25519.
Where does the public key go on the server?
On Linux, in the target user’s ~/.ssh/authorized_keys file, one key per line. On Windows OpenSSH, standard users use their profile’s .ssh\authorized_keys and administrators use C:\ProgramData\ssh\administrators_authorized_keys.
Why does SSH still ask for a password after I copied my key?
Usually permissions are wrong, the key went to the wrong user, or the server is not set to accept public keys. Fix permissions (700 for .ssh, 600 for authorized_keys) and run ssh -v to see what happens.
Can I use the same key on multiple servers?
Yes. Copy the same public key to as many servers as you like. For better security, use separate keys for different roles or devices so you can revoke them independently.
Sources and further reading
- OpenSSH manual pages (ssh, ssh-keygen, ssh-agent, sshd)
- OpenBSD manual: sshd_config
- OpenBSD manual: ssh-keygen
- Microsoft Learn: OpenSSH key management on Windows
- Linuxize: How to set up passwordless SSH login
This guide is based on OpenSSH documentation and common administration practice as of October 26, 2026. Option names and file locations can vary between operating system versions, so check your distribution’s documentation. Changing SSH server settings can lock you out, so always keep a second session or console access open while testing.

