Chapter 27
The Secure Shell Client
|
|
|
|
|
 |
In this chapter: |
|
|
|
  |
Learning about the ssh client
|
  |
An overview of the encryption used for ssh sessions
|
  |
Creating the private and public key
|
  |
Distributing the public key to remote machines
|
  |
Using ssh for remote sessions and to issue remote commands
|
  |
Managing the private key with ssh-agent to increase ease of use
|
|
|
|
 |
|
In Part III, we discussed some of the traditional remote access tools
such as telnet, rsh (remote shell) and
rlogin (remote login). All previous references to these
services noted that their use would result in a dramatic decrease in
security. Offering these services make the server vulnerable due to
the lack of strong authentification for this service and the
possibility that the connection will be monitored.
For example, for telnet, there is an easy to use tool
available which monitors sessions and allows it to hitchhike on the
whole connection. This means that whoever has access to a machine that
acts as a router for your telnet session has an easy way
to spy on whatever you do. This is just an example. There are many
ways to attack remote sessions like this. The major point is that
everything you send or receive through this connection is transmitted
as is. There is no encryption in place to protect you from being
monitored. In these sections I encouraged you to use the secure shell
ssh as a more secure replacement for these traditional
services.
Secure shell (ssh) allows very strong authentification
methods and encrypts the connection. This means the protection of the
server machine is much better and the data transmitted during your
remote session is encrypted. In chapter 13 we learned how to
set up the secure shell server. As ssh is not as common
as telnet or rlogin are, we will talk about
the ssh client in this chapter and see how we can
configure it to optimize it's usability.
|
 |
We mentioned in chapter 13, that the international version
of SuSE Linux doesn't ship with the ssh package. However,
you can download the SuSE ssh package from the German FTP
site ftp.gwdg.de at the URL
ftp://ftp.gwdg.de/pub/linux/suse/6.1/i386.de/suse/sec1/ssh.rpm.
This package contains both server and client components. In the
following we assume that you have this package and have it installed
on your machine.
|
|
|
27.1 | Cryptography in ssh |
|
The ssh-client is the program for logging into a remote
machine and executing commands on a remote machine using the secure
shell protocol. It is intended to replace rlogin and
rsh by providing more securely encrypted communications
between two hosts over an insecure network. X11 connections and
arbitrary TCP/IP ports can also be forwarded over the secure
channel. I won't go into to much detail on this subject here. We'll go
over how to set up the ssh client to login into remote
machines and how to make this more convenient by using the
ssh-agent as repository for your passphrases. A
passphrase can be used (among other methods) to prove your identity to
the remote machine.
The scheme is based on public-key cryptography: there are
cryptosystems where encryption and decryption are done using separate
keys, and it is not possible to derive the decryption key from the
encryption key. RSA is one such system. The idea is that each user
creates a public/private key pair for authentication purposes. The
server knows the public key, and only the user knows the private key.
The file .ssh/authorized_keys lists the public keys that
are permitted for logging in. When you log in, the ssh
client tells the server which key pair it would like to use for
authentication. The server checks if this key is permitted, and if so,
it sends you (actually the ssh program running on your
behalf) a challenge such as a random number, encrypted with your
public key. The challenge can only be decrypted using the proper
private key which is protected by the passphrase. Once you enter the
passphrase, your client decrypts the challenge using the private key
and sends it back to the server.
Ssh implements the RSA authentication protocol
automatically. You create your RSA key pair by running
ssh-keygen (more about this later on). This stores the
private key in .ssh/identity and the public key in
.ssh/identity.pub in your home directory. You should then
copy the identity.pub to
.ssh/authorized_keys in your home directory on the remote
machine (the authorized_keys file corresponds to the
conventional .rhosts file, and has one key per line,
though the lines can be very long). After this, you can log in without
giving the password. RSA authentication is much more secure than
rhosts authentication. The most convenient way to use RSA
authentication may be with an authentication agent. We'll see how this
works later on.
The session terminates when the command or shell on the remote machine
exits and all X11 and TCP/IP connections have been closed. The exit
status of the remote program is returned as ssh's exit status.
|
 |
If you are using X11 (the DISPLAY environment
variable is set), the connection to the X11 display is automatically
forwarded to the remote side in such a way that any X11 programs
on the remote machine will go through the encrypted
channel, and the connection to the real X server will be made from the
local machine. This is very convenient, and definitely a greater
advantage over the traditional tools, where automatically setting the
correct display for remote clients can be difficult. In this way,
ssh works as a replacement for the xon command, which is
the traditional tool for executing X applications on a remote machine
without having to worry about the display.
|
|
You should not manually set DISPLAY when you use
ssh. Forwarding of X11 connections can be configured on
the command line or in configuration files. The DISPLAY
value set by ssh will point to the server machine, but
with a display number greater than zero. This is normal, and happens
because ssh creates a proxy X server on
the server machine for forwarding the connections over the encrypted
channel.
If you are using an authentication agent, the connection to the agent
is automatically forwarded to the remote side unless disabled on the
command line or in a configuration file.
Ssh automatically maintains and checks a database
containing RSA-based identifications for all hosts it has ever been
used with. The database is stored in .ssh/know_hosts in
your home directory. Additionally, the file
/etc/ssh_known_hosts is automatically checked for known
hosts. Any new hosts are automatically added to the user's file. If a
host's identification ever changes, ssh sends a warning
and disables password authentication to prevent a trojan horse from
getting the user's password. Another purpose of this mechanism is to
prevent man-in-the-middle attacks, which could otherwise be used to
circumvent the encryption.
|
27.2 | Creating the public and private keys |
|
Let's get started and create the private and public key for your
ssh sessions. We'll start by calling the command
ssh-keygen.
Ssh-keygen generates and manages authentication keys for
ssh. Each user that wishes to use ssh with
RSA authentication has to run this tool to create the authentication
key in .ssh/identity. Normally this program generates the
key and asks for a file in which to store the private key. The public
key is stored in a file with the same name but with .pub
appended. The program also asks for a passphrase. The passphrase may
be empty to indicate no passphrase, or it may be a string of arbitrary
length. Good passphrases are 10-30 characters long and are not simple
sentences or otherwise easily to guess (English only has 1-2 bits of
entropy per word, and is not appropriate for passphrases). The
passphrase can be changed later by using the -p option.
|
 |
There is no way to recover a lost passphrase. If the passphrase is lost or
forgotten, you will have to generate a new key and copy the
corresponding public key to other machines. Using good, difficult to
guess passphrases is strongly recommended. Empty passphrases should
not be used unless you understand what you are doing.
|
|
There is also a comment field in the key file that used to help the
user identify the key. The comment can tell what the key is for, or
provide another useful hint. The comment is initialized to
user@host when the key is created, but can be changed
using the -c option.
To create your initial key pair call ssh-keygen with no parameters:
|
|
> ssh-keygen
Initializing random number generator...
Generating p:...............................................................
..++ (distance 1126)
Generating q: ......++ (distance 150)
Computing the keys...
Testing the keys...
Key generation complete.
Enter file in which to save the key (/home/arthur/.ssh/identity):
Enter passphrase:
Enter the same passphrase again:
Your identification has been saved in /home/arthur/.ssh/identity.
Your public key is:
1024 35
1624580417623378865504863036878414021751180548666596733457952345412438609939
4527984801647009738969448921336234605689904358246486760415790944264454557598
9543065407142134103545543023645299093840512593975590927808593290132060116185
6756074926147643650627087648965536870126376758356512124593061907205997138309
39571 arthur@Maggie
Your public key has been saved in /home/arthur/.ssh/identity.pub
|
|
The default file to save your private key is
.ssh/identity in your home directory. You should confirm
this default by pressing [RETURN] unless you're sure of
what you're doing. Next you are prompted to enter a passphrase. As
mentioned in the section above, this passphrase should be at least ten
characters. Don't worry about the length. You don't need to type it in
every time you access a remote machine. When using
ssh-agent as an authentication agent, you will need to
type the passphrase only once per session on your local machine. You
have to enter the passphrase twice to make sure that there is no
type-o in it. Don't forget that there is no way to reconstruct a
forgotten passphrase. In your home directory, a subdirectory
.ssh has been created. If you look into it, you'll see
three files:
|
|
> cd ~/.ssh
> ls -l
total 3
-rw------- 1 arthur users 526 Jun 28 17:13 identity
-rw-r--r-- 1 arthur users 330 Jun 28 17:13 identity.pub
-rw------- 1 arthur users 512 Jun 28 17:12 random_seed
|
|
The file identity contains your private key,
identity.pub your public key, and
random_seed is used for seeding the random number
generator. Look at the permissions of the files. Besides
identity.pub, no file should be readable by anyone but
the owner of the files. Since identity.pub contains the
public key, there is no need to keep the contents of this file
confidential. Now you are set on the client side. (Note that we talk
of the machine you use to connect from as client, and the remote
machine where you want to connect to as server.)
|
27.3 | Copying the public key to the server machine |
|
On the server side, you need to install the public key to be able to
connect. You need to copy the contents of identity.pub to
the file .ssh/authorized_keys in your home directory on
the remote machine.
|
 |
Here is the tricky part. How can you do this if
the server only provides ssh logins? The easiest way is to ask
the administrator of the remote machine to do this for you. The public
key doesn't give away any permissions, so it's safe to mail it
unencrypted and give to someone else. The private key,
the public key, and the passphrase together are needed to initiate a
ssh session. Here you see why ssh with RSA authetification is
a good choice for remote access. No doubt that getting all three parts
is much harder than just guessing a password. If ssh is the
only way to log onto the machine (which is the recommended setup), most often the
sysadmin will help and install your public key in the correct place.
|
|
It shouldn't be difficult if you have to install the public key
yourself. If you have only one public key, the file
identity.pub on the client and the file
authorized_keys on the server are identical. Both files
reside in the directory .ssh in your home directory. The
permissions for the authorized_keys file are the same as
the one for your private key. Nobody but you is allowed to access
it. You certainly don't want anybody else with a key to this file but
yourself. If you log on to the same server from more clients, and you
use different private keys on those clients, you have more than one
public key, and you need to add each one to the
authorized_keys file on the server.
|
 |
Each public key is one line in this file. Even if the line is very long,
keep in mind that the public is one line. Be sure not to include any
line feeds when you cut and paste the line by using the mouse.
|
|
|
27.4 | Using ssh |
|
Once the keys are generated and the public key is on the server,
ssh is ready to use. To start a remote session on the
server machine, the command to issue is ssh
server-name. I.e. to log onto
bart@simpsons.com, you would use the command:
|
|
> ssh bart.simpsons.com
Host key not found from the list of known hosts.
Are you sure you want to continue connecting (yes/no)? yes
Host 'bart.simpsons.com' added to the list of known hosts.
Enter passphrase for RSA key 'arthur@Maggie':
Last login: Tue Jun 29 00:20:11 1999 from Lisa.simpsons.com
Have a lot of fun...
No mail.
arthur@Bart:~ >
|
|
The first time you use ssh to log onto a machine, you get a
warning that the remote machine's host key is not known. Once you
add a host to the list of known hosts, the host key will be checked
every time you log onto this machine.
|
 |
If the host key changes, you will get a warning from the
secure shell client. Take this warning seriously. This may indicate
that the machine you are connecting to is not the machine you intended
to connect to. The host key is the signature and therefore the
identification of the server.
|
|
Ssh then prompts you for the passphrase. After you type it
in, the connection to the server will be established.
|
 |
If it doesn't work, you can use the parameter -v to get a detailed
protocol of the progress while the connection is made:
|
|
> ssh -v bart.simpsons.com
SSH Version 1.2.26 [i686-unknown-linux], protocol version 1.5.
Standard version. Does not use RSAREF.
Maggie: Reading configuration data /etc/ssh_config
Maggie: ssh_connect: getuid 700 geteuid 0 anon 0
Maggie: Connecting to bart [192.168.0.66] port 22.
Maggie: Allocated local port 1017.
Maggie: Connection established.
Maggie: Remote protocol version 1.5, remote software version 1.2.26
Maggie: Waiting for server public key.
Maggie: Received server public key (768 bits) and host key (1024 bits).
Maggie: Host 'bart' is known and matches the host key.
Maggie: Initializing random; seed file /home/arthur/.ssh/random_seed
Maggie: Encryption type: idea
Maggie: Sent encrypted session key.
Maggie: Installing crc compensation attack detector.
Maggie: Received encrypted confirmation.
Maggie: Remote: Server does not permit empty password login.
Maggie: No agent.
Maggie: Trying RSA authentication with key 'arthur@Maggie'
Maggie: Received RSA challenge from server.
Enter passphrase for RSA key 'arthur@Maggie':
Maggie: Sending response to host key RSA challenge.
Maggie: Remote: RSA authentication accepted.
Maggie: RSA authentication accepted by server.
Maggie: Requesting pty.
Maggie: Requesting shell.
Maggie: Entering interactive session.
Last login: Tue Jun 29 11:15:08 1999 from maggie.simpsons.com
Have a lot of fun...
No mail.
arthur@Bart:~ >
|
|
|
|
The output shown above demonstrates how ssh performs the
steps explained earlier in this chapter. With this output, you can
easily track down problems.
If you don't want to use ssh to start a remote session
but [would rather] execute a remote command, do it as you normally
would with the remote shell client rsh. Ssh
is designed to be a command line-compatible drop-in replacement for
rsh. If you have scripts or any kind sorts of jobs where
you used rsh, simply replace rsh with
ssh. Below is a brief example that illustrates what
happens when you run the domainname -f command remote on
the machine Bart.simpsons.com:
|
|
> ssh bart domainname -f
Enter passphrase for RSA key 'arthur@Maggie'
Bart.simpsons.com
|
|
The command is issued at Maggie, but is executed on the
machine Bart.simpsons.com, so it reports this name.
|
27.5 | Ssh-agent as Repository for the Passphrase |
|
Ssh-agent is a program designed to hold private
authentication keys. The idea is that the ssh-agent is started at the
beginning of an X-session or a login session, and all other windows or
programs are started as children of the ssh-agent program
(the command normally starts X or is the user shell). Programs started
under the agent inherit a connection to the agent. The agent is also
automatically used for RSA authentication when logging onto other
machines using ssh. If the ssh-agent is
started without any arguments (no command), it will fork and start an
agent as background process. The agent also prints commands that can
be evaluated in sh or csh-like shells that
will set the SSH_AUTH_SOCK and SSH_AGENT_PID
environment variables. The SSH_AGENT_PID environment
variable can be used to [kill the agent away] when it is no longer
needed (such as when you logout from X-session). If no options are
given, the ssh-agent uses the SHELL
environment variable to detect the type of shell you have
(*csh or sh-style shell). The
-c option will force a csh-style shell, and
-s option will force a sh-style shell.
Initially, the agent does not have any private keys. Keys are added
using ssh-add. When executed without arguments, ssh-add
appends the .ssh/identity file. If the identity has a
passphrase, ssh-add requests it. Next it sends the identity to
the agent. Several identities can be stored in the agent, and the
agent can automatically use any of these identities.
Ssh-add -l displays the identities currently held by the agent.
The idea is that the agent runs on your local machine. Authentication
data need not be stored on any other machine, and authentication
passphrases never go over the network. However, the connection to the
agent is forwarded over ssh remote logins, and the user
can thus use the privileges given by the identities anywhere in the
network in a secure way. A connection to the agent is inherited by the
children of the programs. If a command is given as argument to
ssh-agent, the agent exits automatically when the command
given on the command line terminates. The command is executed even if
the agent fails to start its key-storage and challenge-processing
services.
The easiest way to use ssh-agent is by using it to start
your X-session. If you start X manually with the command
startx, you should use ssh-agent startx
instead. This will first start ssh-agent, then the entire
X-session as a child of the agent. This means all applications you
start within the X-session will be able to use the authentication data
stored by the agent.
|
 |
If you use a display manager to log onto your system, SuSE
made it even easier to use with ssh-agent. If you look into
your .xsession file, you will see that it contains everything
you need to automatically run ssh-agent:
|
|
[...]
#
# If ssh is configured and ssh-agent is wanted set "yes"
#
usessh="no"
[...]
#
# Run ssh-agent only if ssh is configured and available.
#
sshagent="no"
if test "$usessh" = "yes" -a -d $HOME/.ssh ; then
type ssh-agent > /dev/null 2>&1 && sshagent="yes"
fi
if test -f $HOME/.xinitrc ; then
if test "$sshagent" = "yes" ; then
exec ssh-agent $HOME/.xinitrc
else
exec /bin/bash $HOME/.xinitrc
fi
else
if test -z "$WINDOWMANAGER" ; then
WINDOWMANAGER=/usr/X11R6/bin/kde
fi
exec $WINDOWMANAGER
fi
[...]
|
|
By default the variable usessh is set to no. If you
change this setting to yes, the script will check if
ssh-agent is available on your system and if the directory
.ssh exists in your home directory. If so, it'll use
ssh-agent to power up the X-session.
|
|
Once X is up and running, and you open a terminal emulation, you
should issue the command ssh-add:
|
|
>ssh-add
Need passphrase for /home/bb/.ssh/identity (arthur@maggie).
Enter passphrase:
Identity added: /home/bb/.ssh/identity (arthur@maggie)
|
|
|
 |
You will be prompted for the passphrase, (as we saw it earlier),
when we tinkered with ssh. The difference is that
once ssh-agent stored the passphrase, ssh will notice
this and ask the agent for the private key instead of asking you for
the passphrase again. Now you can issue remote command without
entering any authentification information:
|
|
>ssh bart
Last login: Tue Jun 29 11:14:06 1999 from maggie.simpsons.com
Have a lot of fun...
You have mail.
Directory: /home/arthur
Tue Jun 29 18:11:02 PDT 1999
[tcshrc]
arthur has logged on :0 from lisa.
bb has logged on ttyp1 from maggie.
[arthur@Bart:101] ~ >
|
|
|
|
Together with the automatic forwarding of the X display, this is a
very secure and very convenient way to work with remote machines.
|
 |
Summary: |
|
We learned how to use the ssh client as a replacement for the
tools traditionally had the same role- rsh, rlogin and
telnet. Ssh requires that we generate a private and a
public key. The private key is protected by a passphrase, which is
requested by ssh each time this tool is issued. Alternately,
ssh can request the private key from the authentification agent
(ssh-agent). This agent acts as a repository for the private
key. All children of the agent inherit a connection to it and can
request the private key without the need to re-enter the passphrase.
|
 |