Skip to main content

Config

To start with, SSH is simple: just ssh username@server and type in your password, and you're on the server's commandline.

To improve security a lot, you'll want to use keypairs - it's a bit more advanced but still straightforward:
- generate a keypair with ssh-keygen, accept the defaults
- copy the public key to the authorized_hosts file on the server - the tool ssh-copy-id can do this for you
- then log into the server with the same command ssh username@server, it should use the key instead of ask for a password.

Basic Config

When dealing with multiple servers, multiple users, multiple keypairs and maybe even a jumphost/bastion for security, it'll be annoying to type out the entire ssh command at some point (example: ssh -p 2222 -i ~/.ssh/id_workkey username2@server3 )

Especially if your DNS is not perfectly set up for ssh, you might also have to type hostnames as server3.work.domain.

To make this easier, you can do SSH config entries in ~/.ssh/config like so:

Host myserver
  HostName server3.work.domain
  User myworkuser
  IdentityFile ~/.ssh/id_workkey

So when you type "ssh myserver" it actually uses these settings configured in ssh config.

If you have a jumphost, you'll also want to use the ProxyJump option, for example:
Host bastion
  HostName bastion.work.domain
  User myworkuser

Host myserver
  HostName myserver.work.domain
  User myworkuser
  ProxyJump bastion

Advanced Config

Match blocks!
If you have multiple servers, and want short names for each of them, but to apply several settings to ALL of them, you might come up with something like this:
Host nickname
  HostName myserver.work.domain

Host otherone
  HostName myserver2.work.domain

Host *.work.domain
  User myworkuser
  Port 2222
  ProxyJump bastion


However, this will NOT work because once SSH finds a "Host" block matching what you typed, it stops parsing any other Host blocks.
What you want is a Match block, these still get parsed:

Match host *.work.domain
  User myworkuser
  <etc>

Also - the ORDER is IMPORTANT. putting the match block first will match nothing, put the Host blocks first so their HostName properties gets rewritten to the full name, and THEN match on the work.domain.

Advanceder Config

Localnetwork!

if you want your SSH configuration to change depending on what network you're in, online sources still recommend some "exec" hack to find that info (making a match block run some command to figure out the network).
SSH from 9.4 (released august 2023) supports a "match localnetwork" setting that can, for example, make you use a different jump host when outside of the work network.

SSH Multiplexing / Control Master options

If you are somewhat paranoid and want to use a FIDO2 hardware security key for your ssh, you might have noticed the connection takes a bit longer to establish.
In my case, connecting to Forgejo took 2.5 seconds, which annoyed me immediately (this happens on every git fetch/pull/push i make).
To speed things up, SSH can open a connection once, and keep it open for a specified time, allowing subsequent commands connection to the same host to use the established one.

Here's the config i use for git, making it 10 times faster on subsequent connections. Ensure the directory in ControlPath exists!

Host forge.shiny.space
    User git
    Port 22
    IdentityFile ~/.ssh/id_ed25519_sk
    ProxyJump none
    ControlMaster auto
    ControlPath ~/.ssh/cm_socket/%r@%h:%p
    ControlPersist 10m