A few years ago, Finnish programmer Tatu Ylönen created a
terrifically useful application called the Secure Shell, or SSH.
SSH is a suite of tools that roughly
correspond to Sun’s
but with one very important difference: paranoia. SSH lets you do
rlogin do, using your choice of
libertarian-grade encryption and authentication methods.
But there was a catch: SSH Version 1 relied heavily on RSA — an excellent but, until very recently, encumbered (patented) technology whose owners required that any application that used it be licensed unless used in noncommercial settings. (Even in noncommercial use, SSH’s legality was murky, especially in the U.S.). But wait, RSA’s U.S. patents expired in September 2000 — problem solved, right?
Almost: Tatu’s got to earn a living, so by the time RSA became less encumbered, SSH itself had become more so as his company, SSH Communications Security, tightened the licensing reins. In fact, beginning with SSH Version 2.0, unlicensed/free commercial use (irrespective of RSA issues) was no longer permitted. All this despite Tatu’s sincere desire that SSH become an Internet standard, one of the requirements of which is that at least one free implementation be available.
SSH Communications Security eventually reloosened the licensing reins with SSH v.2.3, making it free even for commercial use if run on Linux, FreeBSD, NetBSD, and OpenBSD, and returning the right to free use to all noncommercial users regardless of the operating system.
But by this time, Aaron Campbell, Bob Beck, Markus Friedl, Niels Provos, Theo de Raadt, Dug Song, and others on the OpenBSD team had taken matters into their own hands. OpenBSD, of course, is the secure-by-default offshoot of NetBSD, which, in turn, is a free version of BSD Unix. Theo and our open source brethren in the OpenBSD project wanted to include SSH in OpenBSD 2.6, but were wary of SSH’s various encumbrances. When they learned that the Swedish programmer Björn Grönvall had released an improved version of SSH 1.2.12 called “OSSH” (1.2.12 was, at the time, the last completely-free-except-for-RSA version of Ylönen’s SSH), the OpenBSD guys rapidly got to work on updating and adapting OSSH for a larger audience. Their version, OpenSSH, has been part of OpenBSD ever since and is now portable to most Unices.
OpenSSH built on Grönvall’s OSSH work, adding support for later versions of the SSH protocol and modularizing its cryptographic mechanisms in such a way that it’s possible to compile OpenSSH without any patented algorithms whatsoever (i.e., without support for SSH v.1 protocols, which depend on RSA). The other innovation the OpenBSD team brought was the forking of the OpenSSH code base into a “clean” version, which is kept as simple and platform independent as possible, and a “portable” version, which can be compiled for a variety of Unices besides OpenBSD.
This last innovation is of particular note to Linux users: the clean version is kept that way to maximize the code’s “auditability,” ensuring that it’s fundamentally stable and secure. Only after this code is blessed by Theo and Markus (righteous paranoiacs) are portability enhancements added. Thus, we benefit from a software package that is both extremely secure and 100% Linux compatible.
By the way, less than two months passed between the time the OpenBSD crew discovered OSSH and the time they released OpenSSH 1.2.2; in addition, only 6.5 months after that, they released the fully portable and SSH v.2-compatible OpenSSH 2.0. Even considering that they were building on Ylönen’s and Grönvall’s work, this is a remarkable achievement, especially considering the quality of the end product and the fact that nobody gets paid for it!
So that’s the story of SSH and OpenSSH so far. I hope you agree that it’s a pretty compelling one, as notable as is OpenSSH itself. Indeed, OpenSSH has very rapidly become the preferred version of SSH for open source Unices: as of this writing, the latest releases of Red Hat, Debian, and SuSE Linux all ship with binary packages of OpenSSH.
“SSH v.1.x” and “SSH Protocol v.1” refer to SSH’s software release and protocol, respectively, and are not really synonymous. But since the package and protocol major version numbers roughly correspond, from here on in I’ll use “SSH v.1x” to refer to RSA-based versions of SSH/OpenSSH and “SSH v.2x” to refer to versions that support both RSA and DSA.
Secure Shell works very similarly to Secure Sockets Layer web transactions (it’s no coincidence that the cryptographical functions used by OpenSSH are provided by OpenSSL, a free version of Netscape’s Secure Sockets Layer source-code libraries). Both can set up encrypted channels using generic " host keys” or with published credentials ( digital certificates) that can be verified by a trusted certificate authority (such as VeriSign). Public-key cryptography is discussed further later in this chapter, but here’s a summary of how OpenSSH builds secure connections.
First, the client and the server exchange (public) host keys. If the client machine has never encountered a given public key before, both SSH and most web browsers ask the user whether to accept the untrusted key. Next, they use these public keys to negotiate a session key, which is used to encrypt all subsequent session data via a block cipher such as Triple-DES (3DES), blowfish, or IDEA.
As its name implies, a session key is created specifically for a given session and is not used again after that session closes. Host and user keys, however, are static. You might wonder, why not just use host or user keys to encrypt everything? Because the algorithms used in public-key cryptography are slow and CPU-intensive. Why not use the same session key for multiple sessions? Because unique session keys require more work for an attacker who attempts to crack multiple sessions.
As with typical SSL connections, this initial round of key exchanging and session-key negotiation is completely transparent to the end user. Only after the encrypted session is successfully set up is the end user prompted for logon credentials.
By default, the server attempts to authenticate the client using RSA or DSA certificates (key pairs). If the client (user) has a certificate recognized by the server, the user is prompted by their client software for the certificate’s private-key passphrase; if entered successfully, the certificate is used by the SSH client and server to complete a challenge-response authentication, which proves to the server that the client possesses the private key that corresponds to a public key registered with the server. At no point is the private key itself, its passphrase, or any other secret data sent over the network.
Also by default, if RSA/DSA authentication fails or if there is no client certificate to begin with, the user is prompted by the remote server for a standard Unix username/password combination that is valid for the remote system. Remember, an encrypted session has already been established between client and server, so this username/password combination, while easier to subvert or guess than certificate-based authentication, is at least encrypted prior to being transmitted to the server.
Finally, after successful authentication, the session proper begins: a remote shell, a secure file transfer, or a remote command is begun over the encrypted tunnel.
As mentioned earlier, SSH is actually a suite of tools:
The daemon that acts as a server to all other SSH commands
The primary end-user tool; used for remote shell, remote command, and port-forwarding sessions
A tool for automated file transfers
A tool for interactive file transfers
Generates private-public key pairs for use in RSA and DSA authentication (including host keys)
A daemon used to automate a client’s RSA/DSA authentications
Provides an X Windows interface for
Of these tools, most users concern themselves only with
Telnet” is the simplest use of SSH.
however, along with the strong authentication and
port-forwarding capabilities of
ssh itself, make
SSH considerably more flexible than that. Since
we’re paranoid and want to encrypt as much of the
stuff we fling over networks as possible, we leverage this
flexibility as fully as we can.
The URL for OpenSSH’s web
site is http://www.openssh.com.
This is the place to go for the
version of OpenSSH, both in source-code and RPM forms, and also for
OpenSSL, which is required by OpenSSH.
Also required is
, available at ftp://ftp.freesoftware.com/pub/infozip/zlib.
You may or may not get by with RPM packages, depending mainly on whether the RPMs you wish to install were created for your distribution (Mandrake, Red Hat, SuSE, and a number of other distributions can use RPMs, but not always interchangeably). If your distribution doesn’t provide its own OpenSSH RPMs, even in a “contrib.” (end-user contributed) directory, you’re best off compiling OpenSSH from source.
To Linux old timers, “rolling your
own” software installations is no big deal; but if
you’re not in that category, don’t
despair. All three distributions use
scripts that eliminate the need for most users to edit any Makefiles.
Assuming your system has gcc and the normal assortment of system
libraries and that these are reasonably up-to-date, the build process
is both fast and simple.
In my own case, after installing OpenSSL 0.9.5a and zlib-1.1.3 (all version numbers, by the way, may be outdated by the time you read this!), I followed these steps to build and install OpenSSH 2.9p1:
tar -xzvf openssh-2.9p1.tar.gz cd openssh-2.9p1 ./configure --sysconfdir=/etc/ssh make make install
Note that in the third line of the previous code listing, as per
instructions provided by the file
INSTALL, I fed
the configure script one customized option: rather than installing
all configuration files in
/etc, I instructed it
to create and use a subdirectory,
Since this version of OpenSSH supports both
RSA and DSA keys and since each type of
key is stored in its own
file, it makes sense to minimize the
amount of clutter SSH adds to
/etc by having SSH
keep its files in a subdirectory.
Be diligent in keeping up with the latest version of OpenSSH and, for that matter, all other important software on your system! Security software tends to bear enough scrutiny to be updated frequently, or at least it’s supposed to be. Over the past year or two, major revisions of OpenSSH have been released every few months.
(Lest you think this is due to sloppy programming in need of frequent fixing, I assure you that in this case, it’s actually indicative of the OpenSSH team’s paranoia, finickiness, and ongoing lust for perfection.)
If you wish to run the Secure Shell Daemon
sshd (i.e., you wish to accept
ssh connections from remote hosts),
you’ll also need to create startup scripts and, in
the case of SuSE, edit
/etc/rc.config. This has
also been thought of for you: the source
directory contains some useful goodies.
contrib/redhat directory contains
sshd.init, which can be copied to
/etc/rc.d and linked to in the appropriate
runlevel directory (
/etc/rc.d/rc2.d, etc.). It
sshd.pam, which can be installed
/etc/pam if you use
Modules (PAM), and also
openssh.spec, which can
be used to create your very own OpenSSH RPM package. These files are
intended for use on Red Hat systems, but will probably also work on
Red Hat-derived systems (Mandrake, Yellow Dog, etc.).
contrib/suse directory also contains an
openssh.spec file for creating OpenSSH RPM
packages for SuSE and an
rc.sshd file to install
/sbin/init.d in SuSE). In addition, it contains
rc.config.ssd, the contents of which must be
/etc/rc.config for the
rc.sshd script to work properly. This is
achieved by simply entering the following command:
cat ./rc.config.ssd >> /etc/rc.config
Create a symbolic link in
rc3.d, and your SuSE system is ready to serve up
secured shells! Either reboot or type
/etc/rc.d/rc.sshd start to start the daemon.
The simplest use of ssh is to run interactive shell sessions on remote systems with Telnet. In many cases, all you need to do to achieve this is to install ssh and then, without so much as looking at a configuration file, enter the following:
You will be prompted for a password (ssh assumes you wish to use the same username on the remote system as the one you’re currently logged in with locally), and if that succeeds, you’re in! That’s no more complicated yet much more secure than Telnet.
If you need to use a different username on the remote system than
you’re logged in with locally, you need to add it in
front of the hostname as though it were an email address. For
example, if I’m logged on to my laptop as
mick and wish to
kong-fu.mutantmonkeys.org as user
mbauer, I’ll use the command
listed in Example 4-1.
I keep saying ssh is more secure than Telnet, but how? Nothing after the ssh login seems different from Telnet. You may be asked whether to accept the remote server’s public key, it may in general take a little longer for the session to get started, and depending on network conditions, server load, etc., the session may seem slightly slower than Telnet; but for the most part, you won’t notice much difference.
But remember that before ssh even prompts you for a password or
passphrase, it has already transparently negotiated an encrypted
session with the remote server. When I do type my username and
password, it will be sent over the network through this encrypted
session, not in clear text as with Telnet.
Furthermore, all subsequent shell-session data will be encrypted as
well. I can do whatever I need to do, including
-, without worrying about eavesdroppers. And all it costs
me is a little bit of latency!
2.0 of SSH, Tatu Ylönen introduced a new feature:
sftp is built in to
sshd. In other words, it’s
hardcoded to invoke the
sftp-server process when
needed; it isn’t necessary for you to configure
anything or add any startup scripts. You don’t even
need to pass any flags to configure at compile time.
Note, however, that
sftp may or may not be
supported by hosts to which you wish to connect.
It’s only been fully supported in OpenSSH since
OpenSSH v. 2.9. If a host you need to transfer files to or from
you’ll need to use
sftp client is just as simple as using
ssh. As mentioned earlier, it very closely
resembles “normal” ftp, so much so
that we needn’t say more about it right now other
than to look at a sample
sftp cruellerConnecting to crueller... mick@crueller's password: sftp>
dirdrwxr-x--- 15 mick users 1024 May 17 19:35 . drwxr-xr-x 17 root users 1024 May 11 20:02 .. -rw-r--r-- 1 mick users 1126 Aug 23 1995 baklava_recipe.txt -rw-r--r-- 1 mick users 124035 Jun 10 2000 donut_cntrfold.jpg -rw-r--r-- 1 mick users 266 Mar 26 17:40 blintzes_faq -rw-r--r-- 1 mick users 215 Oct 22 2000 exercise_regimen.txt sftp>
get blintzes_faqFetching /home/mick/blintzes_faq to blintzes_faq sftp>
put bakery_maps.pdfUploading bakery_maps.pdf to /home/mick sftp>
command, in most ways equivalent to the
rcp utility, is used to copy a file or
directory from one host to another. (In fact,
scp is based on
rcp’s source code.) In case
you’re unfamiliar with either,
they’re noninteractive: each is invoked with a
single command line in which you must specify the names and paths of
both what you’re copying and where you want it to
This noninteractive quality makes
less user friendly than
sftp, at least for
inexperienced users: to use
scp, most people
need to read its manpage (or books like this!). But like most other
scp is far more useful
in scripts than interactive tools tend to be.
The basic syntax of the
scp command is:
[options] sourcefilestring destfilestring
where each file string can be either a normal Unix file/path string
/home/me/mydoc.txt, etc.) or a host-specific
string in the following format:
For example, suppose I’m logged into the host
crueller and want to transfer the file
recipe to my home directory on the remote host
kolach. Suppose further that
I’ve got the same username on both systems. The
session would look something like Example 4-2 (user
input in bold).
Example 4-2. Simple scp session
scp ./recipe kolach:~
*******recipe 100% |****************************>| 13226 00:00 crueller: >
After typing the
scp command line, I was
prompted for my password (my username, since I
didn’t specify one, was automatically submitted
scp then copied the file over, showing me a
handy progress bar as it went along.
Suppose I’m logged on to
mick, but have
kolach, and I wish to write the file to
/data/recipes/pastries directory. Then my
command line would look like this:
scp ./recipe mbauer@kolach:/data/recipies/pastries/
Now let’s switch things around. Suppose I want to
retrieve the file
kolach (I’m still logged in to
crueller). Then my command line looks like this:
scp mbauer@kolach:/etc/oven.conf .
Get the picture? The important thing to remember is that the source must come before the destination.
isn’t at all complicated. To control the behavior of
the SSH client and server, there are only two files to edit:
, respectively. Depending on the package
you installed or the build you created, these files are either in
/etc or some other place you specified using
./configure --sysconfdir (see
“Getting and Installing OpenSSH,”
earlier in this chapter).
ssh_config is a global configuration file for
ssh sessions initiated from the local host. Its
settings are overridden by command-line options and by
users’ individual configuration files (named, if
$HOME/.ssh/config). For example, if
/etc/ssh/ssh_config contains the line:
but the file
/home/bobo/.ssh/config contains the
then whenever the user “bobo” runs ssh, compression will be disabled by default. If, on the other hand, bobo invokes ssh with the command:
ssh -o Compression=yes
then compression will be enabled for that session.
In other words, the order of precedence for ssh options is, in
decreasing order, the ssh command-line invocation,
ssh_config consists of a list of parameters, one
line per parameter, in the format:
In other words, a parameter and its first value are separated by
whitespace and additional values are separated by commas. Some
parameters are Boolean and can have a value of either
“no.” Others can have a list of
values separated by commas. Most parameters are self-explanatory, and
all are explained in the
ssh(1) manpage. Table 4-1 lists a few of the most useful and important
ones (italicized text indicates possible values).
Table 4-1. Important ssh_config parameters
Whether to notice unexpected source IPs for known host keys. Warns user each time discrepancies are found.
Which block cipher should be used for encrypting ssh v.1 sessions.
Whether to use
Whether to redirect X connections over the encrypted tunnel and to set DISPLAY variable accordingly. Very handy feature!
Whether to attempt (encrypted) Unix password authentication in addition to or instead of trying RSA/DSA.
There are many other options in addition to these; some of them are
covered in Section 4.3 (later in this chapter). Refer to the
ssh(1) manpage for a complete list.
Like the ssh client, sshd’s default behavior is
configured in a single file,
resides either in
/etc or wherever else you
specified in SSH’s configuration directory. As with
the ssh client, settings in its configuration file are overridden by
command-line arguments. Unlike ssh, however, there are no
configuration files for the daemon in individual
users’ home directories; ordinary users
can’t dictate how the daemon behaves.
Table 4-2 lists just a few of the things that can
be set in
Table 4-2. Some sshd_config parameters
TCP port on which the daemon should listen. Being able to change this is handy when using Port Address Translation to allow several hosts to hide behind the same IP address.
Whether to accept root logins. This is best set to
Whether to allow (encrypted) username/password authentication or to insist on DSA- or RSA-key-based authentication.
Whether to allow accounts to log in whose system password is empty.
Does not apply if
Whether to allow clients to run X Windows applications over the SSH tunnel.[a]
[a] There really is nothing to be gained by
There are many other parameters that can be set in
sshd_config, but understanding the previous
concepts is enough to get started (assuming your immediate need is to
replace Telnet and ftp). See the
for a complete reference for these parameters.