Linux Server Security (2nd Edition( [Electronic resources]

Michael D. Bauer

نسخه متنی -صفحه : 94/ 37
نمايش فراداده

4.2. Secure Shell Background and Basic Use

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 corresponds to Sun''s rsh, rcp, and rlogin commands, but with one very important difference: paranoia. SSH lets you do everything rsh, rcp, and rlogin do, using your choice of libertarian-grade encryption and authentication methods.

OpenSSH, a 100% free and open source outgrowth of the OpenBSD project, 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 v1.x and SSH Protocol v1 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, I''ll use SSH v1x to refer to RSA-based versions of SSH/OpenSSH and SSH v2x to refer to versions that support both RSA and DSA.

4.2.1. How SSH Works

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 in more depth 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 his 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 remote server prompts the user 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.

If enabled, rhosts-style host-IP-based authentication with or without RSA keys may be used; OpenSSH also supports authentication using KerberosIV, S/KEY, and PAM.

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.

Cryptographic Terms

Any cryptographic mechanism is made up of several parts. Details concerning how they''re used and how they relate to each other vary from mechanism to mechanism, but in general, any scheme contains some combination of the following:

Algorithm

The heart of the mechanism; a mathematical or logical formula that transforms cleartext into ciphertext, or vice versa.

Block cipher

Family of encryption algorithms in which data is split up into blocks (typically 64 bits or greater per block) prior to transformation. Block ciphers are one category of symmetric algorithmsi.e., they use the same key for both encryption and decryption.

Cipher

Synonym for algorithm.

Ciphertext

Encrypted data.

Cleartext

Nonencrypted data.

Entropy

In layman''s terms, true randomness (which is harder to obtain than you might think!). All cryptographic schemes depend on entropy in some form.

Key

A secret word, phrase, or machine-generated piece of data that is fed into an algorithm to encrypt or decrypt data. Ideally, a key should have high entropy to minimize its likeliness of being guessed.

Passphrase

Secret word or phrase used to encrypt or otherwise protect a key. Ideally, one''s key should be very long and completely random; since such keys are virtually impossible to memorize, they are therefore typically stored as a file that is itself encrypted and protected with a shorter but easier-to-remember passphrase.

Public-key cryptography

Cryptographic schemes/algorithms in which each user or entity has two keys: one nonsecret key (public key) for encrypting and one secret key (private key) for decrypting. The private key can also be used for signing data, and the public key for verifying such signatures. Public-key algorithms tend to be slow but useful for authentication mechanisms and negotiating keys used in other types of ciphers.

Salt

A not-necessarily secret piece of data fed into the algorithm along with one''s key and cleartext data. Salts are often used to add entropy to keys and are almost always transparent to end users (i.e., used "behind the scenes").

Stream cipher

Subcategory of block ciphers. By operating at the word, byte, or even bit level, stream ciphers are designed to be as fast as possible in order to accommodate data streams (e.g., network sessions).

Symmetric algorithm

An encryption algorithm in which the same key is used for both encryption of data and decrypting of ciphertext. These schemes tend to be fast, but secure sharing/transmission of keys between sender and receiver is problematic.

As mentioned earlier, SSH is actually a suite of tools:

sshd

The daemon that acts as a server to all other SSH commands ssh

The primary end-user tool: used for remote shell, remote command, and port- forwarding sessions scp

A tool for automated file transfers sftp

A tool for interactive file transfers ssh-keygen

Generates private-public key pairs for use in RSA and DSA authentication (including host keys) ssh-agent

A daemon used to automate a client''s RSA/DSA authentications ssh-add

Loads private keys into a ssh-agent process ssh-askpass

Provides an X Window interface for ssh-add Of these tools, most users concern themselves only with ssh, since encrypted Telnet is the simplest use of SSH. scp, sftp, ssh-agent, and ssh-add, however, along with the strong authentication and TCP 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.

4.2.2. Getting and Installing OpenSSH

Nowadays, OpenSSH is a standard package on all Linux distributions: it''s that important. Accordingly, the simplest way to get OpenSSH is to install it from your Linux CD-ROMs. Just be sure to also check your distribution''s web site for updates, or run your distribution''s online-update tool (e.g., apt-get, yast2, up2date, etc.) to make sure you''re using your distribution''s newest OpenSSH package. OpenSSH has had some serious security vulnerabilities over the years.

OpenSSH''s official web site is http://www.openssh.com. This is the place to go for the very latest version of OpenSSH, both in source-code and RPM forms, and also for OpenSSL, which is required by OpenSSH. Also required is zlib, available at http://www.zlib.net.

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 for some reason 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 configure 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.6i and zlib-1.1.4 (all version numbers, by the way, may be outdated by the time you read this!), I followed these steps to build and install OpenSSH 3.7.1p2:

tar -xzvf openssh-3.7.1p2.tar.gz cd openssh-3.7.1p2 ./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, /etc/sshd. Since this version of OpenSSH supports both RSA and DSA keys and since each type of key is stored in its own authorized_keys 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! OpenSSH has had several serious security vulnerabilities in recent years, including remote-root vulnerabilities.

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. This has also been thought of for you: the source distribution''s contrib directory contains some useful goodies.

The 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 also contains sshd.pam, which can be installed in /etc/pam if you use Pluggable Authentication Modules (assuming you compiled OpenSSH with PAM support), and 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.).

The contrib/suse directory also contains an openssh.spec file for creating OpenSSH RPM packages for SUSE and an rc.sshd file to install in /etc/rc.d. Note, however, that as of this writing, this particular rc.sshd file doesn''t follow SUSE''s new format; you won''t be able to automatically activate it with chkconfig or insserv, unless you manually add a ### BEGIN INIT INFO section like the one in SUSE''s /etc/init.d/skeleton file.

4.2.3. SSH Quick Start

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:

ssh remote.host.net 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 ssh to kong- fu.mutantmonkeys.org as user mbauer, I''ll use the command listed in Example 4-1.

Example 4-1. Simple ssh command

ssh mbauer@kong-fu.mutantmonkeys.org 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 cleartext as with Telnet. Furthermore, all subsequent shell- session data will be encrypted as well. I can do whatever I need to do, including su -, without worrying about eavesdroppers. And all it costs me is a little bit of latency!

4.2.4. Using sftp and scp for Encrypted File Transfers

With Version 2.0 of SSH, Tatu Ylönen introduced a new feature: sftp. Server-side support for sftp is built into 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 been fully supported in OpenSSH only since OpenSSH v2.9. If a host you need to transfer files to or from doesn''t support sftp, you''ll need to use scp.

Using the 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 session:

[mick@kolach stash]# sftp crueller Connecting to crueller... mick@crueller''s password: sftp> dir drwxr-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_faq Fetching /home/mick/blintzes_faq to blintzes_faq sftp> put bakery_maps.pdf Uploading bakery_maps.pdf to /home/mick sftp> quit [mick@kolach stash]# The scp command, in most ways equivalent to the old 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 go.

This noninteractive quality makes scp slightly 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 command-line utilities, scp is far more useful in scripts than interactive tools tend to be.

The basic syntax of the scp command is:

scp [options] sourcefilestring destfilestring where each file string can be either a normal Unix file/path string (e.g., /docs/hello.txt, /home/me/mydoc.txt, etc.) or a host-specific string in the following format:

username@remote.host.name:path/filename For example, suppose I''m logged in to 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.

Example 4-2. Simple scp session

crueller: > scp ./recipe kolach:~ mick@kolach''s password: ******* 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 using my crueller username). scp then copied the file over, showing me a handy progress bar as it went along.

Suppose I''m logged on to crueller as mick but have the username mbauer on kolach, and I wish to write the file to kolach''s /data/recipes/pastries directory. Then my command line would look like this:

crueller: > scp ./recipe mbauer@kolach:/data/recipies/pastries/ Now let''s switch things around. Suppose I want to retrieve the file /etc/oven.conf from kolach (I''m still logged in to crueller). Then my command line looks like this:

crueller: > scp mbauer@kolach:/etc/oven.conf . Get the picture? The important thing to remember is that the source must come before the destination.

4.2.5. Digging into SSH Configuration

Configuring OpenSSH isn''t complicated. To control the behavior of the SSH client and server, there are only two files to edit: ssh_config and sshd_config, 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 they exist, $HOME/.ssh/config). For example, if /etc/ssh/ssh_config contains the line:

Compression yes but the file /home/bobo/.ssh/config contains the line:

Compression no 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 remote.host.net 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, $HOME/.ssh/config, and /etc/ssh/ssh_config.

ssh_config consists of a list of parameters, one line per parameter, in the format:

parameter-name parameter-value1(,parameter-value2, etc.) 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 yes or 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.

Table 4-1. Important ssh_config parameters
Parameter Possible values Description
CheckHostIP Yes, No (Default=Yes) Whether to notice unexpected source IPs for known host keys. Warns user each time discrepancies are found.

Cipher 3des, blowfish, des(Default=3des) Which block cipher should be used for encrypting ssh v1 sessions.

Ciphers aes128-cbc, 3des-cbc, blowfish-cbc, cast128-cbc, arcfour, aes192-cbc, aes256-cbc Order in which to try block ciphers that can be used for encrypting ssh v2 sessions.

Compression Yes, No (Default=No) Whether to use gzip to compress encrypted session data. Useful over limited bandwidth connections, but otherwise only adds delay.

ForwardX11 Yes, No (Default=No) Whether to redirect X connections over the encrypted tunnel and to set DISPLAY variable accordingly. Very handy feature!

PasswordAuthentication Yes, No (Default=Yes) 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 "Intermediate and Advanced SSH" (later in this chapter). Refer to the ssh(1) manpage for a complete list.

4.2.6. Configuring and Running sshd, the Secure Shell Daemon

Editing ssh_config is sufficient if the hosts you connect to are administered by other people. But we haven''t yet talked about configuring your own host to accept ssh connections.

Like the ssh client, sshd''s default behavior is configured in a single file, sshd_config, that 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 sshd_config.

Table 4-2. Some sshd_config parameters
Parameter Possible values Description
Port 1-65535 (Default=22) 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.

PermitRootLogin Yes, No(Default varies depending on Linux distribution) Whether to accept root logins. This is best set to No; administrators should connect the server with unprivileged accounts and then su to root.

PasswordAuthentication Yes, No (Default=Yes) Whether to allow (encrypted) username/password authentication or to instead insist on DSA or RSA key-based authentication.

PermitEmptyPasswords Yes, No (Default=No) Whether to allow accounts to log in whose system password is empty. Does not apply if PasswordAuthentication is No; also, does not apply to passphrases of DSA or RSA keys (i.e., null passwords on keys is okay).

X11Forwarding Yes, No (Default=No) Whether to allow clients to run X Window System applications over the SSH tunnel.

AllowTcpForwarding Yes, No (Default=Yes) Whether to allow clients to use generic TCP forwarders.

Unfortunately, there really is nothing to be gained by leaving X11Forwarding set to No in sshd_config, since a determined user can simply use generic TCP forwarding to forward X11. Even if AllowTcpForwarding is also set to No, users with shell access can still forward connections by piping SSH''s standard input/output to other (non-SSH) forwarding processes.

The risk, of course, with allowing X and other port forwarding is that this functionality gives users the ability to use SSH as a VPN/tunneling tool; for example, if all you want to do is allow remote users to read their email via pine or copy files to and from their home directory, you probably don''t want them to also be able to run processes on the server that are advertised on their client system and forwarded over an SSH tunnel! Unfortunately, the only sure way to disable port forwarding on an SSH server is to compile SSH without it.

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 sshd(8) manpage for a complete reference for these parameters.