Ssh config file with multiple ssh versions

openssh

I really like the "Match" keyword that was added to OpenSSH around version 6.5, and I make heavy use of it in my .ssh/config file.

But that config file is in my NFS-ed home, and so is referenced when I log in to any of several computers in our LAN.

And many of these computers still have ssh versions older than 6.5.

So if I am at one of these computers, and try to ssh (or scp/rsync), I get a complaint that Match is a 'Bad configuration option', and ssh terminates.

I'd much rather ssh proceed without the customizations in my config file, than not work at all. But I can't seem to find any way to write the config file so that newer versions can make use of newer options, but older version work without them. If anyone has any bright ideas, please share.

I have managed to work out that I can do "ssh -F /dev/null" with older versions. I just find it irksome that that is necessary. Would prefer an "automatic" solution.

Best Answer

Unfortunately, it is not possible. Some applications, where newer versions have introduced new optional syntaxes, have resorted to having "conditional compilation" comments, a notable example is MySQL.

But thankfully OpenSSH is not at that stage yet.

Possible solution: If your entire home directory is mounted in different operating systems, you can add a script to your .profile that checks the version of SSH and if it is not sufficient to load your configuration file, aliases ssh to ssh -F /dev/null. For example:

if [ "$(bc -l <<<"$(ssh -V 2> >(sed 's,^[^0-9]*,,;s,[^\.0-9].*,,')) < 6.5")" == 1 ]
then
    alias ssh="/usr/bin/ssh -F/dev/null"
fi

Alternatively, as per @derobert comment, an alias may not be enough for some use cases, such as using rsync or other applications that use OpenSSH as a transport and call the ssh program directly (without letting the shell resolve the alias). If this is indeed also an issue, you might want to create a script called ssh in your local bin directory (usually ~/bin or ~/.local/bin). When an application resolves the path to the ssh binary, it should see your local bin directory early in the path and run your script, which will then perform the required logic.

Maybe something like this:

#!/bin/bash
if [ "$(bc -l <<<"$(ssh -V 2> >(sed 's,^[^0-9]*,,;s,[^\.0-9].*,,')) < 6.5")" == 1 ]
then
    /usr/bin/ssh -F/dev/null "$@"
else
    /usr/bin/ssh "$@"
fi