The SSH Config File Explained: Stop Typing Long SSH Commands
~/.ssh/config turns ssh -i ~/.ssh/key -p 2222 deploy@203.0.113.10 into ssh prod. Where the file lives on each OS, the options worth knowing, multiple GitHub accounts, jump hosts, keep-alives, and the precedence rule that trips people up.
If you connect to more than one server, you've probably typed something like this:
ssh -i ~/.ssh/work_key -p 2222 deploy@203.0.113.10
The SSH config file lets you give that connection a short name and put the details in one place:
ssh prod
Every tool that uses SSH — git, scp, rsync, VS Code Remote SSH — reads the same file, so the short name works everywhere.
Where it lives
| System | Path |
|---|---|
| macOS / Linux | ~/.ssh/config |
| Windows (OpenSSH) | C:\Users\you\.ssh\config |
It's a plain text file with no extension. If it doesn't exist, create it. It should be readable only by you:
chmod 600 ~/.ssh/config
(Linux file permissions explained.)
The basic shape
Host prod
HostName 203.0.113.10
User deploy
Port 2222
IdentityFile ~/.ssh/work_key
IdentitiesOnly yes
Host— the nickname you'll type. Can include wildcards.HostName— the real address (IP or domain).User— the username on the server.Port— if not the default 22.IdentityFile— which private key to use. (SSH keys explained.)IdentitiesOnly yes— use only that key, rather than trying every key in your agent (which can trigger "Too many authentication failures").
Indentation is optional but makes the file readable.
Options worth knowing
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
AddKeysToAgent yes
ServerAliveInterval 60— send a keep-alive every 60 seconds, so idle connections don't get dropped by routers and firewalls. Fixes many "my SSH session froze" complaints.AddKeysToAgent yes— add the key to your SSH agent after first use, so you type its passphrase once per session.On macOS,
UseKeychain yesstores the passphrase in the keychain.LocalForward— set up a port forward every time you connect:Host db-tunnel HostName 203.0.113.10 User deploy LocalForward 5433 localhost:5432ProxyJump— connect through a bastion/jump host:Host internal-db HostName 10.0.0.5 User admin ProxyJump bastionssh internal-dbhops throughbastionautomatically.
Two GitHub accounts on one machine
A classic use: a personal and a work GitHub account, each with its own key. GitHub only knows which account you are by the key, so define two aliases:
Host github-personal
HostName github.com
User git
IdentityFile ~/.ssh/id_personal
IdentitiesOnly yes
Host github-work
HostName github.com
User git
IdentityFile ~/.ssh/id_work
IdentitiesOnly yes
Then clone using the alias instead of github.com:
git clone git@github-work:company/app.git
For an existing repository, update its remote: git remote set-url origin git@github-work:company/app.git.
The precedence rule that trips people up
SSH reads the file top to bottom, and for each option, the first value it finds wins. So put specific hosts first and a general Host * block last:
Host prod
User deploy # this wins for prod
Host *
User me # used only where nothing earlier set User
If Host * with User me came first, it would win for prod too, and you'd wonder why your User deploy line is ignored.
Testing and debugging
See the final settings SSH will use for a host:
ssh -G prodVerbose connection output to see which key is offered and why it fails:
ssh -v prod
Keep it tidy
- Use
Includeto split configs:Include ~/.ssh/config.d/*at the top of the file, with one file per client or project. - Add comments (
#) explaining unusual entries. - Never put passwords in the config file — SSH doesn't support it anyway; use keys.
The summary
~/.ssh/configgives connections short names and stores their details.- Core options:
HostName,User,Port,IdentityFile,IdentitiesOnly. - Add
ServerAliveIntervalto stop idle disconnects;ProxyJumpandLocalForwardfor hops and tunnels. - First match wins — specific hosts at the top,
Host *at the bottom. ssh -G hostshows the effective settings;ssh -vshows what's going wrong.
EasySpawn servers are reachable over SSH as well as from the browser and your phone — add one config entry and ssh myapp, VS Code Remote SSH and rsync all just work. See how it works or join the waitlist.
Related: SSH Keys Explained · VS Code Remote SSH · A tmux Cheat Sheet for Long-Running Sessions · The Terminal for Complete Beginners
Keep reading
SSH Port Forwarding Explained: Local, Remote, and Dynamic Tunnels
SSH tunnels let you reach a database or web app on a server as if it were on localhost — without opening ports to the internet. Local (-L), remote (-R) and dynamic (-D) forwarding with practical examples, background tunnels, and the security caveats.
VS Code Remote SSH: Develop on a Remote Server as if It Were Local
The Remote - SSH extension lets VS Code edit files, run terminals and debug on a remote Linux server. How it works, setup step by step, SSH config and keys, extensions and port forwarding, and fixes for the common connection problems.