Thursday, January 9, 2014

SSH login-time initializations

Beyond being secure, SSH is feature rich.
It seems that many features are generally overseen.
One quite useful feature is the login-time initializations capability.
One obvious application is to help in tracking SSH logins.
But many other useful actions can be performed.

The details are described at ssh(1) and sshd(1M) man pages.
Even so, I'd like to provide a summary on them on this post.

A fluxogram of the sshd daemon search sequence of each login-time initialization file shall provide a good introductory overview of the feature:



If the $HOME/.ssh/environment exists, it's the first to be read.
The PermitUserEnvironment in /etc/ssh/sshd_config must be set.
Obviously, the file ownership should be set according to the user account.
Its permission should be 600 and contents should be a combination of:
  • Empty lines.
  • Comments lines (started with #).
  • Assignments (name=value)
  
NOTE
The usage of $HOME/.ssh/environment is discouraged.
It may open security breaches as described in sshd_config(4).

Next, if the $HOME/.ssh/rc exists, then it's run with /bin/sh.
Its permission should be 600 and under ownership of the user.
According to sshd(1M) its contents should end with:

    if read proto cookie && [ -n "$DISPLAY" ]
    then
        if [ `echo $DISPLAY | cut -c1-10`  =  'localhost:' ]
        then
            # X11UseLocalhost=yes
            echo add unix:`echo $DISPLAY |
            cut -c11-` $proto $cookie
        else
            # X11UseLocalhost=no
            echo add $DISPLAY $proto $cookie
        fi | xauth -q -
    fi


If the $HOME/.ssh/rc is not found, then /etc/ssh/sshrc is run, if present.
According to sshd(1M) its contents should also end as in  $HOME/.ssh/rc.
The file ownership should be set to the root account.
Its permission should be 644.

That is, if any of $HOME/.ssh/rc or /etc/ssh/sshrc exist, then running xauth is necessary whenever X11 is involved. Of course, this is to add the X11 cookies accordingly.

Finally, if none of the login-time initialization files are found, xauth is run.
 
NOTE
It's critical to not toss out anything to the standard output.
Not observing this is a common source transfer failures with with scp.
For instance, an echo command on .bashrc will break an scp operation.

It's typically a good idea to detect right from the start whether or not the script is running under an interactive session or not. According to tty(1) final NOTES the most portable way of doing that is:

# test for stdin file descriptor
test -t 0 

if [ $? -eq 0 ]
then
    # interactive
    ;
else
    # non-interactive
    ;
fi


An alternative would be to suffix any eventual output to stdout by means of redirection such as 1>&2. But even this may still adversly provoke undesired and unexpected side-effects.
 
If one is running BASH, variations of the previous test could be:
 
if [[ -t 0 ]]; then ...; else ...; fi

if [[ $- =~ i ]]; then ...; else ...; fi