agents, putty, shared home and Windows

Table of Contents

On customer site, I am quite often forced to use a Windows machine to access the Linux boxes I work on. This means I will not have an ssh-agent (nor a gpg-agent) running on the machine I’m sitting at (the Win box) and the Linux boxes I access via putty tend to have shared home directories.

Long story short, I need one agent per Linux box taking into account that I may have more than one login shell to the Linux box (i.e. multiple putty windows) and config files including the hostname.

Below you will find the .bashrc and .bash_profile I use. If you know of more elegant ways to do this, then email me.

Just to be crystal clear, you only need a hack like this when the desktop you log into (and then ssh from) is not runningn an agent. On a civilised Linux desktop none of this hackery is needed. But well, a lot of customers force a Windows machine on me from which I ssh to a datacenter.

the used .bash_profile

# .bash_profile
# read by login shell

echo "running your .bash_profile"


# User specific environment and startup programs

if  ! echo $PATH | /bin/grep -q "/sbin" ; then
        PATH=$PATH:/sbin
fi
if  ! echo $PATH | /bin/grep -q "/usr/sbin" ; then
        PATH=$PATH:/usr/sbin
fi
if  ! echo $PATH | /bin/grep -q "$HOME/sbin" ; then
        PATH=$HOME/sbin:$PATH
fi
if  ! echo $PATH | /bin/grep -q "$HOME/bin" ; then
        PATH=$HOME/bin:$PATH
fi

export PATH

# set my favourite editor
EDITOR="/usr/bin/vim"
export EDITOR

unset USERNAME

# gpg-agent
# https://wiki.fsfe.org/Fellows/stiell/fedora_cryptocard_ssh_setup
# http://blog.schiessle.org/2009/05/12/fedora-and-gpg-agent/
# pcfe, 2010-09-13
GAIFILE=$HOME/.gpg-agent-info-${HOSTNAME}
if test -f "${GAIFILE}" && kill -0 $(grep GPG_AGENT_INFO ${GAIFILE} | cut -d: -f 2 "${GAIFILE}") 2>/dev/null; then
        echo "found a running gpg-agent, not starting a new one"
else
        echo "found no running gpg-agent, starting one"
        eval `gpg-agent  --daemon --write-env-file "${GAIFILE}"`
fi

# ssh-agent
# somehow ssh functionality of gpg-agent seems to not work in here ($current_customer_April_2014)
# so we need another test to make sure we only start one even if we have multiple
# putty sessions
# and take into account that all Linux boxes I ssh to share the same home
# we can still end up with multiple agents (if one deletes the vars file while the agent is still running)
# but the vars file will always have the values relevant to the last staretd one, so that's OK for me
# While I could do a killall ssh-agent in the start agent function, but that's a bit harsh
# pcfe, 2014-04-02

SSH_ENV=${HOME}/.ssh/agentvars-${HOSTNAME}

function start_agent {
        echo "Initialising new SSH agent..."
        (
                umask 077
                /usr/bin/ssh-agent -s | sed 's/^echo/#echo/' > "${SSH_ENV}"
                echo ssh-agent started
                # sub shell with umask is more elegant than chmod post-facto
                # chmod 600 "${SSH_ENV}"
        )
        . "${SSH_ENV}" > /dev/null
}


if [ -f ${SSH_ENV} ]
then
        echo found a ssh vars file parsing it
        . "${SSH_ENV}"
else
        echo found no ssh vars file, starting an agent
        start_agent
fi

# the following test will only work under Linux
if test -d /proc/${SSH_AGENT_PID}
then
        echo "The agent PID (${SSH_AGENT_PID}) referenced in ${SSH_ENV} seems to still be running, all OK."
else
        echo "We seem to have a stale PID in ${SSH_ENV}, starting a new ssh-agent."
        start_agent
fi

echo "ssh-add -l (list fingerprints) tells us;"
ssh-add -l

# larger bash history, default is 1000
HISTSIZE=50000
export HISTSIZE

# any screen running?
echo
screen -ls 2>/dev/null

# Get the aliases and functions
if [ -f ~/.bashrc ]; then
        . ~/.bashrc
fi

the used .bashrc

# .bashrc
# ~/.bashrc file determines the behavior of interactive shells.
# read for every interactive shell that is not a login shell

# do not output if non interactive.
# c.f. https://bugzilla.redhat.com/show_bug.cgi?id=20527
[[ $- == *i* ]] && echo "running your .bashrc"


# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

# User specific aliases and functions

# fancy prompt
# https://wiki.archlinux.org/index.php/Color_Bash_Prompt
# pcfe, 2014-03-24
PS1='\[\e[0;32m\]\u@\h\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[1;32m\]\$\[\e[m\] '
#
# for root one would use the following
# PS1='\[\e[0;31m\]\u@\h\[\e[m\] \[\e[1;34m\]\w\[\e[m\] \[\e[0;31m\]\$ \[\e[m\]\[\e[0;32m\]'

# http://udrepper.livejournal.com/17109.html
alias egrep='egrep --color=tty -d skip'
alias fgrep='fgrep --color=tty -d skip'
alias grep='grep --color=tty -d skip'

## gpg-agent
## https://wiki.fsfe.org/Fellows/stiell/fedora_cryptocard_ssh_setup
## and the gpg-agent man page

GAIFILE=$HOME/.gpg-agent-info-${HOSTNAME}

if [ -f "${GAIFILE}" ]; then
        [[ $- == *i* ]] && echo "Found ${GAIFILE}, grabbing gpg-agent variables from it."
        . "${GAIFILE}"
        export GPG_AGENT_INFO
        # export SSH_AUTH_SOCK
        # export SSH_AGENT_PID
fi

GPG_TTY=$(tty)
export GPG_TTY

# to get ssh agent working in a screen detached from somewhere else
# see http://www.deadman.org/sshscreen.php
alias attach='grabssh ; screen -d -R'
alias fixssh='source $HOME/bin/fixssh'

# have ll with human readable sizes
alias ll='ls -lh --color=auto'

grabssh script

And while I’m at it, this script being referenced in the .bashrc, you can grab it below and put it in $HOME/bin/ (create that directory if you do not have it).

#!/bin/bash
# from http://www.deadman.org/sshscreen.php
# with slight modifications
# pcfe, 2011-01-18
SSHVARS="SSH_CLIENT SSH_TTY SSH_AUTH_SOCK SSH_CONNECTION DISPLAY"

umask 0077
for x in ${SSHVARS} ; do
    (eval echo $x=\$$x) | sed  's/=/="/
                                s/$/"/
                                s/^/export /'
done 1>$HOME/bin/fixssh