SSH Keys From Scratch: Your Machine to Your Servers
Create a key, put it on a server, name your servers in ~/.ssh/config, and connect with ssh prod instead of an IP address. Ends with a machine that logs in without passwords and a config you can copy to the next one.
Prerequisites
- A terminal on your own machine: macOS Terminal, Linux shell, or Windows PowerShell
- A server you can currently reach, with a password or an existing key
- No prior SSH knowledge needed
Do not SSH into the server and generate a key there. That key lets the server reach other machines; it does nothing to get you into the server. The one exception is a deploy key, which is the last step of this guide.
Read this first: which machine am I on?
# Your own machine -> the key is generated here, and the private half stays here # The server -> only the public half goes here whoami && hostname
Almost every step in this guide runs on your own laptop or desktop. Only two touch the server, and each says so.
Windows, macOS or Linux?
# macOS / Linux : the terminal is ready, follow the steps as they are # Windows : open PowerShell and run the next step first # # Note for Windows: if you work inside WSL or Git Bash you are on # Linux, so skip the PowerShell steps and follow the rest as they are.
The commands are identical on macOS and Linux. Windows differs in three places, and each has its own step: the agent is a service, there is no chmod, and the config file sits in your user profile.
Set Up SSH on Windows (PowerShell)
Windows only. Skip this on macOS and Linux.
If a key exists, do not generate over it. Anything that trusts it, servers and GitHub alike, would stop letting you in.
Check Whether You Already Have an SSH Key
On your own machine. A pair named id_ed25519 and id_ed25519.pub means you already have a key and can skip the next step.
Generate ed25519 SSH key
On your own machine. The same command works in PowerShell, Terminal and any Linux shell.
Fix ~/.ssh Permissions
macOS and Linux only. Windows has no chmod: a key inside your user profile is already private to you.
Load a Key into the SSH Agent
On your own machine. On Windows this works once the agent service is running from the earlier step.
Store an SSH Passphrase in the macOS Keychain
macOS only, and optional. It stops the passphrase prompt returning after every reboot.
Two ways to put the key on the server
# Easiest, if password login still works: the next step # If password login is off, or you paste in a panel: the step after it
ssh-copy-id does it in one command when password login still works. The manual step after it is for servers where it does not, or for pasting into a provider panel.
Copy SSH Key to Remote Server
Run this on your own machine, pointed at the server. It asks for your password one last time.
Only the .pub file is ever shared. The file without .pub is the private key and never leaves your machine.
Print Your Public Key to Paste It Somewhere
The alternative route: copy this line and paste it into GitHub, cPanel, or your provider dashboard. On Windows use: Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub
Test an SSH Connection Without Opening a Shell
From your own machine. It should print OK and the hostname without asking for anything.
Set Up ~/.ssh/config for Several Servers
macOS and Linux. Windows users: skip to the next step, which does the same thing in PowerShell.
Create ~/.ssh/config on Windows
Windows only, and the equivalent of the previous step. The file lives at C:\Users\YourName\.ssh\config
Use a Different Key per Account or Host
Optional, and the reason most people meet the config file at all: a work GitHub account and a personal one on the same machine.
SSH via Jump Host (Bastion)
For a server with no public address: reach it through a bastion in one command.
Debug a Refused SSH Login (Verbose Mode)
Keep this one. When a login is refused, it names the cause instead of leaving you guessing.
Create a Deploy Key on a Server
This one runs ON the server, and it is the only step in the guide that does. It is for automation, not for you.
Only after the previous steps succeed, and keep your current session open while you test a second one.
Disable Root SSH Login
On the server. The payoff: once key login is proven, turning off root login removes the attack surface brute force relies on.