Multiple SSH client configuration files

January 13, 2013

Having many hosts managed through your ${HOME}/.ssh/config file can quickly become a wildly beast of a configuration file to maintain with each host containing a few SSH client options.

Host                    web01
HostName                web01.prod.example.com
User                    rene
Compression             yes
ForwardAgent            no
IdentityFile            ~/.ssh/production
ForwardX11              no

OpenSSH won’t allow you to split out the configuration in multiple files, such as ~/.ssh/config.dev, ~/.ssh/config.production and ~/.ssh/config.test and then include them within your main SSH configuration file ~/.ssh/config with a directive such as Include like Apache configuration allows you.

A bug report has been logged with the OpenSSH team though this has got no traction yet.

With a bash alias and a simple ssh client wrapper script, you can create a work around that will allow you to split up SSH client configuration into several files.

First, create the SSH client wrapper. I drop this file into ~/bin/ssh and ensure it is executable.

#!/bin/bash

ssh() {
    TMPDIR=~/tmp
    case "$(uname -s)" in
        Linux)
            tmp_fifo=$(mktemp -u --suffix=._ssh_fifo)
            ;;
        Darwin)
            tmp_fifo=$(mktemp -u -t ._ssh_fifo)
            ;;
        *)
            echo 'unsupported OS'
            exit
            ;;
    esac

    # cleanup first
    rm ~/tmp/._ssh_fifo* 2>/dev/null

    mkfifo "$tmp_fifo"
    cat ~/.ssh/config ~/.ssh/config.* >"$tmp_fifo" 2>/dev/null &
    /usr/bin/ssh -F "$tmp_fifo" "$@"
    rm "$tmp_fifo"
}

ssh $*

The SSH client wrapper creates a FIFO file consisting of all my ~/.ssh/config* files concatenated. The wrapper then calls the proper SSH client binary passing the FIFO file as the alternative configuration file.

So my shell is forced to call this wrapper, I create a simple bash alias in ~/.bash_profile

alias ssh='~/bin/ssh'

Now everytime ssh is called, all configuration files in ~/.ssh/config* are available allowing me to split out my SSH hosts into their own separate file.

This solution came about from the answer provided by estani on the superuser.com question “Is there a way for one SSH config file to include another one?“.

About Rene Cunningham

An expert in the Linux Infrastructure space, Rene is a passionate Systems Engineer with a strong background in Open Source Software Stacks and large scale infrastructure. Based in Melbourne, Australia, Rene works on a highly experienced, distributed team of professional System Administrators at The Linux Foundation.