<?xml version='1.0' encoding="UTF-8"?>
<!DOCTYPE guide SYSTEM "/dtd/guide.dtd">
<!-- $Header: /var/cvsroot/gentoo/xml/htdocs/doc/en/keychain-guide.xml,v 1.8 2010/12/17 07:31:25 nightmorph Exp $ -->

<guide>
<title>Gentoo Linux Keychain Guide</title>

<author title="Author">
  <mail link="eric.brown@dnbrown.net">Eric Brown</mail>
</author>
<author title="Editor">
  <mail link="vanquirius@gentoo.org">Marcelo Góes</mail>
</author>
<author title="Editor">
  <mail link="nightmorph"/>
</author>

<abstract>
This document describes how to use ssh shared keys along with the keychain
program.  It assumes basic knowledge of public key cryptography.
</abstract>

<!-- The content of this document is licensed under the CC-BY-SA license -->
<!-- See http://creativecommons.org/licenses/by-sa/2.5 -->
<license/>

<version>2</version>
<date>2010-12-16</date>

<chapter>
<title>Background</title>
<section>
<title>The problem at hand</title>
<body>

<p>
So you have all of these lovely Gentoo machines running <c>sshd</c>, but it's a
little inconvenient for you to keep typing in all of those login passwords,
right?  Or maybe you have a script or cron-job that needs a convenient way to
use an ssh connection.  Either way, there is a solution to this problem, and it
begins with public key authentication.
</p>

</body>
</section>
<section>
<title>How does public key authentication work?</title>
<body>

<p>
Assume we have a client that wants to connect to sshd on a server.  The client
first generates a key pair and gives the public key to the server.  Afterwards,
whenever the client attempts to connect, the server sends a challenge that is
encrypted with that public key.  Only the holder of the corresponding private
key (the client) is able to decrypt it, so as you might have guessed, the
correct response leads to successful authentication.
</p>

</body>
</section>
</chapter>
<chapter>
<title>How to use public key authentication</title>
<section>
<title>Generating your key pair</title>
<body>

<p>
The first step is to create your key pair.  To do this, we will use the
<c>ssh-keygen</c> command as follows:
</p>

<pre caption="Generating the key pair">
$ <i>ssh-keygen -t dsa</i>
<comment>(Just accept the default values, and make sure to enter a strong passphrase)</comment>
</pre>

<warn>
Be sure to choose a strong passphrase, especially if this key is used for
root logons!
</warn>

<p>
You should now have a private key in <path>~/.ssh/id_dsa</path> and a public
key in <path>~/.ssh/id_dsa.pub</path>.  We are ready to copy the public key over
to the remote host.
</p>

</body>
</section>
<section>
<title>Preparing the server</title>
<body>

<p>
We will be copying the <path>~/.ssh/id_dsa.pub</path> file over to the
server that runs sshd.  We will also be adding it to the
<path>~/.ssh/authorized_keys</path> file that belongs the connecting user on
that server.  Here's an example of how to do that if you already have ssh access
to the server.
</p>

<pre caption="Copying the public key to the server">
$ <i>scp ~/.ssh/id_dsa.pub server_user@server:~/myhost.pub</i>
$ <i>ssh server_user@server "cat ~/myhost.pub >> ~/.ssh/authorized_keys"</i>
$ <i>ssh server_user@server "cat ~/.ssh/authorized_keys"</i>
</pre>

<p>
The output from that last line should show you the contents of the
<path>~/.ssh/authorized_keys</path> file.  Make sure it looks correct.
</p>

</body>
</section>
<section>
<title>Testing the setup</title>
<body>

<p>
Theoretically, if all went well, and the ssh daemon on the server allows it, we
should be able to get ssh access without a password on the server now.  We will
still need to decrypt the private key on the client with the passphrase we
used before, but this should not be confused with the passphrase of the user
account on the server.
</p>

<pre caption="Testing the keys">
$ <i>ssh server_user@server</i>
</pre>

<p>
Hopefully, it asked you for your passphrase for id_dsa, and you were able to
gain ssh access as server_user on the server.  If not, login as server_user, and
verify the contents of <path>~/.ssh/authorized_keys</path> to make sure each
entry is on a single line.  You might also want to check the sshd configuration
to make sure that it prefers to use public key authorization when available.
</p>

<p>
At this point, you're probably thinking, "What's the point, I just replaced one
password with another?!"  Relax, the next section will show you exactly how we
can use this to save your precious time.
</p>

</body>
</section>
</chapter>
<chapter>
<title>Making public key authentication convenient</title>
<section>
<title>Typical key management with ssh-agent</title>
<body>

<p>
If you've been following along, you're probably thinking that it would be great
if we could somehow decrypt our private key(s) once, and gain the ability to ssh
freely, without any passwords.  You are in luck, that is exactly what the
program <c>ssh-agent</c> is for.
</p>

<p>
The program <c>ssh-agent</c> is usually started at the beginning of your X
session, or from a shell startup script like <path>~/.bash_profile</path>.  It
works by creating a unix-socket, and registering the appropriate environment
variables so that all subsequent applications can take advantage of it's
services by connecting to that socket.  Clearly, it only makes sense to start it
in the parent process of your X session if you want to use the set of decrypted
private keys in all subsequent X applications.
</p>

<pre caption="Preparing ssh-agent">
$ <i>ssh-agent</i>
</pre>

<note>
This ssh-agent will keep keys decrypted until you kill ssh-agent.  If you want
to set a lifetime for the keys, use the -t argument as described in <c>man
ssh-agent</c>.
</note>

<p>
When you run ssh-agent, it should tell you the PID of the running ssh-agent, and
also set a few environment variables, namely <c>SSH_AUTH_SOCK</c> and
<c>SSH_AGENT_PID</c>.  It should also automatically add
<path>~/.ssh/id_dsa</path> to it's collection and ask you for the corresponding
passphrase.  If you have other private keys you want to add to the running
ssh-agent, you can use the <c>ssh-add</c> command as follows:
</p>

<pre caption="Adding more keys to ssh-agent">
$ <i>ssh-add somekeyfile</i>
</pre>

<p>
Now for the magic.  Since you should now have your decrypted private key ready,
you should be able to ssh into the server without entering any passwords.
</p>

<pre caption="Ssh without passwords">
$ <i>ssh server</i>
</pre>

<p>
It would be nice to know how to shut down ssh-agent in case you need to, right?
</p>

<pre caption="Shutting down ssh-agent">
$ <i>ssh-agent -k</i>
</pre>

<note>
If you had problems getting ssh-agent to work, it might still be running.  You
can kill it like any other process by running <c>killall ssh-agent</c>.
</note>

<p>
If you want even more convenience from ssh-agent, proceed to the next section on
using keychain.  Be sure to kill the running ssh-agent as in the example above
if you decide to do so.
</p>

</body>
</section>
<section>
<title>Squeezing the last drop of convenience out of ssh-agent</title>
<body>

<p>
Keychain will allow you to reuse an ssh-agent between logins, and optionally
prompt for passphrases each time the user logs in.  Before we get ahead of
ourselves though, let's emerge it first.
</p>

<pre caption="Installing keychain">
# <i>emerge keychain</i>
</pre>

<p>
Assuming that was successful, we can now use keychain freely.  Add the following
to your <path>~/.bash_profile</path> to enable it:
</p>

<pre caption="Enabling keychain in .bash_profile">
keychain ~/.ssh/id_dsa
. ~/.keychain/$HOSTNAME-sh
. ~/.keychain/$HOSTNAME-sh-gpg
</pre>

<note>
You can add more private keys to the command line as you desire.  Also, if you
want it to ask for passphrases each time you spawn a shell, add the --clear
option.
</note>

<note>
If you are not using bash, check the <b>EXAMPLES</b> section of <c>man
keychain</c> for examples of use in other shells.  The idea is to get those
commands to run each time you use a shell.
</note>

<p>
Let's test it.  First make sure we killed the ssh-agent from the previous
section, then start up a new shell, usually by just logging in, or spawning a
new terminal.  It should prompt you for the password for each key you specified
on the command line.  All shells opened after that point should reuse the
ssh-agent, allowing you to make passwordless ssh connections over and over.
</p>

</body>
</section>
<section>
<title>Using keychain with KDE</title>
<body>

<p>
If you are a KDE user, instead of using <path>~/.bash_profile</path>, you can
let KDE manage ssh-agent for you. In order to do so, you will have to edit
<path>/etc/kde/agent-startup.sh</path>, which is read during KDE's
startup, and <path>/etc/kde/shutdown/agent-shutdown.sh</path>, which is
executed during KDE's shutdown. Here is how you could edit those files:
</p>

<pre caption="Editing /etc/kde/agent-startup.sh">
if [ -x /usr/bin/ssh-agent ]; then
  eval "$(/usr/bin/ssh-agent -s)"
fi
</pre>

<pre caption="Editing /etc/kde/shutdown/agent-shutdown.sh">
if [ -n "${SSH_AGENT_PID}" ]; then
  eval "$(ssh-agent -k)"
fi
</pre>

<p>
Now, all you have to do is launch a term of your choice, like Konsole, and load
the keys you would like to use. For example:
</p>

<pre caption="Loading ssh key">
$ <i>keychain ~/.ssh/id_dsa</i>
<comment>(Enter your key password)</comment>
</pre>

<p>
Your keys will be remembered until you end your KDE session or kill the
ssh-agent manually.
</p>

</body>
</section>
</chapter>

<chapter>
<title>Concluding remarks</title>
<section>
<title>Security considerations</title>
<body>

<p>
Of course, the use of ssh-agent may add a bit of insecurity to your system.  If
another user were to use your shell while you were in the bathroom, he could
login to all of your servers without passwords.  As a result, it is a risk to
the servers you are connecting to, and you should be sure to consult the local
security policy.  If you do use it, be sure to take the appropriate measures to
ensure the security of your sessions.
</p>

</body>
</section>
<section>
<title>Troubleshooting</title>
<body>

<p>
Most of this should work pretty well, but if you encounter problems, you'll
certainly want to know a few useful things.
</p>

<ul>
  <li>
    If you are unable to connect without ssh-agent, consider using ssh with the
    arguments -vvv to find out what's happening.  Sometimes the server is not
    configured to use public key authentication, sometimes it is configured to
    ask for local passwords anyway!  If that is the case, you may want to also
    use the -o option with ssh, or change the server sshd_config.
  </li>
  <li>
    If you are having problems with ssh-agent or keychain, it may be that you
    are not using a shell that understands the commands they use.  Consult the
    man pages for ssh-agent and keychain for details on working with other
    shells.
  </li>
  <li>
    You may also want to visit the <uri
    link="http://www.funtoo.org/en/security/keychain/intro/">keychain
    homepage</uri> for more usage tips.
  </li>
</ul>

</body>
</section>
</chapter>
</guide>
