Visually Distinguish Remote ssh Sessions

When administering resources it's often convenient to use the command-line.  For security it's necessary to use an encrypted mechanism - almost always ssh.  However, since once connected, one terminal window looks much like another, there's a significant risk that a command intended to be run on one server gets run on the wrong one!  How can you protect against this and still work efficiently?

One way is to have each ssh session clearly, probably visually different from each other.  This can be automated in Unix based systems.

Use xtermcontrol

There are various ways to control aspects of your terminal session.  Simply printing to the terminal various escape codes can change many aspects of the terminal - including color, but also title and so on.  However, to conveniently and specifically make fine-grained changes, xtermcontrol is very effective and available across many platforms.  It is preferable to setterm because it gives more fine grained control - for instance over the choice of colours - and also setterm can be inconsistent between platforms.

Getting xtermcontrol

Source code can be downloaded from the xtermcontrol homepage but most Unix systems (including Mac) can use their package managers to install it - see the homepage

Configuring ssh Colouring under bash

The following is specific to bash, however obvious variants should work with other shells such as ksh, fish and others.

ssh Config

ssh provides a convenient method to execute commands depending on which server is being accessed - this is what we need.  These commands must be placed in the .ssh/config file.  The particular functionality we will use are Host and LocalCommand.  They're used as follows:

Host <remote hostname or IP address>
  User <username on remote host>
  LocalCommand <command to execute locally after connection>
Host ...
  User ...
  LocalCommand ...
...

For our purposes a .ssh/config file may look like this:

Host 12.34.56.178
  User ubuntu
  LocalCommand xtermcontrol --bg '#600'
Host myhost.tld
  User admin
  LocalCommand xtermcontrol --bg '#431'

This just sets the background colour (bg) though other xtermcontrol options could also be used.   With this .ssh/config in place, when a user does ssh ubuntu@12.34.56.178 or ssh admin@myhost.tld (assuming the appropriate ssh keys are in place) the background in the first case will be a bright red (#600) and in the second a deep green (#431):


Turning It Off

The problem with this scheme is that once the terminal is exited, the coloring remains.  This is counterproductive since the user may assume incorrectly that they are still connected to the host.
The means to solve this issue is aliases.

.bash_aliases

An alias is simply another name for a program.  It's usually used to avoid having to type long command-lines - a very common example is ll which is often aliased to ls -alF.  In our case however, we will first create a bash function and then use it in the alias to revert the changes from .ssh/config.  To make it work add a section like this (adding the file if not already present) to .bash_aliases in your home directory:

function ssh_alias() {
  FG=$(xtermcontrol --get-fg)
  BG=$(xtermcontrol --get-bg)
  $(which ssh) "$@"
  xtermcontrol --fg="$FG"
  xtermcontrol --bg="$BG"
}

alias ssh=ssh_alias

The way this works is:
  1. When bash starts it executes various shell scripts in a particular order (including, e.g. .bashrc).  One of these is .bash_aliases.  Because it's a bash script, all the facilities of bash, including function declarations are possible.  Therefore we can use the line
    function ssh_alias() { ...

    which introduces a function called ssh_alias.  
  2. It first, with FG=$(xtermcontrol --get-fg), records the current foreground colour and then does similarly with the background colour with BG=$(xtermcontrol --get-bg).  
  3. $(which ssh) determines the (unaliased) ssh command name and then calls it, passing to it the set of arguments with which the ssh_alias function was called using the special bash variable $@.  If this use of ssh was to connect to one of the hosts which have a Host directive in the .ssh/config, the commands there adjusting terminal configuration will have been executed (probably changing the background colour).   It will then connect to the required host.  While it stays connected, that ssh command won't return.  
  4. When the work on the remote host is finished and that session is exited, the final two lines are run: xtermcontrol --fg="$FG" sets the foreground colour to the colour that was recorded before ssh was run, thereby reverting that to the original - and similarly for the background colour.
    If you use any xtermcontrol functionality other than changing the background or text (foreground) colours, then you will likely need to add xtermcontrol lines to the ssh_alias() function - both before the $(which ssh) "$@" line to record the original state and after to revert it to the recorded state.
  5. The line
    alias ssh=ssh_alias

    now causes ssh, when entered in the command-line to call the ssh_alias function rather than the ssh executable command, therefore transparently implementing the required effect.

It's a roundabout way of getting the result - but it works.

Comments

Popular posts from this blog

TEX on Linux

Freeze Changing HTML Element in Chrome Developer Tools

Change Unix terminal Title