The ~/.ssh/config file is the most underused tool in a developer's toolkit. Most people type out full SSH commands every time. Once you learn these tricks, you'll never go back.
1. Basic Host Aliases
Stop typing ssh -i ~/.ssh/key user@192.168.1.50 -p 2222. Add this to your config:
Host myserver
HostName 192.168.1.50
User deploy
Port 2222
IdentityFile ~/.ssh/deploy_key
Now just type ssh myserver. This also works with scp, sftp, and rsync.
2. Wildcard Defaults
Set defaults for all connections:
Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_ed25519
ServerAliveInterval 60
ServerAliveCountMax 3
This keeps connections alive, adds keys to the agent automatically, and stores passphrases in macOS Keychain.
3. Jump Hosts (ProxyJump)
Access servers behind a bastion/jump host in one command:
Host bastion
HostName bastion.company.com
User admin
Host internal-db
HostName 10.0.1.20
User dbadmin
ProxyJump bastion
Now ssh internal-db automatically jumps through the bastion. No more ssh -J flags.
4. Port Forwarding Made Permanent
Instead of remembering -L flags:
Host dev-server
HostName dev.company.com
User dev
LocalForward 3000 localhost:3000
LocalForward 5432 localhost:5432
LocalForward 6379 localhost:6379
Every time you ssh dev-server, your local ports automatically forward to the remote services.
5. Agent Forwarding
Use your local SSH keys on the remote server (e.g., for git operations):
Host dev
HostName dev.company.com
ForwardAgent yes
Now you can git pull on the remote server using your local GitHub key. Warning: only enable this for servers you trust.
6. Different Keys for Different Services
Host github.com
IdentityFile ~/.ssh/github_ed25519
Host gitlab.company.com
IdentityFile ~/.ssh/work_ed25519
Host *.internal.company.com
IdentityFile ~/.ssh/work_ed25519
User admin
Wildcards (*) let you apply settings to multiple hosts at once.
7. Keep Connections Alive
Tired of "broken pipe" disconnections?
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
TCPKeepAlive yes
This sends a keepalive packet every 60 seconds and disconnects only after 3 missed responses.
8. Connection Multiplexing
Reuse a single SSH connection for multiple sessions:
Host *
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 600
Create the socket directory first: mkdir -p ~/.ssh/sockets
The first connection authenticates normally. Every subsequent connection to the same host reuses it — instant connections with zero auth overhead.
9. Compression for Slow Networks
Host slow-server
HostName server.faraway.com
Compression yes
Enables compression on the SSH tunnel. Makes a noticeable difference on high-latency or low-bandwidth connections.
10. Custom Commands on Connect
Run a command immediately after connecting:
Host dev
HostName dev.company.com
RemoteCommand cd /var/www/app && exec $SHELL -l
RequestTTY yes
This drops you directly into your project directory every time.
Bonus: Organize Your Config
As your config grows, keep it organized with comments:
# ── Defaults ──
Host *
AddKeysToAgent yes
UseKeychain yes
ServerAliveInterval 60
# ── Work ──
Host bastion
HostName bastion.company.com
# ── Personal ──
Host homelab
HostName 192.168.1.10
Or split it into multiple files using Include:
Include ~/.ssh/config.d/*
Managing All This Visually
If you have dozens of servers, managing a text config file gets unwieldy. Tools like Pluto Door let you manage connections through a visual interface while still respecting your SSH config — so you get the convenience of a GUI with the power of your config file.
The config file is your multiplier. Spend 30 minutes setting it up, save hours every month.
