Although "ssh" stands for "Secure Shell", it is not a shell like
sh, csh or ksh. Rather, think of it as a way to secure your
shell, whatever it is. Secure in this context means encrypted
conversations between your machine and some other machine, and
that's just about all it means: it doesn't mean that your system or
even the system you are ssh'ing to are immune to break-ins or other
security breaches and it doesn't necessarily even mean that you can
be 100% sure that you really are even connected to the machine you
think you are connected to (though you can be pretty sure- more on
that below). Encrypted connections are really all that ssh does-
everything else that the ssh suite includes, like the ability to
copy files or run remote commands, is really just tools added to
use the encrypted communications channel.
Why do you care about encryption? Well, because the standard
Unix tools like telnet and ftp are not encrypted- everything you
type, including your precious passwords, travels in packets that
can at least potentially be seen by every machine they pass by or
through. Even if you aren't protecting anything especially
sensitive, it's not a good idea to have your passwords traveling
the network (internal or the Internet) in plain sight for anyone to
see. With ssh, that's not true- if you use passwords, they will be
encrypted. You can also use ssh so passwords aren't used at all- so
that it uses public key cryptography to authenticate you. In that
case, everything is still encrypted, but no passwords are passed at
all (see below for more explanation of this).
This article primarily discusses OpenSSH. If you are using
SSH1 or SSH2, some of what is covered here will not apply to you or
may have slightly different syntax. Linux and BSD systems generally
include ssh by default; if you need SCO binaries, see Where can I get ssh?.
There are other tools that do similar things to ssh. For
example, Kerberos is an authentication system that is fairly
popular, and may become even more so due to Windows 2000's use of
it. IPSEC is very low level authentication and encryption; it moves
the responsibilities for this to the IP stack itself: programs like
telnet and ftp are just used as they would be normally; the
encryption and decryption is completely transparent to users. There
are other less well known or related tools also. At one time, for
example, PGP signatures and file encryption were a pretty common
sight- but PGP is file oriented, not connection oriented- it's
really not anything like ssh (yet it is, of course, a way to
The advantage of ssh is that it's fairly light weight, not
demanding a lot of resources at the client or server end. It's easy
for users to comprehend (at least at the simplest usage levels) and
it pretty much "just works". It's flexible, powerful, and both
feature rich and yet easy to use and understand- a rare
Always keep in mind that ssh is just one small part of system
security, and that security methods are constantly changing. Don't
let your use of ssh lull you into thinking that you don't need to
constantly be alert to that.
A simple ssh connection
Almost all of the "traditional" terminal emulation products
have added ssh support, so if you are used to and like one of them,
an upgrade will probably get you this capability.
Let's assume that you have an account on my server
aplawrence.com (you don't, but let's just pretend). For reasons
that have to do with my private amusement, your account on my
server is "boopy" and your password is "mUstB50wAys2LOGin". No, you
can't change your password.
I don't allow telnet connections to my server, so you are going
to have to use ssh. You are logged in to your own Unix/Linux
machine (there are Windows ssh clients available, for example
and you want to login as "boopy" on my machine. You type:
If you are running a job-control shell like ksh, you can type
~^Z (tilde followed by Control-Z) to suspend your ssh session and
work locally. The normal "fg" command puts you back to your remote
If it looks like you get logged in but are then immediately
disconnected, it may be your TERM setting that is confusing sshd on
the other machine. Try (for example) "export TERM=ansi". You can
always change it after you are logged in if you need to.
You will be asked for "boopy"'s password, and if you supply it
correctly, you'll be logged in. Your login will look very much like
it would had you been able to telnet, and in fact operates very
much like telnet (but the standard telnet escapes will NOT
Had I been nice enough to give you an account with the same
login name as you use on your own machine, you could have omitted
the "-l boopy" and everything else would be the same. But we'll
leave it at "boopy" (By the way, there IS NO "boopy" account at
aplawrence.com- don't bother to try it).
The password (that awful password) and indeed everything else
that passed between our two machines during this session would be
encrypted. Even if I sat and watched your packets as they flowed in
and out, I wouldn't gain any information about your activities
(well, of course that's not strictly true- the volume of packets or
lack thereof is information of a sort- so if you were doing a lot
of "something", I'd know that, even if I couldn't know exactly what
you were doing). For example, it was recently (recently if you are
reading this in Spring 2001) discovered that someone watching a ssh
conversation would be able to guess the approximate length of the
password, and apparently even get the actual length of shell
commands used during the session. The length of a password isn't
much by itself, but if the system had also been compromised so that
the hacker has access to the systems encrypted passwords
(/etc/shadow for example), knowing the length makes brute force
guessing attacks easier.
Well, as I said at the beginning, ssh is just one part of
security. You might think from your usage so far that all that ssh
is providing here is the encrypted password. That's not quite true,
and I had alluded to that at the very beginning of this article. In
addition to handling the encryption of your password, ssh also
tries to make sure you are really connecting to the server you
think you are connecting to. I say "tries", because in most
situations all you can really trust is that the connection you made
is to the very same machine that you have been connecting to in the
past. Think of it like this: you can recognize your best friend,
and would know if someone else tried to impersonate that person.
But that person you've known "forever" might actually be an
imposter- the driver's license they carry might really be someone
elses, etc. Normally, ssh has the same relationship with the other
computers it talks to. It has "known" them since its first
conversation with them, and it can very safely guarantee that the
system you connect to now is the same system it "knows". The ssh
clients and servers exchange "host keys", which are uniquely
generated and should be impossible to forge because they use
public-key cryptography to for authentication.
Public key cryptography is complex and makes my head hurt, but
conceptually it's pretty simple. You have a pair of "keys", one of
which is public (anyone can know it) and the other is kept
"private" (only you know it). If you have something encrypted with
one of the keys, it can be decrypted with the other. How THAT part
works is what makes my head hurt, so we'll just treat that as PFM
(Pure Funky Magic) for the moment. But how to use that magic for
security is pretty straight forward. Let's say that I want to prove
to you that I'm really me. You have my public key, so you send me
some data and ask me to encrypt it using my private key. I do so,
and send it back to you encrypted. If, using my public key, you
decrypt what I sent back and it matches the data you originally
sent, you know that I have the private key that matches the public
key that you "know" belongs to me.
Ah, but how do you know that? Well, in the case of ssh clients
and servers, probably because the very first time the client talked
to the server, the server gave the client its public key. It's
possible that the public key came from some other source (SSL
security works like that) , or in the mail, and was physically
installed on the client, but in the case of the "boopy" account at
aplawrence.com, your machine got pcunix's public key just by making
a connection. In fact, on your very first connection, ssh would
have told you that it didn't have a public key for aplawrence.com
and would ask if you still wanted to connect. Replying "yes" to
that causes aplawrence.com's public key to be stored in
~/.ssh/known_hosts for future use.
OK, so now you have a public key for me. What happens if
somebody else steals my ip address or compromises DNS or your
routing so that your attempt to ssh to me actually lands you
somewhere else? Well, that person won't be able to decrypt
something encrypted with the real aplawrence.com's public key. Your
ssh client will tell you that, and warn you that you there could be
a "man in the middle" attack going on right now -that's where the
person who hijacked me connects to the real aplawrence.com also and
makes you think you really reached me, but in reality the "man in
the middle" is recording everything that happens between us and
perhaps even altering data.
The same thing happens if I change my server. In fact, that has
happened already- as aplawrence.com has grown, I have had to
migrate it to more powerful hardware. My ssh server generates a
different public/private key pair each time this happens, so if you
tried to connect the day after I changed my hardware, your ssh
client would complain (and the fix would be to remove
aplawrence.com from ~/.ssh/known-hosts and make a "new"
There's also (with some versions and distributions) "sftp",
which gives you an ftp-like interface for transferring files. Note
that it is NOT ftp; you can't use this with an arbitrary FTP
If that were all ssh could do, it would be pretty cool and
pretty useful. But there's more. It can also copy files, or run
remote commands. If you exit back to your server (just as you would
from telnet- "exit" or CTRL-D), you can copy a file:
Once again you will be asked for "boopy"'s password, and if you
can type it correctly once more, your file will be copied. You can
copy with wildcards (but keep in mind that wildcards are expanded
by your shell, not by anything at the other end). When using
wildcards, you'll only be asked for your password once. You can run
commands, too: how about a quick "ls -l"?
Your ability to type the password rewards you with the expected
results or rejects you as an incompetent typist (or just someone
with a bad memory). Have you decided that this ssh is a neat idea
but just too much work? Hang in there, we have a solution.
Obviously, part of the problem is all that typing of "boopy" and
"aplawrence.com" (yeah, retyping the password is annoying too-
we'll get to that in a minute). So, ssh. lets you create a
configuration file. Put this in your ~/.ssh/config:
With that, just "ssh pcunix" or "scp pcunix:~myfile myfile" will
work. There's much more that can be done in a config file; the
system wide file (probably /usr/local/ssh/etc/ssh_config) gives
examples. But we've still got that repetitive password entry.
Agents and Keys
There are other ways to authenticate yourself to the other server
when using ssh. Actually, there are a number of different ways, and
some of them are obscure, complex, or only necessary in unusual
cases. The methods supported also vary by ssh version, so I'm going
to pass right by the exotic stuff: if you need Kerberos or Security
Dynamics or S/Key, you'll be doing whatever it is you need to do to
make it work, but the majority of users will use either login
passwords (as described above) or passphrase authentication- which
I'm about to describe. Technically, there is also Trusted Hosts
authentication, which works very much like traditional rlogin, but
I'm going to ignore that here.
We already know that ssh uses public key cryptography to
identify hosts. It can also use it to identify you. To do, this,
you need to create an "identity". That's easy:
You'll be asked for a passphrase. This is used to protect the
private part of your identity. The public part will be created in
~/.ssh/identity.pub and needs to be copied to the server you want
But the procedure will cause problems if a more
than one computer is used to connect to the server by the user.
That will overwite the file. Instead what I do is
scp the .pub keys to $HOME on the target server. Then from
$HOME/.ssh I run the following script:
# add $HOME/*pub to .ssh/authorized_keys*
# b4 running this 'scp *pub' would be done from $HOME.ssh from
# the remote host.
#cd $HOME/.ssh of the user . not in this script
# as root might do this for users being setup.
# Next make keys when user account is created,
# scp them to other servers.
# then run this script on other servers..
# may need to use rdist to transfer the file & run a script
# on the remote server.
if [ -e ../identity.pub ]
cat ../identity.pub >> authorized_keys
if [ -e ../id_dsa.pub ]
cat ../id_dsa.pub >> authorized_keys2
chmod 700 ../.ssh
chmod 600 *
Once you have created an ssh identity (which is just a pair of
public/private keys), an attempt to access a server that knows your
public key (this is YOUR public key now, nothing to do with the
host keys) no longer asks you for your password. Instead, it asks
you for a passphrase, which is text that you entered when you
created your identity keys. To you, this looks very much like using
a password- it seems all that you've done is replaced the password
with another string of text. However, underneath, things are now
working quite differently:
Rather than sending your password, the authentication works just
like the server authentication described earlier: a bit of data is
encrypted with the public key, and if you can decrypt it with the
private key, that proves who you are. The passphrase is only used
to decrpt the private key, which in turn is then used to decrypt
the public key encrypted challenge, so nothing private gets sent
over the network at all. Remember that your password was sent
encrypted, but this way, nothing secret is sent at all.
Great, so it's more secure. But you still have to type in the
passphrase every single time you copy a file or reconnect. Well,
that's what the ssh-agent is for. Try this:
You don't have to use /bin/ksh- use whatever shell you like.
When you type sssh-add, you will be asked for your passphrase, but
that's the last time you'll be asked- until you exit out of
ssh-agent, of course. Now, when you use ssh or scp, the ssh-agent
provides the passphrase for you. No more repetitive typing.
You can automate that more: create a script called "agent"
ssh-agent /bin/bash --init-file ~/.ssh_bash_start
and a .ssh_bash_start containing "ssh-add". Now running "agent"
prompts for your key and that's all you have to do. You need a
verion of Bash that supports --init-file.
It's also possible to create a passwordless ssh connection. You
might need to do that for a service that you want to start
automatically. You should realize that you are running some risk
with that, but ssh does let you specify that only a specific
command can be run, and that the connection has to originate from a
specific ip address.
There's a lot more to ssh. It can also do port forwarding- for
example, see the description of using ftp through ssh in DSL and Cable Modem Security. You
can have multiple identities, and identities can use blank
passphrases- useful for unattended cron jobs, for example. If you
are going to make serious use of ssh, you'll also want to read
SSH-The Definitive Guide.