Penguin

Differences between version 25 and predecessor to the previous major change of SSHKeys.

Other diffs: Previous Revision, Previous Author, or view the Annotated Edit History

Newer page: version 25 Last edited on Thursday, June 1, 2006 4:22:32 am by AristotlePagaltzis Revert
Older page: version 23 Last edited on Saturday, February 18, 2006 5:08:40 pm by JohnMcPherson Revert
@@ -3,194 +3,212 @@
 PublicKeyAuthentication has a weakness: if your private key is stored unprotected, anybody who gains access to your computer will be able to use your credentials to prove his identity and pretend to be you, gaining entry to machines that he should have no access to. Therefore the private key is stored to disk encrypted with a passphrase. To use the key, the [SSH] client must decrypt it, so it has to prompt you for your passphrase. 
  
 This makes PublicKeyAuthentication less convenient than password authentication: every time you log in somewhere, you have to type a long passphrase rather than a short password. 
  
-__''DO use passphrases''__. It's very tempting to use a passphraseless key so that " you don't have to type in a password every time". Instead, read on. 
+__''DO use passphrases''__. It's very tempting to use a passphraseless key so that you " don't have to type in a password every time". Instead, read on. 
  
-Authentication agents provide a solution to this. [OpenSSH]'s agent is called ssh-agent(1), [PuTTY]'s is called __ Pageant__ . Typically, you launch the agent when you log onto your local machine, which prompts you for the passphrases of any keys you have. The agent then remains persistent and provide your credentials to any client that needs them, so you will no longer be prompted for the passphrase. When you log out, the agent shuts down. 
+Authentication agents provide a solution to this. [OpenSSH]'s agent is called ssh-agent(1), [PuTTY]'s is called <b> Pageant</b> . Typically, you launch the agent when you log onto your local machine, which prompts you for the passphrases of any keys you have. The agent then remains persistent and provide your credentials to any client that needs them, so you will no longer be prompted for the passphrase. When you log out, the agent shuts down. 
  
 Another good option for a 'trusted' box is keychain which will allow you to run cronjobs over ssh even when you are logged out. 
  
 __NOTE:__ Do not run an agent on hosts you do not trust. Their SuperUser can then steal your keys. 
  
 !!! Generating key pairs 
  
 This is what ssh-keygen(1) is for. 
+  
 <verbatim> 
 ssh-keygen -t dsa 
 # or 
 ssh-keygen -t rsa 
 </verbatim> 
+  
 (DSA keys are probably preferable to RSA keys.) 
  
 !!! Distributing public keys 
  
-If you accepted the defaults for ssh-keygen(1) you should have two new files in ~~/.ssh, __ id_dsa__ and __ id_dsa.pub__ (or __ id_rsa__ and __ id_rsa.pub__ )%%%  
- The .pub file is your public key, you need to upload it to all remote hosts that you want to use Keys with.%%%  
-You need a __.ssh__ directory in your home on the remote machine. This directory must not be group or world writable. Keys go into the __.ssh/authorized_keys__ file, which must also not be group or world writable.  
-One any local machine that you wish to ssh *from*, you must have the private key __id_dsa__ (unless you forward an "ssh agent", discussed below) and it must not be readable by anyone other than the owner.  
-Obviously the directory and these files must be owned by the correct user. If the permissions are wrong, [SSH] will refuse to read them (without telling you, unfortunately - it only cries to syslogd(8)). [Debian] provides a ssh-copy-id(1) program which does all this automagically. Just say  
+If you accepted the defaults for ssh-keygen(1) you should have two new files in <tt> ~~/.ssh</tt> , <tt> id_dsa</tt> and <tt> id_dsa.pub</tt> (or <tt> id_rsa</tt> and <tt> id_rsa.pub</tt> ). The <tt> .pub</tt> file is your '' public'' key. You transfer a copy of this key to all remote hosts that you wish to use your key pair with. The easy way to do so is by using ssh-copy-id(1):  
  
- ssh-copy-id ''hostname'' 
+<pre>  
+ ssh-copy-id -i ~~/.ssh/id_dsa.pub ''hostname''  
+</pre>  
+  
+This adds a copy of the public key in <tt>id_dsa.pub</tt> to the <tt>~~/.ssh/authorized_keys</tt> file on the remote machine, and makes sure that neither the <tt>~~/.ssh</tt> directory nor the <tt>authorized_keys</tt> file are group or world writable (if they are, <tt>sshd</tt> will refuse to read the file). Note that if you have a [SSH] agent running (see below) you can omit the "<tt>-i ~/.ssh/id_dsa.pub</tt>" switch and ssh-copy-id(1) will just add whatever keys are being held by the agent.  
+  
+Next, on any local machine that you wish to [SSH] ''from'', you must have the private key <tt>id_dsa</tt> (unless you forward an [SSH] agent; see below) and it must not be readable by anyone other than the owner. Obviously the directory and these files must be owned by the correct user. If the permissions are wrong, [SSH] will refuse to read them (without telling you, unfortunately – it only cries to syslogd(8)).  
  
 !!! Key Security Options 
-You can tell sshd(8) to allow a certain key to only be used by certain hosts or for certain activities. A brief summary of the available options is below. See sshd(8) for the more extensive documentation. These options are specified as a set of comma seperated options before the key in the __ authorized_keys__ file. Spaces are not allowed in options unless they are surrounded by double quotes. 
+  
+ You can tell sshd(8) to allow a certain key to only be used by certain hosts or for certain activities. A brief summary of the available options is below. See sshd(8) for the more extensive documentation. These options are specified as a set of comma seperated options before the key in the <tt> authorized_keys</tt> file. Spaces are not allowed in an option unless the option is surrounded by double quotes. 
  
 !! Limit key use to certain machines 
-Using the __from__ keyword with a list of globs you can restrict which hosts are able to login using the key. Eg:  
  
- from="* .example .com, localhost" ssh-dss XXXX ....base64..keyid....= username@host  
+Using the <tt> from</tt> keyword with a list of globs you can restrict which hosts are able to login using the key . Eg . the following will only allow this key to be used from <tt> localhost</tt> and hosts in the <tt> .example .com</tt> domain:  
  
-This will only allow this key to be used from __localhost__ and hosts in the __ .example.com__ domain . You can also prefix a glob with a ! to negate it. 
+<pre>  
+ from="* .example.com,localhost" ssh-dss ''XXXX....base64..keyid... .='' username@host  
+</pre>  
+  
+ You can also prefix a glob with a <tt> !</tt> to negate it. 
  
 !! Limit key use to a single command 
-Using the __ command__ keyword you can specify a single command to be executed when the key is used to login, any other command specified by the user will be ignored at the ssh session will end once the command specified in the __ authorized_keys__ file has completed. 
+  
+ Using the <tt> command</tt> keyword you can specify a single command to be executed when the key is used to login, any other command specified by the user will be ignored at the ssh session will end once the command specified in the <tt> authorized_keys</tt> file has completed. 
  
 !! Prevent Port/Agent/X11 forwarding 
-You can prevent a key from being used to forward various things by using the __no-port-forwarding__, __no-agent-forwarding__, __no_X11_forwarding__ options. Or you can specify a limited range of allowed port forwards using the __permitopen__ option. Multiple permitopen options may be specified. Eg:  
  
- permitopen="10 .2 .1 .55: 80",permitopen=" 10.2.1.56:25" ssh-dss XXXX....base64..keyid....= username@host  
+You can prevent a key from being used to forward various things by using the <tt>no-port-forwarding</tt>, <tt>no-agent-forwarding</tt>, <tt>no_X11_forwarding</tt> options. Or you can specify a limited range of allowed port forwards using the <tt> permitopen</tt> option . Multiple permitopen options may be specified . Eg . the following would allow someone to login and setup port forward to ports 80 and 25 on host 10.2.1.56: 
  
-Would allow someone to login and setup port forward to ports 80 and 25 on host 10.2.1.56 
+<pre>  
+permitopen="10.2.1.55: 80",permitopen=" 10.2.1.56:25" ssh-dss ''XXXX....base64..keyid....='' username@host  
+</pre>  
  
-!!! Passphrases and SSH Agent 
+!!! Passphrases and [ SSH] Agent 
  
-ssh-agent(1) is designed to run as an ancestor process to any ssh(1) session you wish to manage keys for. The preferred mode of operation (although there are other ways) is to invoke ssh-agent(1) with a program as its argument, which will then be spawned by the agent. This might be a window manager , your shell , or something of the sort. As soon as you exit that program your authentication details get cleaned up and the agent exits. 
+ssh-agent(1) is designed to run as an ancestor process to any ssh(1) session you wish to manage keys for. The preferred mode of operation (although there are other ways) is to invoke ssh-agent(1) with a program as its argument, which will then be spawned by the agent. This might be a WindowManager , your [Shell] , or something of the sort. As soon as you exit that program your authentication details get cleaned up and the agent exits. 
  
-So we have a something along the lines of, say,  
- /usr/bin/ssh-agent -- /usr/X11R6/bin/twm  
-in __.xinitrc__.  
+So in <tt>.xinitrc</tt> we have something along the lines of, say:  
  
-When using xdm(1) or another display manager, it should be configured appropriately to use a call as in the line above, rather than calling your window manager directly.  
+ <verbatim>  
+ /usr/bin/ssh-agent -- /usr/X11R6/bin/twm  
+ </verbatim>  
  
-Now all you have to do is get your window manager to call ssh-add (1) when it starts. ssh-add(1) is how you authenticate yourself for the use of a key . When running under X, you can cause it to run one of the X variants of ssh-askpass(1) by redirecting its input from __/dev/null__:  
+When using xdm (1) or another display manager, it should be configured appropriately to use a call as in the line above, rather than calling your WindowManager directly
  
- /usr/bin/ssh-add < /dev/null & 
+Now all you have to do is get your WindowManager to call ssh-add(1) when it starts. ssh-add(1) is how you authenticate yourself for the use of a key. When running under [X], you can cause it to run one of the [X] variants of ssh-askpass(1) by redirecting its input from <tt>/dev/null</tt>, eg. <tt> /usr/bin/ssh-add < /dev/null &</tt>  
  
-!!Redhat ( GNOME) approach 
+!! RedHat/[ GNOME] approach 
  
 Pilfered from [the fine manual|http://www.redhat.com/docs/manuals/linux/RHL-9-Manual/custom-guide/s1-openssh-client-config.html#S3-OPENSSH-SSH-AGENT-WITH-GNOME]: 
  
-# You'll need to have the package openssh-askpass-gnome installed; you can use the command rpm -q openssh-askpass-gnome to determine if it is installed or not. If it is not installed, install it.  
-# Select Main Menu Button (on the Panel) => Preferences => More Preferences => Sessions, and click on the Startup Programs tab. Click Add and enter /usr/bin/ssh-add in the Startup Command text area. Set it a priority to a number higher than any existing commands to ensure that it is executed last. A good priority number for ssh-add is 70 or higher. The higher the priority number, the lower the priority. If you have other programs listed, this one should have the lowest priority. Click Close to exit the program.  
-# Log out and then log back into GNOME; in other words, restart X. After GNOME is started, a dialog box will appear prompting you for your passphrase(s). Enter the passphrase requested. If you have both DSA and RSA key pairs configured, you will be prompted for both. From this point on, you should not be prompted for a password by ssh, scp, or sftp
+# You'll need to have the [Package] <tt> openssh-askpass-gnome</tt> installed; you can use the command <tt> rpm -q openssh-askpass-gnome</tt> to determine if it is installed or not. If it is not installed, install it. 
  
-!!SSH Agent, Deluxe Ultra Series 
+# Select <i>Main Menu</i> Button (on the Panel) → <i>Preferences</i> → <i>More Preferences</i> → <i>Sessions</i>, and click on the <i>Startup Programs</i> tab. Click <i>Add</i> and enter <tt>/usr/bin/ssh-add</tt> in the <i>Startup Command</i> text area. Set it a priority to a number higher than any existing commands to ensure that it is executed last. A good priority number for <tt>ssh-add</tt> is 70 or higher. The higher the priority number, the lower the priority. If you have other programs listed, this one should have the lowest priority. Click <i>Close</i> to exit the program.  
+  
+# Log out and then log back into [GNOME]; in other words, restart [X]. After [GNOME] is started, a dialog box will appear prompting you for your passphrase(s). Enter the passphrase requested. If you have both DSA and RSA key pairs configured, you will be prompted for both. From this point on, you should not be prompted for a password by ssh(1), scp(1), or sftp(1).  
+  
+ !! [ SSH] Agent, Deluxe Ultra Series  
+  
+There is an elegant way to combine these methods independently of whether your WindowManager provides a facility for autoexecuting commands at launch. Using the <tt>exec</tt> command, the shell can replace itself with a new ssh-agent(1) instance if it cannot detect an existing agent. The new agent then immediately spawns a new shell to re-execute the script, which now successfully detects the agent and continues to do its actual work. In practice, your <tt>.xinitrc</tt> or <tt>.xsession</tt> might look something like this:  
  
-There is an elegant way to combine these methods independently of whether your window manager provides a facility for autoexecuting commands at launch. Using the __exec__ command, the shell can replace itself with a new ssh-agent(1) instance if it cannot detect an existing agent. The new agent then immediately spawns a new shell to re-execute the script, which now successfully detects the agent and continues to do its actual work. In practice, your __.xinitrc__ or __.xsession__ might look something like this:  
 <verbatim> 
 #!/bin/bash 
 # check if there's no agent already 
 if [ -x /usr/bin/ssh-agent -a -z "$SSH_AUTH_SOCK" ] ; then 
- exec /usr/bin/ssh-agent $ 
+ exec /usr/bin/ssh-agent $ 
 fi 
 
 # the usual .xinitrc mumbo jumbo goes here 
 
 /usr/bin/ssh-add < /dev/null & 
 exec /usr/X11R6/bin/twm 
 </verbatim> 
-You can easily do something similar if you use CommandLine only systems; in that case, your __ .bash_profile__ might look like this: 
+  
+ You can easily do something similar if you use CommandLine only systems; in that case, your <tt> .bash_profile</tt> might look like this:  
+  
 <verbatim> 
 #!/bin/bash -x 
 # check if there's no agent already 
 if [ -x /usr/bin/ssh-agent -a -z "$SSH_AUTH_SOCK" ] ; then 
- exec /usr/bin/ssh-agent sh -c "exec -a '$' -- $SHELL" 
+ exec /usr/bin/ssh-agent sh -c "exec -a '$' -- $SHELL" 
 fi 
+  
 
 # usual .bash_profile mumbo jumbo goes here 
 
+  
 # add keys unless we've already done so 
 if [ -x /usr/bin/ssh-add ] && ! ssh-add -l &> /dev/null ; then 
- /usr/bin/ssh-add 
+ /usr/bin/ssh-add 
 fi 
 </verbatim> 
-The check for existing keys was added here because in contrast to your __.xinitrc__, __.bash_profile__ is typically executed quite frequently - f.ex, for every xterm(1) you open.  
  
-Under Debian 3.0 (woody ), and possibly others, ssh-agent is normally set up to run like this anyway. If you use one of the standard session options, it all works fine. However, if (as in my case) you run a custom setup (ie, have a heavily modified __ .xsession__ file), then the ssh-agent either doesn't get called for some reason, or it dies early. Using the above script should solve this. 
+The check for existing keys was added here because in contrast to your <tt>.xinitrc</tt>, <tt>.bash_profile</tt> is typically executed quite frequently – f.ex, for every xterm(1) you open.  
+  
+ Under [ Debian] 3.0 ([Woody] ), and possibly others, ssh-agent(1) is normally set up to run like this anyway. If you use one of the standard session options, it all works fine. However, if (as in my case) you run a custom setup (ie, have a heavily modified <tt> .xsession</tt> file), then the ssh-agent(1) either doesn't get called for some reason, or it dies early. Using the above script should solve this.  
+  
+Page 144 of [Linux Server Hacks|http://library.wlug.org.nz/show.pl?id=1] by O'Reilly shows another, more convenient but less secure variant on the way to run an agent (page 144). The above script doesn't provide an immediate way to pass the agent information between virtual consoles, so you'll usually spawn a new agent for each of them and so have to enter the credentials once for each. The script shown below is more convenient in that a single agent running will suffice, but there's no automatic mechanism for terminating agents, so it will hang around indefinitely. If you are not concerned about this and want more comfort, see below:  
  
-Page 144 of "[Linux Server Hacks|http://library.wlug.org.nz/show.pl?id=1]" by O'Reilly shows another, more convenient but less secure variant on the way to run an agent (page 144). The above script doesn't provide an immediate way to pass the agent information between virtual consoles, so you'll usually spawn a new agent for each of them and so have to enter the credentials once for each. The script shown below is more convenient in that a single agent running will suffice, but there's no automatic mechanism for terminating agents, so it will hang around indefinitely. If you are not concerned about this and want more comfort, see below:  
 <verbatim> 
 # the `hostname` part is there so that this script can be run from the same home 
 # NFS-mounted on different machines without them clobbering each other's settings 
 AGENTFILE=~/.agent.`hostname`.env 
  
 # don't do anything if there's already an agent, such as when 
 # logging into this machine with agent forwarding enabled on the remote end 
 if [ -z "$SSH_AUTH_SOCK" ]; then 
+ # have settings?  
+ if [ -f $AGENTFILE ]; then  
+ # load them  
+ . $AGENTFILE > /dev/null  
  
- # have settings?  
- if [ -f $AGENTFILE ]; then  
-  
- # load them  
- . $AGENTFILE > /dev/null  
-  
- # make sure they're not invalid  
- if [ ! kill -0 $SSH_AGENT_PID > /dev/null 2> ]; then  
- echo "Stale agent file found. Spawning new agent..."  
- eval `ssh-agent | tee $AGENTFILE`  
- ssh-add  
- fi  
- else  
- # no existing settings found, start new agent and save them  
- echo "Starting ssh-agent..."  
- eval `ssh-agent | tee $AGENTFILE`  
- ssh-add  
- fi 
+ # make sure they're not invalid  
+ if [ ! kill -0 $SSH_AGENT_PID > /dev/null 2> ]; then  
+ echo "Stale agent file found. Spawning new agent..."  
+ eval `ssh-agent | tee $AGENTFILE`  
+ ssh-add  
+ fi  
+ else  
+ # no existing settings found, start new agent and save them  
+ echo "Starting ssh-agent..."  
+ eval `ssh-agent | tee $AGENTFILE`  
+ ssh-add  
+ fi 
 fi 
 </verbatim> 
-''In fact, it should easily be possible to merge these methods such that you get the benefits of both. I need to mull over the best way to do this.'' --AristotlePagaltzis  
  
-!!Removing keys when you're not around.  
+''These methods should be mergable such that you get the benefits of both. I need to mull over the best way to do this.'' —AristotlePagaltzis  
+  
+ !! Removing keys when you're not around 
  
 If you're a paranoid ol' bugger like me, and leave your machine logged in most of the time, but don't want to leave your keys freely accessible to everyone while you're away from the computer, here's a simple script that sniffs when the screensaver runs, and removes all your keys, and, when the screensaver is dismissed it prompts you for your keys again: 
+  
 <verbatim> 
 #!/bin/bash 
  
 KEYS="id_dsa id_rsa identity insecure sourceforge" 
  
-delete_all_keys() {  
- ssh-add -D  
-
+delete_all_keys() { ssh-add -D } 
  
 add_all_keys() { 
- local OK_KEYS  
- unset OK_KEYS  
- for i in $KEYS; do  
- [ -r ~/.ssh/$i ] && OK_KEYS="$OK_KEYS /home/$USER/.ssh/$i"  
- done  
- echo Adding keys...  
- ssh-add $OK_KEYS  
- echo done 
+ local OK_KEYS  
+ unset OK_KEYS  
+ for i in $KEYS; do  
+ [ -r ~/.ssh/$i ] && OK_KEYS="$OK_KEYS /home/$USER/.ssh/$i"  
+ done  
+ echo Adding keys...  
+ ssh-add $OK_KEYS  
+ echo done 
 
  
 exec xscreensaver-command -watch | while read command arg; do 
- case $command in  
- LOCK)  
- delete_all_keys  
- ;;  
- UNBLANK)  
- add_all_keys  
- ;;  
- RUN)  
- echo "Changing screensaver ($arg)"  
- ;;  
- BLANK)  
- #placeholder  
- ;;  
- *)  
- echo Unknown command: $command  
- echo " with arg: $arg"  
- esac 
+ case $command in  
+ LOCK)  
+ delete_all_keys  
+ ;;  
+ UNBLANK)  
+ add_all_keys  
+ ;;  
+ RUN)  
+ echo "Changing screensaver ($arg)"  
+ ;;  
+ BLANK)  
+ #placeholder  
+ ;;  
+ *)  
+ echo Unknown command: $command  
+ echo " with arg: $arg"  
+ esac 
 done 
 </verbatim> 
-Place this script somewhere in your PATH (eg. $HOME/bin/screenwatch) then start it from either your .xsession or your session manager (Gnome, KDE etc) with ''x-terminal-emulator -e "$HOME/bin/screenwatch"''  
  
-!!Agent Connection Forwarding 
+Place this script somewhere in your <tt>$PATH</tt> (eg. <tt>~~/bin/screenwatch</tt>) then start it from either your <tt>.xsession</tt> or your session manager ([GNOME], [KDE], etc.) with <tt>x-terminal-emulator -e ~/bin/screenwatch</tt>.  
+  
+ !! Agent Connection Forwarding 
  
-To save a lot of more typing, you can forward ssh-agent(1) information with the __ -A__ option to [SSH]. You can thus keep all your credentials on a single machine. __NOTE:__ Do not forward agent connections to hosts you do not trust. Their SuperUser can steal your keys. 
+To save a lot of more typing, you can forward ssh-agent(1) information with the <tt> -A</tt> option to [SSH]. You can thus keep all your credentials on a single machine. __NOTE:__ Do not forward agent connections to hosts you do not trust. Their SuperUser can steal your keys. 
  
-__ .ssh/config__ convenience (see [SSHNotes] and ssh_config(5)) is achieved using __ ~ForwardAgent yes__
+<tt> .ssh/config</tt> convenience (see [SSHNotes] and ssh_config(5)) is achieved using <tt> ~ForwardAgent yes</tt>
  
 If your home directory is available to multiple machines, some might or might not have ssh-agent running already; you might or might not have forwarded authentication. The following in your $HOME/.profile sets up ssh-agent if it is not present for a particular sh/bash/ksh session, but does not clobber forwarded authentication: 
  
 <verbatim>