SSH Config Trick

Update2 : As I have been informed now, there has recently been support added for including external files in the ssh config. Refer https://man.openbsd.org/ssh_config#Include for details.

Update : Modified the script for more flexibility to allow easy modifications

I use SSH nearly every day to securely connect to remote servers. For simplifying managing remote server configurations & not having to remember IP addresses and other server specific details, I use ssh config. For those who aren’t familiar with this should read – http://nerderati.com/2011/03/17/simplify-your-life-with-an-ssh-config-file/

SSH configs are really neat, they allow for you to be able to logically name servers, provide configurations specific to servers (1)for instance if you use different ssh keys for different servers and ultimately make using ssh hassle free without having to provide / remember the server specific details while actually trying to connect to the servers manually. It saves a lot of time!

I keep all my system configurations, along with my ssh config within source control at https://github.com/dhruvasagar/dotfiles to be able to setup new systems very quickly (2)have had to do that on several occasions . Previously I used to symlink my sshconfig into ~/.ssh directory to setup the base ssh config with my personal server details. However, since I work as a consultant, I have to often modify it and add confidential server configurations of clients I work with.

The problem with that is often that leaves me with uncommitted changes which really annoyed me. I had been looking for ways to be able to segregate my ssh config into multiple files allowing me to keep confidential information in separate files yet not requiring any changes in my base config file to avoid this problem. Unfortunately there is no support for including / importing / referencing external files.

I came up with this simple solution :

Instead of symlinking, I created a simple shell script to generate my ssh config instead. Here is what it looks like :

action=${1:-'build'}
configs_dir=~/.ssh/configs

if [ "$action" = "build" ]; then
  cat ~/dotfiles/sshconfig $configs_dir/* > ~/.ssh/config 2>/dev/null
  echo 'sshconfig generated'
elif [ "$action" = "list" ]; then
  # sshconfig list to see list of client specific
  # configuration files present in configs folder
  # ls -l1 $configs_dir | tail -n+2 | awk '{print $9}'
  find "$configs_dir" -type f -exec basename {} \;
elif [ "$action" = "rm" ]; then
  # sshconfig rm <filename>
  file="$2"
  rm -f "$configs_dir/$file"
  $0 build
elif [ "$action" = "create" ]; then
  file="$2"
  $EDITOR "$configs_dir/$file"
else
  echo 'Usage: sshconfig build|list|rm|create <filename>'
fi

Now all I do is create separate files in ~/.ssh/configs directory to store ssh configs of different clients and simply re-run the above script to generate a new concatenated ssh config.

This way my base ssh config remains unchanged and I can safely create multiple client specific ssh config files in ~/.ssh/configs directory without worrying about accidentally committing them and leaking to public.

comments powered by Disqus