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-mastorather thanssh -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