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 22

After this, the connection is just:

ssh app-prod

Use 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 30

Keep 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 yes

IdentitiesOnly 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_internal

Do 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 bastion

Now the private host is reached with:

ssh app-private

The 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 no

When 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_hosts

If 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-private

Verbose 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 bastion

Use 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.