Here is a practical, step-by-step guide to generate and use SSH keys for remote access.
- Decide where you are running commands
- macOS/Linux: Terminal
- Windows: Windows Subsystem for Linux (WSL) or PowerShell with OpenSSH installed, or use PuTTY (less recommended for new setups)
- Generate a new SSH key pair
- Open your terminal or PowerShell
- Choose an algorithm:
- Recommended (modern): ed25519
- Legacy compatibility: rsa (4096 bits)
- Commands:
- ed25519 (recommended)
- ssh-keygen -t ed25519 -C “your_email@example.com”
- rsa (if needed)
- ssh-keygen -t rsa -b 4096 -C “your_email@example.com”
- ed25519 (recommended)
- When prompted:
- Enter a file path (default is ~/.ssh/id_ed25519 or id_rsa)
- Enter a passphrase (strongly recommended) and confirm
- If you skip a passphrase, just press Enter (less secure)
- Start the SSH agent and add your private key
- macOS/Linux:
- eval “$(ssh-agent -s)”
- ssh-add ~/.ssh/id_ed25519
- Windows (PowerShell with OpenSSH):
- Start-Service ssh-agent
- ssh-add $env:USERPROFILE.ssh\id_ed25519
- If you used a non-default filename, adjust paths accordingly
- Copy your public key to the remote server Two common options:
- Automated (recommended if available):
- ssh-copy-id user@remote_host
- If prompted, enter remote user password
- Manual (works anywhere):
- Display your public key: cat ~/.ssh/id_ed25519.pub
- Copy the entire line
- On the remote server, ensure ~/.ssh exists and has correct permissions:
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- Append the key to authorized_keys:
- echo “public_key_contents” >> ~/.ssh/authorized_keys
- Or: printf “%s ” “public_key_contents” >> ~/.ssh/authorized_keys
- Set permissions on the remote file:
- chmod 600 ~/.ssh/authorized_keys
- Optional: set permissions on the remote home and .ssh directories
- chmod 755 ~
- chmod 700 ~/.ssh
- Test the SSH connection
- ssh user@remote_host
- If you used a passphrase, you will be prompted to enter it (or use ssh-agent to cache)
- You should be logged in without entering the remote user’s password
- Optional: use an SSH config file for convenience
- Create or edit ~/.ssh/config
- Add an entry like:
- Host myserver HostName remote_host User remote_user IdentityFile ~/.ssh/id_ed25519 IdentitiesOnly yes
- Then connect with: ssh myserver
- Manage the SSH agent and multiple keys
- List currently loaded keys: ssh-add -l
- Remove a key: ssh-add -d ~/.ssh/id_ed25519
- Add another key: ssh-add /path/to/another_key
- Improve security and usability
- Use a strong passphrase on your private key
- Disable password authentication on the remote server (requires access to server config)
- Edit /etc/ssh/sshd_config on the server:
- PasswordAuthentication no
- ChallengeResponseAuthentication no
- PermitRootLogin no (optional but recommended)
- Reload SSH service:
- sudo systemctl reload sshd
- Edit /etc/ssh/sshd_config on the server:
- Consider using a hardware security key (FIDO2/WebAuthn) with SSH
- Regularly rotate keys and remove old ones:
- Remove a public key from remote_authorized_keys when no longer needed
- Windows-specific tips (if not using WSL)
- If using Windows OpenSSH client:
- ssh-keygen works in PowerShell to generate keys
- Use ssh-copy-id if available, or copy the public key manually as above
- If using PuTTY tools (older workflow):
- Generate keys with PuTTYgen
- Copy the public key into the remote server’s authorized_keys
- Use Pageant to cache the private key for single sign-on
Common pitfalls and quick fixes
- Permissions: remote ~/.ssh and authorized_keys must be strict (700 for .ssh, 600 for authorized_keys)
- Wrong key used: ensure the server’s SSH config isn’t forcing a different key method; specify IdentityFile in SSH config if needed
- Firewall/port: default SSH port is 22; if you use a nonstandard port, include it in the host (e.g., ssh -p 2222 user@host) or in the SSH config
- If you’re locked out: use console access or a separate admin method to revert sshd_config changes