Introduction to OpenSSH (and PuTTY)
Disclaimer
This document is provided free of charge, and thus, only provided on an "as-is" basis. Although the information contained in this document is believed to be correct, there may be errors or omissions in this document. Neither the author nor Openesque LLC shall be liable for any damages, including incidental or consequential damages, as a result of any errors or omissions in this document.
Introduction
This document describes basic configuration and usage of OpenSSH and PuTTY.
The commercial SSH server and client are not covered. Their product isn't free; they can document their own products.
In this document, I will only discuss the latest versions of
ssh
tools. I may make reference to older versions, but
generally speaking, you should be using the latest stable versions if
at all possible… and if that's not possible, you need greater
expertise available than this document will provide you with.
Cryptography technologies will only be discussed in sufficient detail here to (hopefully) allow you to use them securely.
OpenSSH is a free implementation of the SSH server and client tools for Unix environments. PuTTY is a free implementation of the SSH client tools for Win32 environments.
While the documentation provided with both of these is quite good, it's difficult to get the "first clue" from them; hence, this document.
The PuTTY documentation presented here is brief, as the documentation provided with PuTTY is quite good. Hopefully, you will find that once you understand OpenSSH better, the equivalent functionality in PuTTY will become more obvious.
Feedback on this document is welcome. E-mail to feedback@openesque.com.
Conventions
In this document:
- "ssh" refers to the ssh client program provided by OpenSSH.
- "SSH" refers to the Secure Shell protocol and transport used by all ssh-compatible clients and servers, including PuTTY.
There was some controversy about SSH
Communications Security trademarking the terms "SSH" and
"Secure Shell". Their trademark, as I understand it, does
not cover these terms generically, only their logo representation in a
particular font. Go Google
about it if you really care—and whatever you do, don't set up
your browser to use the fonts they did! ;-)
Make sure your SSH software is up-to-date
Versions of OpenSSH prior to 3.4 are vulnerable to attack. There may be newer vulnerabilities since this document was last revised. Visit http://www.openssh.com and make sure you're up to date.
The latest version of OpenSSH as of this writing is 3.4. Check here to see if a newer version is available.
NOTE: don't upgrade just the OpenSSH client or server; upgrade both when you upgrade.
It's also a good idea to subscribe to the openbsd-security-announce if running OpenBSD, or opnessh-unix-announce list if running some other OS. If your operating system vendor packages OpenSSH for you, be sure to subscribe to their security announcement mailing list. This will help assure you don't get compromised if a new exploit for OpenSSH is discovered.
The latest version of PuTTY as of this writing is beta 0.52 (they're all betas to date.) Check here to see if a newer version is available.
It's a good idea to subscribe to the putty-announce mailing list for announcements of new versions.
Overview of SSH technologies
Symmetric and asymmetric cryptography
Again, this is by no means a complete discussion; just enough to move forward. The discussion is quite simplified.
In symmetric cryptography, the same key is used to encrypt and decrypt the data.
In asymmetric cryptography, also known as public key cryptography, a pair of keys known as the private key and the public key are used. Data encrypted by the private key can only be decrypted by the public key, and vice versa. This allows us to publicly publish the public key (hence the name,) and allow a remote site and/or user to encrypt data or us with our public key. Only we can decrypt it.
For a given level of security (that is, computation difficulty in decrypting the session,) asymmetric cryptography is much slower than symmetric cryptography. In order to speed things up, asymmetric cryptography is used in ssh to exchange a key for symmetric encryption; the remainder of the session is then symmetrically encrypted.
SSH functionality
"ssh
" stands for "secure shell." The
ssh
family of tools consists of clients and servers which,
when used properly, provide secure, encrypted access to remote systems
over insecure IP networks (i.e.: the Internet.) ssh
is a
replacement for tools such as telnet
and rlogin
,
which transmit passwords and data unencrypted, and thus, are
succeptible to packet sniffing and "man-in-the-middle
attacks," where an impostor masquerades as your desired remote
host, steals your authentication, and possibly rewrites your
interactions with the remote server.
"Shell" refers to a command interpreter, such as
sh
, csh
, etc. on Unix-like operating systems (or
command.com
and cmd.exe
on DOS/Windows systems.)
Here, I will only discuss connecting to Unix servers.
ssh
, in addition to allowing remote interactive sessions,
also allows you to send individual remote commands to a remote system,
and also (via scp
and sftp
, to be discussed later)
to copy files securely to and from the remote system.
ssh
can authenticate to a remote system either by securely
passing your remote password, or by using asymmetric (public key)
cryptography. The latter is preferable. Here, you have a personal
private and public key, and install your public key in your account on
the remote host. Then, instead of a simple password, you authenticate
by passing a message to the remote host that is encrypted with your
private key. To get the full benefit of this security, keys must be
managed properly. This will be discussed later in this document.
ssh also uses asymmetric cryptography to verify that the remote host (system) is in fact the remote host we wish to connect to, and not some other host pretending to be our remote host. To do this, each host has a host key, which is a private/public key pair as discussed previously. When an ssh client begins negotiation with an ssh server to establish a connection, the server sends its public host key, which is then used to encrypt subsequent session setup. If we know the correct public host key in advance, we can detect someone attempting to masquerade as our remote host, and terminate the session.
For users of the X Window System, X sessions can be forwarded over ssh connections, so that you can securely run X applications from the remote host on your local system.
Extra power, functionality, and security hazards become available
to you with the use of an "agent," which allows you to load
your ssh
private key into memory, and use these to connect to
any system that private key will authenticate.
Versions, versions, versions
This can get rather confusing…
ssh client and server versions
First of all, there's the version of the ssh application itself.
For OpenSSH, ssh -V
will tell you which version you're running.
To see which version of PuTTY you have, you need to open a session
window, select the system menu (upper left-hand corner,) and select
"About PuTTY". You can do this by selecting
localhost
as the host; you'll most likely get
"Connection refused" but you can then access the system menu
in the inactive PuTTY window to get the version.
Protocol versions
There are two different versions of the ssh protocol: version 1 and version 2. Version 2 is generally considered to be more secure, but it has been a topic of debate in the past.
OpenSSH 3.4 and PuTTY beta 0.52 support both protocol versions.
If you restrict usage to protocol version 2 (or 1, for that matter,) you eliminate a family of "man-in-the-middle" attacks that take advantage of users using one protocol version by causing the session to change to the other version. This way, you won't get the big scary warning that the host key has changed; instead, you'll get the more inocuous message that the host key is unknown.
Public key versions
There are three types of public keys currently in use with OpenSSH. The following table shows terminology used by OpenSSH and PuTTY:
OpenSSH | PuTTY |
---|---|
rsa1 | SSH1 (RSA) |
rsa | SSH2 (RSA) |
dsa | SSH2 (DSA) |
rsa1
can only be used with protocol version 1.
rsa
and dsa
can only be used with protocol
version 2. The relative strengths and weaknesses of these two is a
source of constant debate; however, at this time, there's no proven
practical method of cracking either one. I usually use dsa
,
but rsa
is fine also.
Regardless, use at least a 1024-bit key. Some are tending now towards 2048 bits. The larger the key, the longer it will take the client and server to use them.
OpenSSH clients
ssh
Typical usage:
ssh
user@
host
…where host is the remote host you wish to connect
to, and user is your username on the remote host. If your
username on the remote host is the same as on the computer you're
ssh
ing from, then you may omit user@
.
localhost
is a valid host; this can be very useful in
conjunction with an agent (more on that later.)
You can also run a single command on the remote host by specifying
a command after the ssh
invocation. Example:
ssh foo.com ps
This runs the command ps
on foo.com
; the
standard output and standard error from the ps
command on the
remote machine are securely transmitted back to your local process.
This leads to a whole new universe of possibilities, most of which
will be left to your imagination. But, here's an example just to
demonstrate what you can do. Here, I'll get /etc/passwd
from
host chester
and sort it locally by UID, then run that
through more
to view it.
ssh chester cat /etc/passwd | sort -t: -nk3 | more
Perhaps I'd prefer to do the sort over on chester instead. A little careful quoting will take care of that:
ssh chester 'cat /etc/passwd | sort -t: -nk3' | more
Other possibilities are left as an exercise for the reader.
scp
scp
, as in "secure copy," allows for the secure
copying of files to and from remote hosts. If you can handle
cp
, then you should be able to handle scp
. man
scp
for the details.
One caveat: you will not be able to scp
from one remote
host to another remote host (that is, copying files between system A
and B when you're running scp
from system C) without using an
ssh agent.
sftp
sftp
, as in "secure FTP" is a secure replacement
for FTP. Like scp
, it uses ssh transport; however, the user
interface is very similar to ftp
, so (command-line) FTP users
should feel pretty comfortable using this.
rsync
rsync
is not part of the OpenSSH package, but it so widely
used, it bears mention here.
rsync
, a tool for
efficiently "mirroring" directories (that is, keeping a
local directory tree in sync with a remote tree, or vice versa) is a
much more versatile and powerful tool than scp, and it can also
utilize ssh for transport by specifying rsync -e ssh
.
Some versions of rsync use ssh transport by default, but it doesn't
hurt to explicitly specify it.
Note that you can't use ssh transport with an rsync server (where
you specify host::
path as the path; note the
two colons.)
I rarely use scp
anymore, unless on a machine without
rsync
installed.
Note that rsync
does not do remote-to-remote transfers;
you'll need to login to either the source or destination machine to do
the rsync (although you can pass rsync
as a remote command
via ssh
; you don't have to open an interactive session.)
Using public keys with OpenSSH
ssh-keygen
As mentioned previously, SSH permits you to authenticate to a
server using public key cryptography. In order to do this, first you
must create a key. ssh-keygen
is the tool that generates SSH
keys.
You can find the usage synopsis in the manpage. Here, I'll do a more "concrete" example:
$ ssh-keygen -t dsa -C ron-30jul2002 -f ron-30jul2002
Generating public/private dsa key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ron-30jul2002.
Your public key has been saved in ron-30jul2002.pub.
The key fingerprint is:
4b:3e:c1:f8:45:c4:42:f5:6d:9f:78:7d:b5:19:e8:e8 ron-30jul2002
The "passphrase" is the "password" for the private key being generated. The security of the entire operation can hinge on a good choice of passphrases here: if your private key ever falls into the wrong hands (e.g.: your system is hacked somehow, or you leave the floppy with your key pair in the wrong place,) the strength of your passphrase will determine how long the key can survive before being brute-force cracked… thus giving the attacker access to every user account that allows this key pair to authenticate. Here, you have to balance between convenience and security.
My root access keys have passphrases that read like long drunken rants with a badly malfunctioning keyboard; they're at least several words long, and have symbols, numbers, and misspellings interspersed throughout, along with words that weren't in the original human phrase at all. My personal keys are shorter, but still longer than the typical password. I typically use an SSH agent, so I only have to type them once per session.
When dreaming up your next crazy passphrase, remember:
- I typically take a phrase and beat the hell out of it (symbols, typos, etc.) I DON'T use a phrase I would normally use, nor anything particularly "popular" at the moment.
- Do put a few symbols in the mix and mix the case up a little. Just lowercase reduces the solution space a lot; it's typically the first thing tried.
- Don't rely exclusively on "lamer-speak" substitutions such as 3l337 for 'elite', etc.; these are well-known. That being said, it's not a bad thing to throw a couple in along with the mix.
- Once you create your new crazy passphrase, be sure to try it several times in a row to make sure it's properly "burned in." Otherwise, you risk inflicting a denial-of-service attack on yourself when you can't login anymore because you forgot your tough passphrase.
-t
specifies the key type: either rsa1
,
rsa
, or dsa
.
-C
specifies a comment for the key; -f
specifies
the filename for the private key (the public file is the same as the
private key, with a .pub
extension. If you don't specify a
filename, it will default to a filename in your ~/.ssh
directory;
ssh
will look for these "default" files when
establishing connections. If it finds a key, it will ask for the
passphrase.
I avoid using the defaults, because (a) I usually use an agent to avoid having to type in the passphrase for each session, and (b) it's a good idea to change out your keys from time to time, depending on your level of security-consciousness (it's not paranoia… the script kiddies really are out to get you.) The comment and filename help to keep track of the keys, so I know I'm using the correct one.
~/.ssh/authorized_keys
This file holds all the public keys that are allowed to access the
account for this user. It must be in Unix textfile format, not DOS,
and must be one public key per line. Also note that the
~/.ssh
directory must be owned by the user who's home
directory it resides in (i.e.: if /home/roliver is owned by roliver,
then /home/roliver/.ssh must be also,) and must have no permissions
granted to group or other (i.e.: ls -ld ~/.ssh
will show
drwx------
.) Your private keys also must not be readable nor
writable by anyone except their owner.
ssh-agent
Your patience in reading through all this and taking "I'll explain the agent later" on faith will now be rewarded. If you're skipping to this section and haven't read the rest, at least go back to the top and read the Disclaimer again.
An SSH agent holds private keys in memory. When client programs need to authenticate, they have the agent do the authentication for them. The private key is never transmitted across the network. However, the unencrypted private key is in memory, and thus, could be read from memory by a process running as the user, or root.
There are two different ways to start ssh-agent
:
eval `ssh-agent` # backquotes
ssh-agent
command [args] …
In the first case, ssh-agent
is forked off. It will print
environment variable settings to stdout like so:
SSH_AUTH_SOCK=/tmp/ssh-XX1Hlb4e/agent.4607; export SSH_AUTH_SOCK; SSH_AGENT_PID=4608; export SSH_AGENT_PID; echo Agent pid 4608;
Hence, the eval
to make the shell interpret this output.
With the environment variables set properly, ssh
and friends
can find the agent and use it to authenticate. You need to be careful
with this method, as the agent will not automatically be killed
when you exit this shell (at least, ssh-agent
doesn't kill
itself when this happens.)
To kill an ssh-agent
started by the first method:
eval `ssh-agent -k`
This will kill the agent and unset all the ssh-agent
environment variables.
In the second case, ssh-agent
is the parent of
command
; it sets up the environment for command
, and
exits when command
exits. I use this version to start my X
session. I can then use the agent from any shell window I open, and
when I logout of my X session, the agent dies.
ssh-add
ssh-add
is used to add, delete, and list keys that
ssh-agent
has available.
- To add a key to the agent:
ssh-add
path-to-private-key - To delete a key from the agent:
ssh-add -d
path-to-private-key - To delete all keys from the agent:
ssh-add -D
path-to-private-key - To list all keys currently loaded:
ssh-add -l
man ssh-add
for all options available.
OpenSSH server: sshd
sshd
is the OpenSSH daemon, or server, program.
I'm not going to cover this in much detail, but I will point out a few
security-related issues to read more on.
I suggest that you read through the manpages for sshd
and
sshd_config
at least once. You may have issues at your local
site that are not addressed in this document.
man sshd
to read more on these issues:
- If you want to restrict keys to only be accepted from certain hostnames, read the section "AUTHORIZED_KEYS FILE FORMAT".
- Best bet: build up your public
/etc/ssh/ssh_known_hosts
files with the public keys of all your servers, and deploy this file across all your servers. I do this with a script that also addslocalhost
for the particular server, sossh localhost
doesn't makessh
say the host key is unknown. I do that in a script by prepending "localhost,127.0.0.1,
" to the line corresponding to the machine the file is being copied to.
man sshd_config
to read more on these issues:
- ListenAddress: you can use this to restrict
sshd
to only listen on particular network interfaces. If you don't need to connect to your servers from the Internet, this can protect you even in the event that a new remote exploit is discovered. - PasswordAuthentication: if everyone uses public keys for authentication, set this to 'no' and make it impossible for some kiddie to get in, even if he or she discovers a user's login password.
- PermitRootLogin: I set this to "without-password," which
means you cannot login as root with a password. You can,
however, login using public key authentication with any keys that are
installed in root's
~/.ssh/authorized_keys
. - Protocol: specifies which protocol versions are supported.
If your client software all supports version 2, then put…
Protocol 2
…in your/etc/ssh/sshd_config
file. This will prevent use of protocol 1 (which you'll never notice if all your clients support protocol 2,) which protects you from the sneaky man-in-the-middle attack mentioned previously.
Host key messages and what they mean
The authenticity of host … can't be established
$ ssh spiff
The authenticity of host 'spiff (172.30.0.12)' can't be established. RSA key fingerprint is 3a:12:80:11:66:fc:c4:b0:36:75:8a:2d:14:ce:61:37. Are you sure you want to continue connecting (yes/no)?
This means that the local system doesn't have a copy of spiff's
public key in either /etc/ssh/ssh_known_hosts
or
~/.ssh/known_hosts
, so it doesn't know if it's really talking
to spiff… or a man in the middle.
It could also be more sinister: you usually use protocol version 2,
but you have an attacker intercepting your communications. He's
told your ssh
that he doesn't speak protocol v2, only protocol
v1. If you only use protocol v2, and thus don't have the host key for
protocol v1, you won't have the key, and you'll never know the
difference.
This threat can be reduced by placing the following in
/etc/ssh/ssh_config
:
Protocol 2
Unless the user overrides it, this will prevent ssh
from
using protocol version 1.
The safest bet is to talk to someone reliable that can access that system, and have them run
ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub
If the fingerprint matches what's above, type 'yes' and Enter and
you're done. If you follow my suggestion above about managing your
/etc/ssh/ssh_known_hosts
, you wouldn't get these messages.
Unsafe (but better than nothing) self-check
If you can't get someone there, you can do the next best thing and run it yourself. A really crafty man-in-the-middle could burn you on this, but it's unlikely. Of course, now that I've written this, some jerk may write an exploit that watches for you trying this… caveat emptor.
$ ssh spiff ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub
The authenticity of host 'spiff (172.30.0.12)' can't be established.
RSA key fingerprint is 3a:12:80:11:66:fc:c4:b0:36:75:8a:2d:14:ce:61:37.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'spiff,172.30.0.12' (RSA) to the list of known hosts.
1024 3a:12:80:11:66:fc:c4:b0:36:75:8a:2d:14:ce:61:37 /etc/ssh/ssh_host_rsa_key.pub
This is perhaps a little confusing.
ssh-keygen -lf /etc/ssh/ssh_host_rsa_key.pub
…prints the fingerprint of the key specified on the command line.
So, we ran this command over ssh
to print out the remote
host's key fingerprint. The last line in the message above is the
output from ssh-keygen -l
, which had better match the
fingerprint from the warning message.
WARNING: as mentioned above, it is possible for an attacker to circumvent this technique! I've mentioned this technique here because (a) it's better than blindly accepting the key, (b) there are times when you need remote access now, and you're willing to take the (small) chance that someone is aggressively trying to gain access to your system in order to get your work done.
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!
$ ssh spiff
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY! Someone could be eavesdropping on you right now (man-in-the-middle attack)! It is also possible that the RSA host key has just been changed. The fingerprint for the RSA key sent by the remote host is 3a:12:80:11:66:fc:c4:b0:36:75:8a:2d:14:ce:61:37. Please contact your system administrator. Add correct host key in /home/roliver/.ssh/known_hosts to get rid of this message. Offending key in /home/roliver/.ssh/known_hosts:4 RSA host key for spiff has changed and you have requested strict checking. Host key verification failed.
It's yelling at you for a reason. Pay attention. One of the following happened (in order of likelihood):
- The sysadmin upgraded the system, or deployed a new system at the same domain name and/or IP address, and didn't preserve the original host key. This isn't necessarily a bad thing… but if you, the sysadmin, do this, it's a really good idea to notify people that this has happened, along with the new host key fingerprint, in a spoof-resistant place where people can verify it. You don't want to do this via E-mail, since E-mail is so readily forged.
- There's a man in the middle trying to intercept your communications.
- There was a man in the middle who is now gone. Ouch.
PuTTY
PuTTY is an excellent ssh client set for Win32 platforms. It includes:
putty.exe
: the interactive SSH client, which can also do telnet.puttytel.exe
: the telnet-only version ofputty.exe
, for use in crypto-restricted environments.plink.exe
: the command-line SSH client, for passing commands to remote hosts.pscp.exe
: command-line scp client.psftp.exe
: command-line sftp client.pageant.exe
: PuTTY's ssh-agent. This is a GUI application, which runs in the "tray". It has allssh-agent
andssh-add
functionality in one convenient package.puttygen.exe
: tool to generate RSA and DSA keys.
PuTTY's documentation is excellent, and I'm not going to rehash it here. Hopefully, you're now empowered with a clue about ssh technology, which should make the reading go much faster.
One thing worth mentioning: in puttygen
, after
successfully generating a key, you will need to select the entire
field entitled "Public key for pasting into OpenSSH authorized_keys2
file" and save that as your OpenSSH public key. PuTTY's public
key file format will not work with OpenSSH, nor vice-versa.
Notes on above:
- In
~/.ssh
, there used to be anauthorized_keys
for protocol version 1 keys andauthorized_keys2
for protocol version 2 keys. They all go intoauthorized_keys
now;authorized_keys2
is deprecated. - The latest PuTTY snapshot versions support OpenSSH keys, but I generally don't recommend using snapshot versions for "real" work. I've found it to be only a minor hassle to have to have one public key for OpenSSH and another for PuTTY.
I've never found a reason to save PuTTY's public key. You can get it out of the private key file later if you find you need it.
Epilogue
I hope this was a useful introduction to the ssh world for you. If not, or if you have anything to add/subtract/etc, feedback is welcome. E-mail to feedback@openesque.com.
Ron Oliver, Manager
Openesque LLC
September 5, 2004 (original July 30, 2002)