You’re probably just typing ssh long.server.name.with.a.very.long.domain.suffix over and over again, and it’s a pain. SSH host aliases, defined in your ~/.ssh/config file, let you use short, memorable names instead of those monstrous connection strings.

Let’s say you have a server at app.production.eu-west-1.aws.mycompany.internal that you access via SSH on port 2222 with the username deployer. Instead of typing ssh deployer@app.production.eu-west-1.aws.mycompany.internal -p 2222 every time, you can set up an alias.

Here’s how it looks in your ~/.ssh/config file:

Host prod-app
    HostName app.production.eu-west-1.aws.mycompany.internal
    User deployer
    Port 2222
    IdentityFile ~/.ssh/id_rsa_prod

Now, you can simply type ssh prod-app and it will automatically connect using the specified HostName, User, Port, and even use a specific IdentityFile for authentication.

This isn’t just about convenience; it’s about managing complexity. Imagine you have dozens of servers, each with different usernames, ports, or even jump hosts. Without aliases, your command line quickly becomes a mess, and it’s easy to make mistakes.

Let’s break down what’s happening under the hood when you type ssh prod-app.

  1. Lookup: The SSH client reads your ~/.ssh/config file. It looks for a Host entry that matches prod-app.
  2. Configuration Loading: Once it finds the Host prod-app block, it loads all the directives within that block: HostName, User, Port, IdentityFile.
  3. Connection Establishment: The SSH client then uses these loaded configurations to establish the connection. It will attempt to connect to app.production.eu-west-1.aws.mycompany.internal on port 2222, using the username deployer, and authenticating with the key ~/.ssh/id_rsa_prod.

The power comes from the flexibility of the Host directive. It accepts wildcards and can even match multiple hosts.

For example, you can group similar hosts:

Host *.dev.internal
    User devuser
    ForwardAgent yes

With this, any host ending in .dev.internal (like web.dev.internal or db.dev.internal) will automatically use devuser and forward your SSH agent.

You can also specify a default User for all hosts:

Host *
    User defaultuser
    ServerAliveInterval 60

This sets defaultuser as the username for any host you connect to, unless overridden by a more specific Host entry. ServerAliveInterval 60 sends a "keep-alive" packet every 60 seconds to prevent idle connections from being closed by firewalls or network devices.

A really useful directive is ProxyJump, which simplifies connecting through bastion hosts or jump boxes. Suppose you need to reach a server internal-db that’s only accessible from a bastion host bastion.mycompany.com.

Host internal-db
    HostName 10.0.1.50
    User dbadmin
    ProxyJump bastion.mycompany.com

Host bastion.mycompany.com
    HostName bastion.mycompany.com
    User sysadmin
    IdentityFile ~/.ssh/id_rsa_bastion

Now, ssh internal-db will first connect to bastion.mycompany.com (using its specific configuration, including a dedicated key), and then establish a tunnel through that bastion to reach internal-db. You don’t need to explicitly use ssh -J or ssh -W commands; the ProxyJump directive handles it all.

The order of Host entries matters. SSH processes the configuration file from top to bottom, and the first matching Host entry is used. If you have a general Host * entry, make sure more specific entries appear before it.

# This is more specific, so it should come first
Host prod-app
    HostName app.production.eu-west-1.aws.mycompany.internal
    User deployer
    Port 2222

# This is a general catch-all, should come last
Host *
    User defaultuser
    ForwardAgent no

If prod-app were listed after Host *, the Host * entry would match first, and you’d end up trying to connect as defaultuser to app.production.eu-west-1.aws.mycompany.internal on the default port 22, which is not what you want.

A common pitfall is forgetting to restart your SSH agent or re-authenticate if you change IdentityFile directives, especially if you’ve set IdentitiesOnly yes. The IdentitiesOnly yes directive forces SSH to only use the identity files explicitly listed in the config for that host, preventing it from trying default keys like id_rsa or id_ed25519. This is crucial for security when you have multiple keys.

The next thing you’ll likely want to explore is SSH multiplexing, which lets you reuse an existing SSH connection for multiple new connections, significantly speeding up repeated access to the same host.

Want structured learning?

Take the full Ssh course →