SSH config: aliases, keys and jump hosts
OpenSSH client configuration turns long, error-prone ssh commands into named hosts with explicit users, keys and routing. A small ~/.ssh/config file is easier to review than a she…
OpenSSH client configuration turns long, error-prone ssh commands into named hosts with explicit users, keys and routing. A small ~/.ssh/config file is easier to review than a shell history full of flags.
Put repeated options in host blocks
The OpenSSH client reads its per-user configuration from ~/.ssh/config. The file is made of Host sections. Each section applies to host patterns that match the name used on the command line.
Host app-prod
HostName app-01.example.com
User deploy
Port 22After this, the connection is just:
ssh app-prodUse aliases for intent, not only for hostnames. app-prod is usually more useful than app-01, because it tells the reader why the connection exists.
Keep defaults separate from specific hosts
Use a wildcard Host * section for safe defaults. For each option, ssh uses the first value it obtains, so put the wildcard section after more specific entries when you rely on that behaviour.
Host app-prod
HostName app-01.example.com
User deploy
IdentityFile ~/.ssh/id_ed25519_app_prod
Host *
AddKeysToAgent no
IdentitiesOnly yes
ServerAliveInterval 30Keep defaults boring. A global option affects every connection, including Git remotes and one-off diagnostics.
Use explicit keys
IdentityFile specifies a file from which the client reads an authentication identity. Use one key per trust boundary when that makes access review easier.
Host git-internal
HostName git.example.com
User git
IdentityFile ~/.ssh/id_ed25519_git_internal
IdentitiesOnly yesIdentitiesOnly yes tells the client to use only the configured identity files, even when an agent offers more identities. This avoids surprising key attempts, and it can prevent authentication failures on servers that limit the number of tries.
Set strict file permissions for private keys and the config file.
chmod 700 ~/.ssh
chmod 600 ~/.ssh/config ~/.ssh/id_ed25519_git_internalDo not commit private keys. Do not paste private keys into issue trackers, chat or deployment logs.
Use jump hosts with ProxyJump
A jump host is an intermediate SSH server used to reach another host. OpenSSH supports this with ProxyJump, which is the config-file form of the -J command line option. The client first connects to the jump host, then establishes a forwarded connection to the final target.
Host bastion
HostName bastion.example.com
User lee
IdentityFile ~/.ssh/id_ed25519_bastion
Host app-private
HostName 10.0.12.34
User deploy
IdentityFile ~/.ssh/id_ed25519_app
ProxyJump bastionNow the private host is reached with:
ssh app-privateThe configuration for the target connection stays on the originating machine. Do not assume the jump host's local SSH config will be used for the final target.
Avoid agent forwarding by default
Agent forwarding can be useful, but it exposes the local agent to the remote environment. ForwardAgent is off by default; keep it that way unless a specific workflow requires it and the remote host is trusted.
Host *
ForwardAgent noWhen a workflow needs access from a remote host to another system, prefer alternatives such as ProxyJump, a limited key deployed for that environment, or short-lived credentials.
Manage host key checking deliberately
Host keys protect against connecting to the wrong server. Avoid disabling host key checking globally.
Host *
StrictHostKeyChecking ask
UserKnownHostsFile ~/.ssh/known_hostsIf infrastructure rebuilds hosts often, solve host key rotation in provisioning or known-host management. Do not normalise StrictHostKeyChecking no across all hosts.
Debug the effective configuration
Use ssh -G to print the configuration that OpenSSH would use after evaluating Host and Match blocks.
ssh -G app-private | grep -E '^(hostname|user|identityfile|proxyjump) 'Use verbose mode for connection diagnostics. Repeat -v up to three times for more detail.
ssh -vvv app-privateVerbose output can include paths, usernames and key information. Treat logs from failed SSH sessions as sensitive when sharing them.
Keep the file maintainable
Group hosts by environment or purpose. Add comments only for facts that are not obvious from the options. Remove aliases when systems are decommissioned.
# Production application hosts are reached through the bastion.
Host prod-*
User deploy
ProxyJump bastionUse pattern blocks carefully. A broad pattern such as Host *prod* may match more than intended.
Conclusion
A good SSH config makes secure connections boring. Use named aliases, explicit users, explicit identity files and ProxyJump for private networks. Keep global defaults conservative, leave agent forwarding off by default and use ssh -G when the effective configuration is unclear.
