Table of Contents

ssh-agent

Manual Setup

This describes how to setup everything manually, for a more intuitive way see “pam_ssh” below.

You can place these two lines into the startscript of your window manager:

[-n "`pgrep ssh-agent`"] || ssh-agent -s > $HOME/.ssh/AGENT_VARS
["`pgrep ssh-agent`" = "$SSH_AGENT_PID"] || source $HOME/.ssh/AGENT_VARS >/dev/null 2>&1

or put it into $HOME/.bash_profile (for 'bash' users), at best into both:

[-n "`pgrep ssh-agent`"] || ssh-agent -s > $HOME/.ssh/AGENT_VARS
source $HOME/.ssh/AGENT_VARS >/dev/null 2>&1

as it is a new shell, sourcing is always necessary.

This is how:

# sourcing is never needlessly done
# the useless ssh-agent feedback to stdout is supressed (makes trouble with scp/sftp):
$ source .ssh/AGENT_VARS 
Agent pid 11142

Managing Identities

Identities can be managed via ssh-add.

This command adds the identity “id_dsa”:

$ ssh-add $HOME/.ssh/my_dsa

removal is analogous:

$ ssh-add -d $HOME/.ssh/my_dsa

there is a shortcut to remove all identities at once:

$ ssh-add -D

to view registered identities use '-l':

$ ssh-add -l

you can even output the pubkey (for scripting e.g.):

$ ssh-add -L

Correct Naming Of The Identity-File

These are the default searchpaths of OpenSSH:

If you name your identity-file like one of the names above, you may get into trouble when connecting to a server not having the corresponding pubkey in the authorized_keys-file.

As the ssh client first tries the registered identity, and (after failing) searches the default paths above for an alternate, it will find your (now still encrypted) identity again and asks for it's passphrase.

Obviously, also after entering the correct password, the second attempt will also fail, and eventually the prompt for the challenge-and-response authentication method will appear.

To avoid getting prompted for an already registered identity, you should name them different to the ones above and give the ssh-agent the correct name as a parameter.

pam_ssh

This pam module eases the management of the ssh-agent instance a lot. Despite it's either very easy to setup, it will be described here further.

Setup

After installing the apropriate files in /etc/pam.d have to be applied. As I seldom login via a text console, I only edited the file xdm.

This line should go to the beginning of it:

auth       sufficient pam_ssh.so keyfiles=base_dsa

The paramter keyfiles gets a filename inside $HOME/.ssh as parameter, this is exactly the identity-file to register.

The following line should go to the end of the file:

session    optional pam_ssh.so

Usage

Well, you will need an identity having the same password as the login for your preferred method. When authorizing against pam, it will use the given passphrase to unlock the identity specified, and if successful, starts the ssh-agent for you.

The ssh-agent output that has to be sourced by new shells is put into the files agent-$HOSTNAME and agent-${HOSTNAME}-${DISPLAY}.

ssh - utils

ssh-askpass

This is a helper-app providing a colourful window asking for the passphrase. It's an alternate to using pam_ssh. Best use in combination with the following ssh-agent configuration and put into your window manager startup script (below the lines added first):

[ `ssh-add -l >/dev/null` ] || ssh-add $HOME/.ssh/my_dsa </dev/null >/dev/null 2>&1

this adds the identity.

redirecting 'stdin' from /dev/null enforces the use of ssh-askpass. redirecting 'stdout' and 'stderr' to /dev/null is for compatibility.

'gtk2-ssh-askpass' is a very colourful version.

sshfs

sshfs utilizes Fuse and sftp/scp to virtually mount a remote host's filesystem.

Mounting

Easily done with:

sshfs user@host:/path/to/mount/ /mnt/point/

Unmounting

Here one can see the internals (fuse):

fusermount -u /mnt/point

ssh-copy-id

This makes copying pubkeys to different hosts a simple task.

Usage: /usr/bin/ssh-copy-id [-i [identity_file]] [user@]machine

Sharing Multiple Sessions

The trick is done in ~/.ssh/config:

Host *
  ControlMaster auto
  ControlPath ~/.ssh/%l-%r@%h:%p.control
  ControlPersist 30

this let's ssh default to acting as “ControlSlave” using the socket given as ControlPath. If that fails, it will automagically act as ControlMaster and provide the mentioned socket.

Using the “ControlPersist” option makes the master connection background immediately and stay alive for the given timespan (30 seconds in this example). This also allows the initial connection to quit without hanging when there are still users of the control path. Not setting it too low should aid for tab-completion on hosts without already existing connection, e.g. when “tabbing” though a remote path.

Bugfixes For Incompatible Programs

Shared connections do not work for svn+ssh. To get rid of this, edit “$HOME/.subversion/config”:

[tunnels]
 ssh = $SVN_SSH ssh -S none

Another problem exists when using rsync and QoS by inspecting the TOS field. This means when a ssh connection is already open, the rsync stream packets have the TOS field value set to Minimize-Delay as for ssh. Of course, this is a bad idea as rsync streams should be set to Maximize-Throughput. To achieve this, use an alias to rsync as follows:

alias rsync='rsync -e "ssh -S none"'

Defeating Stale Sessions

A stale SSH session can be easily created:

another way to do this is e.g. to forget disconnecting before suspending the notebook. After resume (given a reasonable delay, of course), the session hangs, and the connection is gone. This is how to handle it, just add some lines to the default section of your ssh_config:

ServerAliveCountMax 2
ServerAliveInterval 7

the first statement can be omitted, it's default value is 3. The second statement is crucial, as it is per default set to 0 (thereby disabling it).

The effect is the following: after 7 seconds (ServerAliveInterval) of idling, the server is being sent a keepalive packet over the encrypted channel. If there is no response for 2 packets (ServerAliveCountMax), the connection timeouts.

The difference to TCPKeepAlive is, as the packets are sent through the tunnel, this method doesn't depend on TCP timeouts.

Playground

Appending Local Files To Remote Ones

The escaping of control chars is a little tricky:

filedata="`cat /path/to/file`"
ssh hostname echo "$filedata" \>\>/path/to/remotefile

Writing Into Remote Files

More a hack than a feature:

ssh hostname echo \\"
this is \
a testfile, \
but i dont know how to make \
newlines into it.\
" \>testfile