Previous Next

Home Up


Secure Shell client and server setup

Contents

Secure Shell is a replacement for telnet, rsh and similar things. It allows you to connect to a remote machine as with telnet, but with a few twists. The most important is that the entire connection is encrypted. The standard encryption is 128-bit IDEA encryption. This pretty much prevents anyone from seeing the data passing over the connection. It also allows for authentication of the server. When connecting, the client software requires a host key from the server. If the key is not in the list of known host keys, the client software will prompt you for whether you want to add it or not. If this happens when connecting to a server that should be known, you know someone is impersonating the server. For those using X11 software like Emacs, SSH sets up a tunnel for X11 traffic through the encrypted connection so that Emacs, xterm and such can connect to your local display without you having to open up outside access to the display.

With no further setup, SSH will set up an encrypted connection and prompt you for your password just as telnet would. For situations where you don't want to have to type in a password all the time, SSH can be configured to use public-key encryption to bypass the password step. You generate a key pair on the client end, then transfer the public half of the key to the server you want to access. Now, as long as you have the matching private key, you can connect to that server without needing to use a password.

The SSH package also includes the scp program. This operates the same way the rcp remote copy program does, except that it uses the same encryption and authentication as SSH. This can be a very useful tool for moving data to the server, for example you can use scp to transfer the authentication keys to the server after you've generated them and be assured that nobody eavesdropped on the transfer.

Downloading, building and installing the software

Due to some ridiculous US Government regulations, nobody in the United States is willing to distribute Secure Shell. On the Internet this isn't a major problem, you just download the software from a site outside the US. The most popular place would be Zedz in Europe.

First, download the source RPM from Replay. This is the latest US-legal release of version 1 of the SSH package. There is an international source RPM that offers better key lengths than the US version but is not legal for use in the United States due to the license terms RSADSI imposes on the use of the RSA algorithm. The only difference in building the international version is the name of the spec file. There is also a version 2 of SSH, but I haven't built and installed it yet, Replay doesn't yet provide prepared RPMs for it and it's still undergoing revisions to fix security bugs and needs to stabilize. Install the source RPM in /usr/src/redhat using "rpm -i <filename>".

cd to /usr/src/redhat/SPECS. The build is straightforward, your basic "rpm -ba ssh-1.2.26us.spec". Since the package is buildrooted, building it won't affect any installed software. The default configuration in the spec file is suitable for most purposes and doesn't need changing.

There will be four RPMs in /usr/src/redhat/RPMS/i386. The plain "ssh" one, the "ssh-clients" one and the "ssh-extras" one contain the programs that you need for a basic client setup. The "ssh-server" RPM contains the programs needed to run an SSH server on your system. Install all 4 packages with "rpm --upgrade -v *.rpm". Then, if you don't intend to run an SSH server on your system, cd to /etc/rc.d and remove the ssh links in the rcX.d directories, or use "chkconfig --levels 0123456 sshd off". This will insure that the server is never started.

Setting up the client

  1. Setting up the config file
  2. Client-side key generation
  3. Transfer the client public key to the server
  4. The client-side authentication agent

Client setup has three stages to it. The first is configuring the system-wide config files appropriately. The second is setting up the files for your user account and generating a user key. The third is setting up the authentication agent program if you wish to use it.

The system-wide client configuration is controlled by the /etc/ssh/ssh_config file. This is the only file you really need to configure. There is a default configuration already installed, but as a personal matter I prefer this file instead. The contents are:

# This is ssh client systemwide configuration file.  This file provides 
# defaults for users, and the values can be changed in per-user configuration
# files or on the command line.

# Configuration data is parsed as follows:
#  1. command line options
#  2. user-specific file
#  3. system-wide file
# Any configuration value is only changed the first time it is set.
# Thus, host-specific definitions should be at the beginning of the
# configuration file, and defaults at the end.

# Site-wide defaults for various options

Host *
Cipher idea
Compression yes
CompressionLevel 6
EscapeChar ~
FallBackToRsh no
ForwardAgent yes
ForwardX11 yes
IdentityFile ~/.ssh/identity
KeepAlive yes
KerberosAuthentication no
KerberosTgtPassing no
PasswordAuthentication yes
Port 22
RSAAuthentication yes
RhostsAuthentication no
RhostsRSAAuthentication no
StrictHostKeyChecking ask
TISAuthentication no

Much of this is relatively standard. I switch to the IDEA cipher, you can go with this or the Blowfish cipher. I would not recommend any of the others. The StrictHostKeyChecking line makes it ask you about any host who's host key is not on the list of known hosts. I disable the Kerberos and TIS authentication ( few people have Kerberos installed, and TIS has some serious security flaws ). I also disable fallback to the various flavors of RSH-style authentication using the .rhosts file. Even in SSH the RSH-style methods are subject to host-name spoofing by an attacker, and we're trying to improve security here. The various authentication methods are, in the order that SSH will try them:

RSAAuthentication
Normal public-key authentication. You generate a key pair locally, then copy the public half to the server you want to access. Access requires that the server have a key listed on the known hosts list and have a public key for you matching a private key in your keyfile on the client system.
RhostsRSAAuthentication
Modified .rhosts-based authentication. The server has to have a key listed on the known hosts list, and your hostname/username combination has to pass the requirements for rsh access. Specifically, your hostname has to be in either /etchosts.equiv or /etc/ssh/shosts.equiv on the server and your username must be the same on both the client and server, or your hostname must be listed in .rhosts or .shosts in your home directory on the server and your username must either be the same on both the client and server or your client-side username must match the username listed in the server-side file for your client-side hostname.
RhostsAuthentication
No encryption keys are needed to connect. The standard rules for rsh access are followed. The only thing you gain over conventional rsh is an encrypted connection.
PasswordAuthentication
If all other authentication methods are either not allowed or fail, the client will prompt you for your password and pass it over the encrypted connection to the server for validation. This is essentially telnet with an encrypted connection.
FallBackToRsh
This isn't strictly an authentication method. If all attempts to make an SSH connection fail, the SSH client software can be configured to simply run rsh and let it have a go at it. I tend to leave this option disabled because I don't like the idea of the software silently giving me an unencrypted rsh connection when I was expecting an encrypted SSH one.

The Host line allows variations in configuration based on the server the client is trying to connect to. We use the wildcard here to make configuration entries that apply to all hosts, but you can add additional sections with configuration entries that apply only to specific hosts by just preceeding the section with a "Host <hostname>" line. The "*" wildcard character works the way you'd expect it to here.

Each user also has a user-specific configuration file in .ssh/config underneath their home directory. I have found that when using the system-wide configuration above I don't usually need a user-specific config file, but if you need to make exceptions to the general configuration for a particular user you have that option.

We'll leave the /etc/ssh/ssh_known_hosts file empty, so there are no system default known hosts. As you connect to hosts, the software will prompt you and add them to your user-specific known hosts list. This is easier to manage than a system-wide list.

If you don't mind entering your password every time, you're good to go at this point. Personally, though, I prefer generating a key pair for RSA key-based authentication. This is a fairly straightforward process. To kick it off, simply run the ssh-keygen program. It will prompt you for the things you need. I would suggest a 1024-bit key rather than one of the shorter lengths. It may ask you to type in some text to seed the random number generator it uses to generate keys. Just type in some text normally and it'll tell you when it's got enough. It'll also ask you for a passphrase to protect the private keys. You can legally give it an empty passphrase, but consider the implications. With a passphrase, even if someone gets physical access to your machine they can't steal your keys and impersonate you. If you leave off the passphrase, anyone who can get at your private keys can use them. OTOH, every time the client programs need access to the keys they have to ask you to enter the passphrase. If you need to have scripts use the SSH utilities unattended, you may have to leave off the passphrase.

When key generation is done, there are two files created in the .ssh directory under your home directory. identity is a binary file containing the private key, encrypted with the passphrase you gave when generating keys. Make sure this file is only readable by you, and never let anyone else get access to it. The contents of this file are equivalent to your password. The other file, identity.pub, is the public half of the key pair. It can safely be world-readable.

To grant yourself access to a server, move a copy of identity.pub to the server and append it to ~/.ssh/authorized_keys. You may need to create the .ssh directory under your home directory, and create an initial empty authorized_keys file in it. I don't believe you need to keep authorized_keys private, but it might be a good idea to make it readable only by you just to be on the safe side. By keeping others from reading it, you keep them unable to find out what keys can be used to access your account and make it that much harder for them to attack you. You can use normal FTP to copy the public key over, or make use of the scp command to copy it. For example, to set up an XMission account for SSH access if it hasn't had it before, I'd do:

# Start on local system
cd ~/.ssh
scp identity.pub xmission.xmission.com:identity.pub
# answer password prompt
ssh xmission.xmission.com
# answer password prompt
# Now on xmission.xmission.com
mkdir .ssh
chmod u=rwx,go=rx .ssh
cd .ssh
mv ../identity.pub authorized_keys
chmod u=rw,go-rw authorized_keys
exit
# Back on local system

When you first do the scp command, it'll probably tell you that xmission.xmission.com isn't a known host and ask if you want to continue. Answering "yes" here will add the key for xmission.xmission.com to your own user-specific known hosts file, which is the proper thing to do.

Now if you do "ssh xmission.xmission.com", you should be prompted for the passphrase for your key file and be logged in. If you didn't give a passphrase when you generated your key pair, you won't be prompted at all. If you want to see the gory details of the negotiations, try "ssh -v xmission.xmission.com" and get more detailed messages.

The SSH package also comes with a program called ssh-agent. This is an authentication agent that works together with the client programs to help avoid having to type the passphrase for your key over and over. When you first run it, it sets up a socket and provides the proper environment variables to allow other processes to talk to it. You then use the ssh-add program to add sets of private keys to the agent. ssh-add will prompt you for your passphrase if needed, then store the keys in the agent. Client programs then, upon finding the agent's environment variables, contact the agent for any needed keys without having to prompt you for the passphrase.

The proper piece of code to start the agent under bash is:

eval `ssh-agent -s`
This will word for any Bourne-type shell. The eval command will take the output of the ssh-agent program and execute it. Since that output is the commands to place the agent's environment variables into the shell environment, from this point on any programs you run will have access to the agent. If you need to run this from a C-shell-type shell, substitue "-c" for "-s" in the command. eval works in both types of shell.

Once the agent is started, you can use ssh-add to add keys to the agent. By default it will add the keys found in ~/.ssh/identity which is what you want most of the time. Most of the time just issuing the "ssh-add" command will cause the right thing to happen. On a console you'll get a keyboard prompt to enter your passphrase. Under X11, it'll pop up a box to let you enter the passphrase. Sometimes under X11 you need to use "ssh-add </dev/null" to force it to recognize that it's not got a console to work with.

To shut down the agent, use "ssh-agent -k". This will terminate the agent cleanly.

Where to put the ssh-agent and ssh-add commands is an interesting question. I usually run X11, so I put both early in the .Xclients file before I've started a window manager or any client programs. By doing that, I insure that all client programs will inherit the environment variables and will be able to talk to the agent. When I start X11 or log in via XDM the very first thing I get is ssh-add's passphrase pop-up. I also have my .Xclients wait on the window manager or the xexit program before exiting, and run the "ssh-agent -k" command just before exiting .Xclients to insure a clean shutdown.

Running the agent on the console is a bit trickier. You'd need to add the commands to your login startup files. The problem is that those are not just run when you log in. Some are run every time you start a new process, and if you run under X11 some are run every time you open a new xterm. Multiple agents won't cause fatal problems, but you can't cleanly shut down multiple copies easily and it makes a mess. I avoid the whole problem by running the agent automatically only for X11, and accepting that if I need it while in a console login I'll have to start it by hand. Generally I only use console logins for local maintenance and stuff like that anyway, so I rarely need SSH from them and I'm not very motivated to solve this particular problem. Anyone else feel like taking a swing at it?

Setting up the server software

Under construction Under Construction


Previous Next

Home Up


tknarr@silverglass.org