Introduction to OpenSSH (and PuTTY)
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.
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 firstname.lastname@example.org.
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
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" 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
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
csh, etc. on Unix-like operating systems (or
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
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
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.
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.
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:
rsa1 can only be used with protocol version 1.
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
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.
…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
sshing 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
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
chester and sort it locally by UID, then run that
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, 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 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
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 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
I rarely use
scp anymore, unless on a machine without
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
ssh; you don't have to open an interactive session.)
Using public keys with OpenSSH
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
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:
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
-C specifies a comment for the key;
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 will look for these "default" files when
establishing connections. If it finds a key, it will ask for the
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.
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.
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
eval `ssh-agent` # backquotes
ssh-agentcommand [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;
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
In the second case,
ssh-agent is the parent of
command; it sets up the environment for
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 is used to add, delete, and list keys that
ssh-agent has available.
- To add a key to the agent:
- To delete a key from the agent:
- To delete all keys from the agent:
- To list all keys currently loaded:
man ssh-add for all options available.
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_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_hostsfiles with the public keys of all your servers, and deploy this file across all your servers. I do this with a script that also adds
localhostfor the particular server, so
ssh localhostdoesn't make
sshsay 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
sshdto 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
- Protocol: specifies which protocol versions are supported.
If your client software all supports version 2, then put…
/etc/ssh/sshd_configfile. 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 spiffThe 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
~/.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
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
This threat can be reduced by placing the following in
Unless the user overrides it, this will prevent
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
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 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 of
putty.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 all
ssh-addfunctionality 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
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:
~/.ssh, there used to be an
authorized_keysfor protocol version 1 keys and
authorized_keys2for protocol version 2 keys. They all go into
- 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.
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 email@example.com.