Typing ssh -i ~/.ssh/client_key -p 2222 deploy@203.0.113.10 every time is slow and easy to get wrong. The SSH client config file lets you give each server a short name and store its address, user, port and key once. After that, ssh web is all you type, and the same shortcut works for scp, sftp, rsync, Git and VS Code.
Before you start
- The OpenSSH client, which is built into Linux, macOS and Windows 10 and 11. See Use the built-in OpenSSH client in Windows Terminal on Windows.
- The connection details for each server: IP, SSH port, username and key file.
Where the file lives
The per-user config file is:
- Linux and macOS:
~/.ssh/config - Windows:
C:\Users\<you>\.ssh\config(no file extension)
Create it if it does not exist. On Linux and macOS:
mkdir -p ~/.ssh && chmod 700 ~/.ssh
touch ~/.ssh/config && chmod 600 ~/.ssh/configOn Windows, create it in Notepad and make sure it is not saved as config.txt. In the save dialog, set Save as type to All files.
Note: SSH refuses to use a config file that other users can write to. Keep it readable and writable only by you.
Your first Host entry
Each block starts with Host followed by the short name you want to type. The indented lines below it apply to that name:
Host web
HostName 203.0.113.10
User deploy
Port 22
IdentityFile ~/.ssh/id_ed25519Host: the alias you type. It can be anything without spaces.HostName: the real IP address or domain name.User: the login name on the server.Port: the SSH port. Leave it out for the default22.IdentityFile: the private key to use.~works on Windows too.
Now connect with:
ssh webThe alias also works with other tools:
scp site.tar.gz web:/home/deploy/
rsync -av ./public/ web:/var/www/example.com/
sftp webSeveral servers
Add one block per server. A blank line between blocks keeps it readable:
Host web
HostName 203.0.113.10
User deploy
Host db
HostName 198.51.100.20
User admin
Port 2222
IdentityFile ~/.ssh/db_ed25519A Host line can list several aliases, for example Host web web1 shop.
Wildcards and shared defaults
Patterns let one block apply to many hosts:
*matches any text,?matches one character.!excludes a pattern.
Host *.example.com
User deploy
IdentityFile ~/.ssh/work_ed25519
Host *
ServerAliveInterval 60
ServerAliveCountMax 3Order matters. For each setting, SSH uses the first value it finds, reading the file top to bottom. Put specific hosts first and the general Host * block at the end, or its values will win over your specific ones.
ServerAliveInterval 60 sends a small keepalive every minute, which stops idle sessions being dropped by routers and firewalls.
IdentitiesOnly: stop "too many authentication failures"
If you have several keys loaded in an SSH agent, the client may offer every one of them before the one in IdentityFile. Servers usually allow only a few attempts, so you get:
Received disconnect from 203.0.113.10 port 22:2: Too many authentication failuresIdentitiesOnly yes tells SSH to offer only the key named in the config:
Host db
HostName 198.51.100.20
User admin
IdentityFile ~/.ssh/db_ed25519
IdentitiesOnly yesFor more on juggling keys, see Manage several SSH keys.
Other useful options
LocalForward 8080 127.0.0.1:80: open a tunnel every time you connect. See SSH local port forwarding.ProxyJump bastion: reach a server through another one.Compression yes: can help on slow links.Include ~/.ssh/config.d/*: split a long config into several files. Put theIncludeline near the top.
Check the full list with man ssh_config.
Check it works
Ask SSH to show the final settings it would use for an alias, without connecting:
ssh -G web | grep -E '^(hostname|user|port|identityfile) 'You should see the values from your block. Then connect with verbose output to confirm the right key is used:
ssh -v webLook for a line like Offering public key: /home/you/.ssh/id_ed25519.
Troubleshooting
Bad owner or permissions on ~/.ssh/config: runchmod 600 ~/.ssh/configon Linux or macOS. On Windows, remove other users from the file's Properties → Security list.Could not resolve hostname web: the alias is not being read. Check the file name (no.txt), its location, and spelling of theHostline.- The wrong user or port is used: an earlier block, often
Host *, set it first. Move general blocks to the end. Bad configuration optionon one machine only: some options are platform-specific, such asUseKeychainon macOS. AddIgnoreUnknown UseKeychainat the top of the file to share it across systems.
Next steps
- Edit server files in your editor using your aliases: VS Code Remote-SSH.
