The OpenSSH client and server applications are ubiquitous. Like many a software dev, I’m `ssh’ing all over the place. And you know what? I’ve put off learning the ins and outs of its configuration for far too long. I learned that a little bit of know-how can simplify my day-to-day use of SSH. That’s exactly why I’ve written this post to exemplify the configuration options I’m now using.
~/.ssh/config contains settings for a user’s SSH client.
System-wide SSH client settings are placed in
Settings here can be defined per-host.
General configuration options include aliases, SSH agent behavior, and jump hosts to name a few.
Different sections of a sample
~/.ssh/config are discussed in detail below.
Further documentation is available from the
This article assumes the reader is familiar with the basics of SSH and the syntax of SSH configuration files.
Normally, SSH consults the
~/.ssh/known_hosts when connecting to a host.
The known hosts file stores an identifying key for each host it has connected to previously.
As connections are made to new hosts, keys are registered in the user’s known hosts file.
Each time SSH establishes a connection to a known host, the key is checked, and the connection is aborted if it does not match.
When running multiple SSH servers from a single host, the key will fail to match whenever switching servers.
If you connect to various VMs through
localhost, SSH will throw an error whenever switching between machines.
yes is a convenient way to workaround by skipping host checking is skipped for
This does not skip host checking for the
The following section contains only one option which applies to
As an example,
vm_host represents a computer dedicated for running multiple virtual machines.
Host vm_host Hostname vm_host.local
Hostname, indicates the true hostname of this host which means
vm_host is really just an alias.
vm_host can be used on the command-line instead of having to type out
Next, several configuration options are given for the hosts
Host vm1 HostKeyAlias vm1.localhost Host vm2 HostKeyAlias vm2.localhost Host vm1 vm2 Hostname localhost Port 9001 ProxyJump vm_host
Starting with the shared configuration options, the
Port options indicate that both hosts are available on the port
9001 at the reserved
vm2 use the same hostname and port, they can’t both be available simultaneously.
In this scenario, either virtual machine
vm2 would be available at any one time.
ProxyJump key is used here with one intermediate host,
vm_host, defined previously.
This means that the SSH connection will connect to the
localhost address on
So, instead of executing
ssh vm_host followed by
ssh -p 9001 localhost to access either of the VMs, use just one command either
ssh vm1 or
The individual host blocks provide a distinct
HostKeyAlias for each host.
This is critical because these virtual machines will have different host keys but share the same hostname
When checking the known hosts file, instead of looking for an entry for
localhost, SSH will look for an entry for the value provided to
The configuration line
NoHostAuthenticationForLocalhost yes from the beginning of the file only works for the
localhost address on the current machine.
In other words, this option has no effect when connecting to
localhost on any other machine, including a jump host.
According to the
HostKeyAlias should be used for handling multiple servers running on a single host.
The following configuration accommodates the variability of the IP address associated with a given hostname on networks using multicast DNS.
Host *.local CheckHostIP no
It might be worth setting this option for all users in the system-wide configuration file
The last section contains a few defaults for all hosts, which boil down to a few quality-of-life improvements.
Host * AddKeysToAgent yes IdentitiesOnly yes IdentityFile ~/.ssh/id_rsa_catalina-build.pub PreferredAuthentications publickey,keyboard-interactive,password,gssapi-with-mic,hostbased ServerAliveInterval 90 ServerAliveCountMax 4 # Specific to macOS UseKeychain yes
The meanings of these options are described one-by-one below.
Automatically registers SSH keys with the SSH Agent as they are loaded.
Provides the path to an authentication identity. The private key file is often provided for this option, but providing the public key works when storing the private key itself directly within KeePassXC..
Sets the order of preference for the various authentication methods. Here, public key cryptography is preferred first because I use this most often.
The amount of time in seconds between sending successive SSH keepalives to the SSH server. Setting this option enables SSH server keepalives, which are helpful for keeping existing SSH connections open. A value of 90 here results in a keepalive being sent every 90 seconds.
The number of successive keepalives the SSH server must fail to respond to before terminating the connection.
With a max count of four and a
ServerAliveInterval of 90 seconds, the session will be terminated after six minutes where no response from the SSH server is received.
On macOS, this allows storing and accessing keys from the user’s Keychain so they are automatically available after logging on.
It is possible to forward the SSH Agent to avoid typing passwords so much.
You can forward the SSH Agent by setting
yes, shown in the following example.
Host server ForwardAgent yes
Be wary when using agent forwarding. Those with administrative access on the forwarded machine will be able to use the keys from your agent to authenticate as you.
The SSH server is configured in
I explain my typical server options here.
ClientAliveInterval 90 ClientAliveCountMax 4
The amount of time in seconds between sending successive SSH keepalives to the SSH client. Setting this option enables SSH client keepalives, which are helpful for keeping existing SSH connections open. A value of 90 here results in a keepalive being sent every 90 seconds.
The number of successive keepalives an SSH client must fail to respond to before terminating the connection.
With a max count of four and a
ClientAliveInterval of 90 seconds, the session will be terminated after six minutes where no response from the SSH client is received.
That was a bit of configuration. Assuming I didn’t just cover topics you already knew, you should have a better understanding of SSH and its configuration options. Hopefully you’ll be able to capitalize on this knowledge by simplifying your SSH work flow. If you’re interested in smoothing out even more wrinkles in your SSH use, you might checkout the Mosh project.