Penguin
Annotated edit history of SSHKeys version 30, including all changes. View license author blame.
Rev Author # Line
18 MattBrown 1 !!! Introduction
2
3 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.
4
5 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.
6
24 AristotlePagaltzis 7 __''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.
18 MattBrown 8 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.
9
10 Another good option for a 'trusted' box is keychain which will allow you to run cronjobs over ssh even when you are logged out.
11
12 __NOTE:__ Do not run an agent on hosts you do not trust. Their SuperUser can then steal your keys.
13
14 !!! Generating key pairs
15
19 JohnMcPherson 16 This is what ssh-keygen(1) is for.
24 AristotlePagaltzis 17
30 AristotlePagaltzis 18 <pre>
19 ssh-keygen -t [dsa|DSA]
20 # or, effectively equivalent as far as [SSH] is concerned:
21 ssh-keygen -t [rsa|RSA]
22 </pre>
18 MattBrown 23
24 !!! Distributing public keys
25
24 AristotlePagaltzis 26 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):
18 MattBrown 27
24 AristotlePagaltzis 28 <pre>
29 ssh-copy-id -i ~~/.ssh/id_dsa.pub ''hostname''
30 </pre>
31
32 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.
33
34 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)).
18 MattBrown 35
36 !!! Key Security Options
24 AristotlePagaltzis 37
38 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.
18 MattBrown 39
40 !! Limit key use to certain machines
41
24 AristotlePagaltzis 42 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:
18 MattBrown 43
24 AristotlePagaltzis 44 <pre>
45 from="*.example.com,localhost" ssh-dss ''XXXX....base64..keyid....='' username@host
46 </pre>
47
48 You can also prefix a glob with a <tt>!</tt> to negate it.
18 MattBrown 49
50 !! Limit key use to a single command
24 AristotlePagaltzis 51
52 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.
18 MattBrown 53
54 !! Prevent Port/Agent/X11 forwarding
55
24 AristotlePagaltzis 56 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:
18 MattBrown 57
24 AristotlePagaltzis 58 <pre>
59 permitopen="10.2.1.55:80",permitopen="10.2.1.56:25" ssh-dss ''XXXX....base64..keyid....='' username@host
60 </pre>
18 MattBrown 61
24 AristotlePagaltzis 62 !!! Passphrases and [SSH] Agent
18 MattBrown 63
24 AristotlePagaltzis 64 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.
18 MattBrown 65
24 AristotlePagaltzis 66 So in <tt>.xinitrc</tt> we have something along the lines of, say:
18 MattBrown 67
24 AristotlePagaltzis 68 <verbatim>
69 /usr/bin/ssh-agent -- /usr/X11R6/bin/twm
70 </verbatim>
18 MattBrown 71
24 AristotlePagaltzis 72 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.
18 MattBrown 73
24 AristotlePagaltzis 74 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>
18 MattBrown 75
24 AristotlePagaltzis 76 !! RedHat/[GNOME] approach
18 MattBrown 77
78 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]:
79
24 AristotlePagaltzis 80 # 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.
18 MattBrown 81
24 AristotlePagaltzis 82 # 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.
83
84 # 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).
85
86 !! [SSH] Agent, Deluxe Ultra Series
87
88 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:
18 MattBrown 89
90 <verbatim>
19 JohnMcPherson 91 #!/bin/bash
92 # check if there's no agent already
93 if [ -x /usr/bin/ssh-agent -a -z "$SSH_AUTH_SOCK" ] ; then
24 AristotlePagaltzis 94 exec /usr/bin/ssh-agent $0
19 JohnMcPherson 95 fi
96 #
97 # the usual .xinitrc mumbo jumbo goes here
98 #
99 /usr/bin/ssh-add < /dev/null &
100 exec /usr/X11R6/bin/twm
101 </verbatim>
24 AristotlePagaltzis 102
103 You can easily do something similar if you use CommandLine only systems; in that case, your <tt>.bash_profile</tt> might look like this:
104
19 JohnMcPherson 105 <verbatim>
106 #!/bin/bash -x
107 # check if there's no agent already
108 if [ -x /usr/bin/ssh-agent -a -z "$SSH_AUTH_SOCK" ] ; then
24 AristotlePagaltzis 109 exec /usr/bin/ssh-agent sh -c "exec -a '$0' -- $SHELL"
19 JohnMcPherson 110 fi
24 AristotlePagaltzis 111
19 JohnMcPherson 112 #
113 # usual .bash_profile mumbo jumbo goes here
114 #
24 AristotlePagaltzis 115
19 JohnMcPherson 116 # add keys unless we've already done so
117 if [ -x /usr/bin/ssh-add ] && ! ssh-add -l &> /dev/null ; then
24 AristotlePagaltzis 118 /usr/bin/ssh-add
19 JohnMcPherson 119 fi
120 </verbatim>
18 MattBrown 121
24 AristotlePagaltzis 122 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.
123
124 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.
125
126 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:
18 MattBrown 127
128 <verbatim>
19 JohnMcPherson 129 # the `hostname` part is there so that this script can be run from the same home
130 # NFS-mounted on different machines without them clobbering each other's settings
131 AGENTFILE=~/.agent.`hostname`.env
18 MattBrown 132
19 JohnMcPherson 133 # don't do anything if there's already an agent, such as when
134 # logging into this machine with agent forwarding enabled on the remote end
135 if [ -z "$SSH_AUTH_SOCK" ]; then
24 AristotlePagaltzis 136 # have settings?
137 if [ -f $AGENTFILE ]; then
138 # load them
139 . $AGENTFILE > /dev/null
18 MattBrown 140
24 AristotlePagaltzis 141 # make sure they're not invalid
142 if [ ! kill -0 $SSH_AGENT_PID > /dev/null 2> ]; then
143 echo "Stale agent file found. Spawning new agent..."
144 eval `ssh-agent | tee $AGENTFILE`
145 ssh-add
146 fi
147 else
148 # no existing settings found, start new agent and save them
149 echo "Starting ssh-agent..."
150 eval `ssh-agent | tee $AGENTFILE`
151 ssh-add
152 fi
19 JohnMcPherson 153 fi
154 </verbatim>
18 MattBrown 155
24 AristotlePagaltzis 156 ''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
157
158 !! Removing keys when you're not around
18 MattBrown 159
160 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:
24 AristotlePagaltzis 161
19 JohnMcPherson 162 <verbatim>
163 #!/bin/bash
18 MattBrown 164
19 JohnMcPherson 165 KEYS="id_dsa id_rsa identity insecure sourceforge"
18 MattBrown 166
24 AristotlePagaltzis 167 delete_all_keys() { ssh-add -D }
18 MattBrown 168
19 JohnMcPherson 169 add_all_keys() {
24 AristotlePagaltzis 170 local OK_KEYS
171 unset OK_KEYS
172 for i in $KEYS; do
173 [ -r ~/.ssh/$i ] && OK_KEYS="$OK_KEYS /home/$USER/.ssh/$i"
174 done
175 echo Adding keys...
176 ssh-add $OK_KEYS
177 echo done
19 JohnMcPherson 178 }
18 MattBrown 179
19 JohnMcPherson 180 exec xscreensaver-command -watch | while read command arg; do
24 AristotlePagaltzis 181 case $command in
182 LOCK)
183 delete_all_keys
184 ;;
185 UNBLANK)
186 add_all_keys
187 ;;
188 RUN)
189 echo "Changing screensaver ($arg)"
190 ;;
191 BLANK)
192 #placeholder
193 ;;
194 *)
195 echo Unknown command: $command
196 echo " with arg: $arg"
197 esac
19 JohnMcPherson 198 done
199 </verbatim>
18 MattBrown 200
25 AristotlePagaltzis 201 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>.
24 AristotlePagaltzis 202
203 !! Agent Connection Forwarding
18 MattBrown 204
24 AristotlePagaltzis 205 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.
18 MattBrown 206
24 AristotlePagaltzis 207 <tt>.ssh/config</tt> convenience (see [SSHNotes] and ssh_config(5)) is achieved using <tt>~ForwardAgent yes</tt>.
22 StephenScahefer 208
209 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:
210
211 <verbatim>
212 if [ -z "$SSH_AGENT_PID" -a -z "$SSH_AUTH_SOCK" -o ! -S "$SSH_AUTH_SOCK" ]; then
213 eval `ssh-agent`
214 trap "kill -1 $SSH_AGENT_PID" EXIT
215 fi
216 </verbatim>
18 MattBrown 217
26 BenStaz 218 !! Disable Password Authentication
219
220 Use your favourite text editor [Vim] to edit /etc/ssh/sshd_config on the machine you wish to ssh to, and set these options.
221
222 <verbatim>
223 ChallengeResponseAuthentication no
224 PasswordAuthentication no
225 UsePAM no
27 BenStaz 226 </verbatim>
26 BenStaz 227
228 Now you will HAVE to have to have a key if you wish to SSH into that machine.
229 If not you will NOT be prompted for a password but instead will see: ''Permission denied (publickey)''
27 BenStaz 230
18 MattBrown 231 ----
232 Part of CategorySecurity and CategoryNetworking

PHP Warning

lib/blame.php:177: Warning: Invalid argument supplied for foreach() (...repeated 8 times)