Hero Image

Using a SSH config

OpenSSH is the de-facto SSH implementation. It allows easy and secure management of remote systems. Seasoned SysOps (like yours truly) are suckers for a SSH config file - it can save an incredible amount of time and effort.

Why you should use a config file

  • Shorter commands: Imagine being able to run ssh exq-masto rather than ssh -p 2222 -i ~/.ssh/exquisite h3artbl33d@exquisite.social.
  • Per-host identities: No need to remember which keypair you setup on a remote system or what username you need to use.
  • Security posture: Enforce strong ciphers and algorithms.
  • Jumphosts: Seamless ProxyJump/ProxyCommand

Getting started

You will need the .ssh directory and the .ssh/config file. On OpenBSD, the .ssh directory is within the profile skeleton - meaning that you very likely already have it in your homedir. This is different on a number of Linux distributions. You should be aware that permissions matter. ssh(1) ignores insecure files and directories. If you don't have the .ssh directory, it can be created the following way:

mkdir ~/.ssh
touch ~/.ssh/config
chmod 600 ~/.ssh/config
chmod 700 ~/.ssh

For the most secure setup, you will need to use keypairs, rather than a password. You should encrypt the private file, by entering a password when prompted for it. A keypair can be generated like this (for ed25519):

ssh-keygen -t ed25519 -a 500 -f ~/.ssh/test -C "Fill in a comment"

This key is then stored as ~/.ssh/test. You might want to generate a unique key per remote host, or per group of remote hosts.

Enforcing the use of keypairs and disabling passwords is done in sshd_config(5) on the remote machine/server. That is out of scope for this article, all the details can be found in the sshd_config manpage.

Config file anatomy

An SSH config file is comprised of hosts and options for them. Like this:

Host $name
    Option 1
    Option 2
    Option etc

Basic config file

Say you want to shorten the command you have to enter, connecting to a host on the local network. In this example, we'll shorten the name to local-masto, which will connect to the IP address 192.168.1.2, port 2222, username h3artbl33d and an unique keypair. That will give the following config:

Host local-masto
    HostName 192.168.1.2
    Port 2222
    User h3artbl33d
    IdentityFile ~/.ssh/local-mastodon

Adding those lines to the config file (~/.ssh/config) will mean that we can connect to this machine by entering the command ssh local-masto. Behind the scenes, it reads the config file, gets the options from there and connects to it.

If you did it correctly and applied the private key encryption, you will be prompted to enter the passphrase each time you connect. You can use ssh-add(1) to 'remember' the password for the duration of your session (until you logout from your computer, that is). See the corresponding manpage.

Full config file

Below you'll find the example of a full config file, which might offer some inspiration and insights. For different options or what the below ones do, please refer to the ssh_config manpage.

Host exq-masto
    HostName exquisite.social
    Port 2222
    Username h3artbl33d
    IdentityFile ~/.ssh/exquisite
    IdentitiesOnly yes
    Ciphers chacha20-poly1305@openssh.com
    KexAlgorithms mlkem768x25519-sha256,sntrup761x25519-sha512,sntrup761x25519-sha512@openssh.com
    HostkeyAlgorithms ssh-ed25519
    PubkeyAcceptedKeyTypes ssh-ed25519

Host local-masto
    HostName 172.16.42.2
    Port 1337

Host socks-proxy
    HostName 1.2.3.4
    Port 8081
    DynamicForward 8080

Host local-*
    User h3artbl33d
    IdentityFile ~/.ssh/localnet
    ProxyJump bastionhost

Host *
    ForwardAgent no
    Compression no
    IdentitiesOnly yes
    AddKeysToAgent yes
    ControlMaster auto
    ControlPath ~/.ssh/cm-%r@%h:%p
    ControlPersist 10m