The SSH config file at ~/.ssh/config defines per-host settings: Host alias, hostname, user, port, identity file, jump hosts. The team that uses this config avoids typing ssh -i ~/.ssh/key -p 2222 user@hostname every time. The team that has 5+ hosts has saved minutes per day.
Table of contents
- The config file location
- Basic structure
- Common directives
- ProxyJump for bastion access
- Wildcard hosts
- Include other files
- Common pitfalls
- FAQ
The config file location
~/.ssh/config is the per-user file. /etc/ssh/ssh_config is the system-wide file (rarely used). The team that uses the per-user file has per-user settings; the team that uses the system file has shared settings across all users.
Basic structure
Host github.com
User git
IdentityFile ~/.ssh/github_ed25519
Host gitlab.com
User git
IdentityFile ~/.ssh/gitlab_ed25519
Host myserver
HostName 203.0.113.42
User deploy
Port 2222
IdentityFile ~/.ssh/server_ed25519
IdentitiesOnly yes
After this, ssh github.com, ssh gitlab.com, ssh myserver use the right config automatically.
Common directives
- Host: alias pattern (
*is wildcard). - HostName: real hostname or IP.
- User: SSH user.
- Port: non-standard port.
- IdentityFile: private key path.
- IdentitiesOnly yes: only send the listed key, ignore agent.
- ProxyJump: jump host for accessing through bastion.
- ForwardAgent yes: forward SSH agent.
- ServerAliveInterval 60: keepalive every 60s.
- Compression yes: enable compression (for slow links).
ProxyJump for bastion access
Access internal hosts through a bastion:
Host bastion
HostName bastion.example.com
User myuser
Host db.internal
HostName db-1.internal.example.com
User admin
ProxyJump bastion
ssh db.internal connects to bastion first, then through to db-1.internal. The team that uses ProxyJump has transparent bastion access.
Wildcard hosts
Host *.internal.example.com
User admin
IdentityFile ~/.ssh/internal_ed25519
IdentitiesOnly yes
Host *.staging
User deploy
ProxyJump bastion
The team that uses wildcards applies the right config to many hosts.
Include other files
Include ~/.ssh/config.d/*
The team that splits config into per-tool files (config.d/github, config.d/work-servers) has organized config.
Common pitfalls
- Wrong
Hostpattern - matches a different host. - Forgetting
IdentitiesOnly yes- sends all agent keys. - Permissive
Host *block - applies to too many hosts. - Permissions:
~/.ssh/configmust be600or644(SSH refuses otherwise).
FAQ
Do I need a config file?
Not strictly. The team that has 1-2 hosts types flags each time. The team that has 5+ hosts uses a config file.
What permissions should ~/.ssh/config have?
600 (or 644). SSH refuses to read the file if it’s group-writable or world-writable.
Can I have multiple Host blocks for the same alias?
No - the first matching Host block wins. The team that uses specific aliases (github.com, gitlab.com) has one block per alias.
Why is my IdentityFile not being used?
Either IdentitiesOnly no (default) and agent has different keys, or wrong path. The team that uses IdentitiesOnly yes forces the listed key.
Can I share config across users?
Yes - put common config in /etc/ssh/ssh_config (system-wide) and per-user overrides in ~/.ssh/config. Per-user takes precedence.
If you are sizing the infrastructure for the kind of project this post covers, the RunxBuild hosting calculator is the right place to model the line items. The compute, the memory, the storage, the bandwidth, the database - each one is a separate number, and the team’s mental model for the platform is the sum of those numbers. The RunxBuild dashboard is where the team sees the actual usage in one place.
Useful related references: