Set up ssh-agent: Difference between revisions

From cctbx_xfel
Jump to navigation Jump to search
(Added comments from the other wiki.)
m (Nitpicks.)
 
(5 intermediate revisions by the same user not shown)
Line 1: Line 1:
Checking out or updating the ''PHENIX'' sources will establish many ssh(1) connections to cci.lbl.gov.  While not necessary for a successful installation, having an ssh-agent(1) daemon running on the machine used to access cci.lbl.gov will save much error-prone password-typing.  The idea is to provide the remote system with the public half of a cryptographic key pair, which enables it to send a randomly generated challenge to the ssh-agent.  If the agent agent has acquired a corresponding private key, it can decrypt the challenge, thus proving to the remote system that it has access to the decrypted private key, and hence authenticating to the remote system without any further user intervention.
Checking out or updating the ''PHENIX'' sources will establish many ssh-connections to several servers hosting the source repositories.  While not necessary for a successful installation, having an ssh-agent running on the machine used to access the repositories will save much error-prone password-typing.  The idea is to provide the remote server with the public half of a cryptographic key pair, which enables it to encrypt a randomly generated challenge and send it to the ssh-agent.  If the agent has acquired the corresponding private key it can respond with the decrypted challenge, thereby proving to the remote server that it has access to the decrypted private key.  The ssh-agent has authenticated with the server without any user intervention.
 


== Creating a cryptographic key pair ==
== Creating a cryptographic key pair ==
The first step is to generate a complementary pair of cryptographic keys.  One of the keys is public and the other is private; together they define an <i>identity</i>.  This step can be skipped if a key pair already exists—it is perfectly safe to use the same key pair to authenticate to any number of remote systems.  The public component of the key pair can be distributed without compromising security.  Indeed, any system one wishes to authenticate to will need access to the public key.  The private component must be kept secret.  In addition, the private key can be encrypted using a passphrase without which it cannot be used.  It is possible to generate a key pair without a passphrase, but then anybody who gains access to the key also acquires access to all systems the key unlocks.


In the example below, the key pair is generated in the default location, <i>/home/user/.ssh/id_rsa</i>.  A passphrase, <b><i>yourverysecretpasswordhere</i></b> below, is used to encrypt the private key.  The passphrase should be complex—when using ssh-agent(1) one will not need to type it very often.   
The first step is to generate a complementary pair of cryptographic keys.  This step can be skipped if a key pair already exists—it is perfectly safe to use the same key pair to authenticate with any number of remote systems.  One of the keys is public and the other is private.  The public component of the key pair can be freely distributed without compromising security; indeed, any system one wishes to authenticate with will need access to the public key.  The private component must be kept secret.  In addition, the private key can be encrypted using a passphrase without which it cannot be used.  It is possible to generate a key pair without a passphrase, but then anybody who gains access to the key also acquires access to all systems the key unlocks.
 
In the example below, an RSA key pair is generated in the default location, <i>/home/user/.ssh/id_rsa</i> and <i>/home/user/.ssh/id_rsa.pub</i>.  The passphrase should be complex—when using ssh-agent one will not need to type it very often.   
  $ ssh-keygen
  $ ssh-keygen
  Generating public/private rsa key pair.
  Generating public/private rsa key pair.
  Enter file in which to save the key (<i>/home/user/.ssh/id_rsa</i>):
  Enter file in which to save the key (<i>/home/user/.ssh/id_rsa</i>): <b>[PRESS RETURN]</b>
  Enter passphrase (empty for no passphrase): <b><i>yourverysecretpasswordhere</i></b>
  Enter passphrase (empty for no passphrase): <b>[ENTER A COMPLEX PASSPHRASE AND PRESS RETURN]</b>
  Enter same passphrase again: <b><i>yourverysecretpasswordhere</i></b>
  Enter same passphrase again: <b>[REPEAT COMPLEX PASSPHRASE AND PRESS RETURN]</b>
  Your identification has been saved in <i>/home/user/.ssh/id_rsa</i>.
  Your identification has been saved in <i>/home/user/.ssh/id_rsa</i>.
  Your public key has been saved in <i>/home/user/.ssh/id_rsa.pub</i>.
  Your public key has been saved in <i>/home/user/.ssh/id_rsa.pub</i>.
  The key fingerprint is:
  The key fingerprint is:
  <i>ba:f2:7a:78:aa:b0:33:1d:53:de:63:01:62:15:d6:c9 user@host</i>
  <i>ba:f2:7a:78:aa:b0:33:1d:53:de:63:01:62:15:d6:c9 user@host</i>
Then, start the ssh-agent, and add the newly generated identity to the ssh-agent's cache of decrypted private keys.
Then, start the ssh-agent, and add the decrypted private key of the newly generated key pair to the ssh-agent's cache.
  $ eval `ssh-agent`
  $ eval `ssh-agent`
  $ ssh-add
  $ ssh-add
  Enter passphrase for <i>/home/user/.ssh/id_rsa</i>: <b><i>yourverysecretpasswordhere</i></b>
  Enter passphrase for <i>/home/user/.ssh/id_rsa</i>: <b>[ENTER COMPLEX PASSPHRASE AND PRESS RETURN]</b>
  Identity added: <i>/home/user/.ssh/id_rsa</i> (<i>/home/user/.ssh/id_rsa</i>)
  Identity added: <i>/home/user/.ssh/id_rsa</i> (<i>/home/user/.ssh/id_rsa</i>)
ssh(1) will now find the running ssh-agent(1), and attempt to use the keys it holds to authenticate with the remote system.
New ssh-processes will now act as clients to the ssh-agent, and attempt to use the keys it holds to authenticate with the remote system.
<!-- XXX Comment on RSA vs DSA keys? -->
 


== Distribute the public key to the remote system ==
== Distribute the public key to the remote system ==


The remote system has to be aware of the key pair to grant access.  This means that the public component of the key pair has to be present in <code>~/.ssh/authorized_keys</code> on the remote system.
The remote system needs access to the public component of the key pair to generate the authenticating challenge for the ssh-agent.  This means that the <em>public</em> component of the key pair has to be present in <code>~/.ssh/authorized_keys</code> on the remote system.
  $ cat ~/.ssh/id_rsa.pub | ssh <b><i>user@remote.host</i></b> "cat - >> ~/.ssh/authorized_keys"
  $ cat ~/.ssh/id_rsa.pub | ssh <b><i>user@remote.host</i></b> "cat - >> ~/.ssh/authorized_keys"
This will append the <em>public</em> key of the recently created key pair to <code>~/.ssh/authorized_keys</code> on the <em>remote</em> system.  It is now possible to access <b><i>remote.host</i></b> without typing a password on the command line.
This will append the public key of the recently created key pair to <code>~/.ssh/authorized_keys</code> on the <em>remote</em> system.  It is now possible to access <b><i>remote.host</i></b> without typing a password on the command line.
 


<!-- XXX How to distribute the key pair to sourceforge -->
=== Distribute the public key to SourceForge ===
 
The servers at SourceForge can be made aware of the public key, too.  To do so, access the account from the web interface and navigate to [http://sourceforge.net/account/services SSH Settings], and choose [https://sourceforge.net/account/ssh Edit SSH Keys for Shell/CVS].  The public key can now be pasted into the text box.  Note that it may take several minutes for the change to take effect.


== Using ''keychain'' ==
== Using ''keychain'' ==


An ssh-agent started from command line only affects ssh-connections started from the same shell, and separate ssh-agents would be required for each new login shell.  The private key would have to be unlocked from every login shell separately.  Furthermore, ssh-agents are not terminated when the login shell is exited, this has the potential to clutter the system with "orphaned" ssh-agents.  ''keychain'' is a shell script that was written to avoid this situation: it probes the system for any running ssh-agents, and attempts to use a present agent instead of starting a new process.  If no ssh-agents are running, ''keychain'' starts a new process and uses ssh-add(1) to add the specified identities.
An ssh-agent started from command line only affects ssh-connections started from the same shell, and separate ssh-agents would be required for each new login shell.  The private key would have to be decrypted from every login shell separately.  Furthermore, ssh-agents are not necessarily terminated when the login shell exits, potentially cluttering the system with orphaned ssh-agents.  ''keychain'' is a shell script that was written to avoid this situation: it probes the system for any running ssh-agents, and attempts to use a running agent instead of starting a new daemon.  If no ssh-agents are running, ''keychain'' starts a new process and uses ssh-add to add the specified private keys.


At CCI and SLAC ''keychain'' is installed at <code>~hattne/gentoo/usr/bin/keychain</code> (at NERSC it is at <code>/global/project/projectdirs/lcls/gentoo/usr/bin/keychain</code>).  It is recommended to run ''keychain'' from the shell configuration files for interactive, login shells.  To do so, bash(1) users can add the following lines to <code>~/.bash_profile</code>:
At CCI and SLAC ''keychain'' is installed at <code>~hattne/gentoo/usr/bin/keychain</code>.  At NERSC it is at <code>/global/project/projectdirs/lcls/gentoo/usr/bin/keychain</code>.  It is recommended to run ''keychain'' from the shell configuration files for interactive, login shells.  To do so, bash-users can add the following lines to their <code>~/.bash_profile</code>:
   test -x <b><i>/path/to/keychain</i></b> && \
   test -x <b><i>/path/to/keychain</i></b> && \
     eval `<b><i>/path/to/keychain</i></b> --agents ssh --eval id_rsa --inherit any-once --stop others`
     eval `<b><i>/path/to/keychain</i></b> --agents ssh --eval id_rsa --inherit any-once --stop others`
csh(1) would modify <code>~/.login</code> instead.
csh-users would modify <code>~/.login</code> instead.
 
<!-- Commands in <code>~/.bash_profile</code> or <code>~/.login</code> will only be executed when a new login shell is started, which is appropriate for ssh-agent(1). However, even non-login shells may need environment variables to be set, and in what follows, those will be defined in ~/.bashrc (or ~/.cshrc for csh(1) users). Assuming that all customisations for non-login shells are applicable to login shells as well, putting the line
test -r "${HOME}/.bashrc" && . "${HOME}/.bashrc"
near the top of ~/.bash_profile is a way to avoid duplicating configuration options in ~/.bash_profile and ~/.bashrc. With csh(1), this is not necessary because ~/.cshrc is always read.
-->




== Using agent forwarding ==
== Using agent forwarding ==


It is not necessary to start ssh-agents on every system logged in to.  If an ssh-agent is running on the host used to access the remote system from, the agent can be forwarded using the ssh(1)’s <code>-A</code> option to forward the authentication agent when logging in.  ''keychain'' will recognize that agent-forwarding is in effect and will not start a new agent on the remote system.  Note that forwarding the agent connection has security implications.
It is not necessary to start ssh-agents on every system logged in to.  If an ssh-agent is running on the host used to access a remote system, a connection to the agent can be forwarded using the ssh’s <code>-A</code> option.  Any ssh-processes on the remote system will now query the ssh-agent on the host logged in from.  ''keychain'' will recognize that agent-forwarding is in effect and will not start a new agent on the remote system.




== External links ==
== External links ==


* [http://www.openbsd.org/cgi-bin/man.cgi?query=ssh-agent OpenBSD manual pages: ssh-agent]
* [http://www.openbsd.org/cgi-bin/man.cgi?query=ssh-keygen OpenBSD manual pages: ssh-keygen]
* [http://www.openbsd.org/cgi-bin/man.cgi?query=ssh-add OpenBSD manual pages: ssh-add]
* [https://sourceforge.net/apps/trac/sourceforge/wiki/SSH%20keys SSH keys - SourceForge]
* [http://www.funtoo.org/Keychain Keychain—Funtoo]
* [http://www.funtoo.org/Keychain Keychain—Funtoo]

Latest revision as of 21:41, 5 February 2014

Checking out or updating the PHENIX sources will establish many ssh-connections to several servers hosting the source repositories. While not necessary for a successful installation, having an ssh-agent running on the machine used to access the repositories will save much error-prone password-typing. The idea is to provide the remote server with the public half of a cryptographic key pair, which enables it to encrypt a randomly generated challenge and send it to the ssh-agent. If the agent has acquired the corresponding private key it can respond with the decrypted challenge, thereby proving to the remote server that it has access to the decrypted private key. The ssh-agent has authenticated with the server without any user intervention.


Creating a cryptographic key pair

The first step is to generate a complementary pair of cryptographic keys. This step can be skipped if a key pair already exists—it is perfectly safe to use the same key pair to authenticate with any number of remote systems. One of the keys is public and the other is private. The public component of the key pair can be freely distributed without compromising security; indeed, any system one wishes to authenticate with will need access to the public key. The private component must be kept secret. In addition, the private key can be encrypted using a passphrase without which it cannot be used. It is possible to generate a key pair without a passphrase, but then anybody who gains access to the key also acquires access to all systems the key unlocks.

In the example below, an RSA key pair is generated in the default location, /home/user/.ssh/id_rsa and /home/user/.ssh/id_rsa.pub. The passphrase should be complex—when using ssh-agent one will not need to type it very often.

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa): [PRESS RETURN]
Enter passphrase (empty for no passphrase): [ENTER A COMPLEX PASSPHRASE AND PRESS RETURN]
Enter same passphrase again: [REPEAT COMPLEX PASSPHRASE AND PRESS RETURN]
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is:
ba:f2:7a:78:aa:b0:33:1d:53:de:63:01:62:15:d6:c9 user@host

Then, start the ssh-agent, and add the decrypted private key of the newly generated key pair to the ssh-agent's cache.

$ eval `ssh-agent`
$ ssh-add
Enter passphrase for /home/user/.ssh/id_rsa: [ENTER COMPLEX PASSPHRASE AND PRESS RETURN]
Identity added: /home/user/.ssh/id_rsa (/home/user/.ssh/id_rsa)

New ssh-processes will now act as clients to the ssh-agent, and attempt to use the keys it holds to authenticate with the remote system.


Distribute the public key to the remote system

The remote system needs access to the public component of the key pair to generate the authenticating challenge for the ssh-agent. This means that the public component of the key pair has to be present in ~/.ssh/authorized_keys on the remote system.

$ cat ~/.ssh/id_rsa.pub | ssh user@remote.host "cat - >> ~/.ssh/authorized_keys"

This will append the public key of the recently created key pair to ~/.ssh/authorized_keys on the remote system. It is now possible to access remote.host without typing a password on the command line.


Distribute the public key to SourceForge

The servers at SourceForge can be made aware of the public key, too. To do so, access the account from the web interface and navigate to SSH Settings, and choose Edit SSH Keys for Shell/CVS. The public key can now be pasted into the text box. Note that it may take several minutes for the change to take effect.

Using keychain

An ssh-agent started from command line only affects ssh-connections started from the same shell, and separate ssh-agents would be required for each new login shell. The private key would have to be decrypted from every login shell separately. Furthermore, ssh-agents are not necessarily terminated when the login shell exits, potentially cluttering the system with orphaned ssh-agents. keychain is a shell script that was written to avoid this situation: it probes the system for any running ssh-agents, and attempts to use a running agent instead of starting a new daemon. If no ssh-agents are running, keychain starts a new process and uses ssh-add to add the specified private keys.

At CCI and SLAC keychain is installed at ~hattne/gentoo/usr/bin/keychain. At NERSC it is at /global/project/projectdirs/lcls/gentoo/usr/bin/keychain. It is recommended to run keychain from the shell configuration files for interactive, login shells. To do so, bash-users can add the following lines to their ~/.bash_profile:

 test -x /path/to/keychain && \
   eval `/path/to/keychain --agents ssh --eval id_rsa --inherit any-once --stop others`

csh-users would modify ~/.login instead.


Using agent forwarding

It is not necessary to start ssh-agents on every system logged in to. If an ssh-agent is running on the host used to access a remote system, a connection to the agent can be forwarded using the ssh’s -A option. Any ssh-processes on the remote system will now query the ssh-agent on the host logged in from. keychain will recognize that agent-forwarding is in effect and will not start a new agent on the remote system.


External links