Inside SSH

SSH secures your data while it passes over a network, but how exactly does it work ? In this chapter, we move firmly onto technical ground and explain the inner workings of SSH. Let's roll up our sleeves and dive into the bits and bytes.
This chapter is written for system administrators, network administrators, and security professionals. Our goal is to teach you enough about SSH to make an intelligent, technically sound decision about using it. We cover the SSH-1 and SSH-2 protocols separately since they have important differences.
Of course, the ultimate references on SSH are the protocol standards and the source code of an implementation. We don't completely analyze the protocols or recapitulate every step taken by the software. Rather, we summarize them to provide a solid, technical overview of their operation. If you need more specifics, you should refer to the standards documents. The SSH Version 2 protocol is in draft status on the IETF standards track; it is available at:
http://www.ipsec.com/tech/archive/secsh.html http://www.ietf.org/
The older protocol implemented in SSH1 and OpenSSH/1 is Version 1.5 and is documented in a file named RFC included in the SSH1 source package.
Book: SSH, The Secure Shell: The Definitive Guide Section: Chapter 3. Inside SSH
3.1 Overview of Features
The major features and guarantees of the SSH protocol are:
  • ●  Privacy of your data, via strong encryption
  • ●  Integrity of communications, guaranteeing they haven't been altered
  • ●  Authentication, i.e., proof of identity of senders and receivers
  • ●  Authorization, i.e., access control to accounts
  • ●  Forwarding or tunneling to encrypt other TCP/IP-based sessions
    3.1.1 Privacy (Encryption)
    Privacy means protecting data from disclosure. Typical computer networks don't guarantee privacy; anyone with access to the network hardware, or to hosts connected to the network may be able to read (or sniff ) all data passing over the network. Although modern switched networks have reduced this problem in local area networks, it is still a serious issue; passwords are regularly stolen by such sniffing attacks.
    SSH provides privacy by encrypting data that passes over the network. This end-to-end encryption is based on random keys that are securely negotiated for that session and then destroyed when the session is over. SSH supports a variety of encryption algorithms for session data, including such standard ciphers as ARCFOUR, Blowfish, DES, IDEA, and triple-DES (3DES).
    3.1.2 Integrity
    Integrity means assuring that data transmitted from one end of a network connection arrives unaltered on the other side. The underlying transport of SSH, TCP/IP, does have integrity checking to detect alteration due to network problems (electrical noise, lost packets due to excessive traffic, etc.). Nevertheless, these methods are ineffective against deliberate tampering and can be fooled by a clever attacker. Even though SSH encrypts the data stream so an attacker can't easily change selected parts to achieve a specific result, TCP/IP's integrity checking alone can't prevent, say, an attacker's deliberate injection of garbage into your session.
    A more complex example is a replay attack. Imagine that Attila the Attacker is monitoring your SSH session and also simultaneously watching over your shoulder (either physically, or by monitoring your keystrokes at your terminal). In the course of your work, Attila sees you type the command rm -rf * within a small directory. He can't read the encrypted SSH session data, of course, but he could correlate a burst of activity on that connection with your typing the command and capture the packets containing the encrypted version of
your command. Later, when you're working in your home directory, Attila inserts the captured bits into your SSH session, and your terminal mysteriously erases all your files!
Attila's replay attack succeeds because the packets he inserted are valid; he could not have produced them himself (due to the encryption), but he can copy and replay them later. TCP/ IP's integrity check is performed only on a per-packet basis, so it can't detect Attila's attack. Clearly, the integrity check must apply to the data stream as a whole, ensuring that the bits arrive as they were sent: in order and with no duplication.
The SSH-2 protocol uses cryptographic integrity checking, which verifies both that transmitted data hasn't been altered and that it truly comes from the other end of the connection. SSH-2 uses keyed hash algorithms based on MD5 and SHA-1 for this purpose: well known and widely trusted algorithms. SSH-1, on the other hand, uses a comparatively weak method: a 32-bit cyclic redundancy check (CRC-32) on the unencrypted data in each packet. [Section 3.9.3]
3.1.3 Authentication
Authentication means verifying someone's identity. Suppose I claim to be Richard Silverman, and you want to authenticate that claim. If not much is at stake, you might just take my word for it. If you're a little concerned, you might ask for my driver's license or other photo ID. If you're a bank officer deciding whether to open a safe-deposit box for me, you might also require that I possess a physical key, and so on. It all depends on how sure you want to be. The arsenal of high-tech authentication techniques is growing constantly and includes DNA-testing microchips, retina and hand scanners, and voice-print analyzers.
Every SSH connection involves two authentications: the client verifies the identity of the SSH server (server authentication), and the server verifies the identity of the user requesting access (user authentication). Server authentication ensures that the SSH server is genuine, not an impostor, guarding against an attacker's redirecting your network connection to a different machine. Server authentication also protects against man-in-the- middle attacks, wherein the attacker sits invisibly between you and the server, pretending to be the client on one side and the server on the other, fooling both sides and reading all your traffic in the process!
There is difference of opinion as to the granularity of server authentication: should it be distinguish between different server hosts, or between individual instances of the SSH server? That is, must all SSH servers running on a particular host have the same host key, or might they have different ones? The term "host key," of course, reflects a bias towards the first interpretation, which SSH1 and OpenSSH follow: their known-hosts lists can only associate a single key with any particular hostname. SSH2, on the other hand, uses the second approach: "host keys" are actually associated with individual listening sockets, allowing multiple keys per host. This may reflect a pragmatic need rather than a considered change in principle. When SSH2 first appeared, it supported only DSA host keys, whereas SSH-1 supports only RSA keys. It was therefore impossible, as a matter of implementation,
for a single host to run both SSH-1 and SSH2 servers and have them share a host key.
User authentication is traditionally done with passwords, which unfortunately are a weak authentication scheme. To prove your identity you have to reveal the password, exposing it to possible theft. Additionally, in order to remember a password, people are likely to keep it short and meaningful, which makes the password easier for third parties to guess. For longer passwords, some people choose words or sentences in their native languages, and these passwords are likely to be crackable. From the standpoint of information theory, grammatical sentences contain little real information (technically known as entropy): generally less than two bits per character in English text, far less than the 8 -16 bits per character found in computer encodings.
SSH supports authentication by password, encrypting the password as it travels over the network. This is a vast improvement over other common remote-access protocols (Telnet, FTP) which generally send your password in the clear (i.e., unencrypted) over the network, where anyone with sufficient network access can steal it! Nevertheless, it's still only simple password authentication, so SSH provides other stronger and more manageable mechanisms: per-user public-key signatures, and an improved rlogin-style authentication, with host identity verified by public key. In addition, various SSH implementations support some other systems, including Kerberos, RSA Security's SecurID tokens, S/Key one-time passwords, and the Pluggable Authentication Modules (PAM) system. An SSH client and server negotiate to determine which authentication mechanism to use, based on their configurations. SSH2 can even require multiple forms of authentication.
3.1.4 Authorization
Authorization means deciding what someone may or may not do. It occurs after authentication, since you can't grant someone privileges until you know who she is. SSH servers have various ways of restricting clients' actions. Access to interactive login sessions, TCP port and X window forwarding, key agent forwarding, etc., can all be controlled, though not all these features are available in all SSH implementations, and they aren't always as general or flexible as you might want. Authorization may be controlled at a serverwide level (e.g., the /etc/sshd_config file for SSH1), or per account, depending on the authentication method used (e.g., each user's files ~/.ssh/authorized_keys, ~/.ssh2/ authorization, ~/.shosts, ~/.k5login, etc.).
3.1.5 Forwarding ( Tunneling)
Forwarding or tunneling means encapsulating another TCP-based service, such as Telnet or IMAP, within an SSH session. This brings the security benefits of SSH (privacy, integrity, authentication, authorization) to other TCP-based services. For example, an ordinary Telnet connection transmits your username, password, and the rest of your login session in the clear. By forwarding telnet through SSH, all of this data is automatically encrypted and integrity-checked, and you may authenticate using SSH credentials.
SSH supports three types of forwarding. General TCP port forwarding operates as described earlier for any TCP-based service. [Section 9.2] X forwarding comprises
additional features for securing the X protocol (i.e., X windows). [Section 9.3] The third
type, agent forwarding, permits SSH clients to access SSH public keys on remote machines. [Section 6.3.5]
Book: SSH, The Secure Shell: The Definitive Guide Section: Chapter 3. Inside SSH
3.2 A Cryptography Primer
We've covered the basic properties of SSH. Now we focus on cryptography, introducing important terms and ideas regarding the technology in general. There are many good references on cryptographic theory and practice, and we make no attempt here to be comprehensive. (For more detailed information, check out Bruce Schneier's excellent book, Applied Cryptography, published by John Wiley & Sons.) We introduce encryption and decryption, plaintext and ciphertext, keys, secret-key and public-key cryptography, and hash functions, both in general and as they apply to SSH.
Encryption is the process of scrambling data so that it can't be read by unauthorized parties. An encryption algorithm (or cipher) is a particular method of performing the scrambling; examples of currently popular encryption algorithms are RSA, RC4, DSA, and IDEA. The original, readable data is called the plaintext, or data in the clear, while the encrypted version is called the corresponding ciphertext. To convert plaintext to ciphertext, you apply an encryption algorithm parameterized by a key, a string that is typically known only to you. An encryption algorithm is considered secure if it is infeasible for anyone to read (or decrypt) the encrypted data without the key. An attempt to decrypt data without its key is called cryptanalysis.
3.2.1 How Secure Is Secure?
It's important to understand the word "infeasible" in the previous paragraph. Today's most popular and secure ciphers are vulnerable to brute-force attacks: if you try every possible key, you will eventually succeed in decryption. However, when the number of possible keys is large, a brute-force search requires a great deal of time and computing power. Based on the state of the art in computer hardware and algorithms, it is possible to pick sufficiently large key sizes so as to render brute-force key search infeasible for your adversary. What counts as infeasible, though, varies depending on how valuable the data is, how long it must stay secure, and how motivated and well-funded your adversary is. Keeping something secret from your rival startup for a few days is one thing; keeping it secret from a major world government for 10 years is quite another.
Of course, for all this to make sense, you must be convinced that brute force is the only way to attack your cipher. Encryption algorithms have structure and are susceptible to mathematical analysis. Over the years, many ciphers previously thought secure have fallen to advances in cryptanalysis. It isn't currently possible to prove a practical cipher secure. Rather, a cipher acquires respectability through intensive study by mathematicians and cryptographers. If a new cipher exhibits good design principles, and well-known researchers study it for some time and fail to find a practical, faster method of breaking it
[1]
than brute force, then people will consider it secure.
3.2.2 Public- and Secret-Key Cryptography
Encryption algorithms as described so far are called symmetric or secret-key ciphers; the same key is used for encrypting and decrypting. Examples are Blowfish, DES, IDEA, and RC4. Such a cipher immediately introduces the key-distribution problem: how do you get the key to your intended recipient? If you can meet in person every once and a while and exchange a list of keys, all well and good, but for dynamic communication over computer networks, this doesn't work.
Public-key, or asymmetric, cryptography replaces the single key with a pair of related keys: public and private. They are related in a mathematically clever way: data encrypted with the public key may be decrypted with its private counterpart, and it is infeasible to derive the private key from the public one. You keep your private key, well... private, and give the public key to anyone who wants it, without worrying about disclosure. Ideally, you publish it in a directory next to your name, like a telephone book. When someone wants to send you a secret message, they encrypt it with your public key. Other people may have your public key, but that won't allow them to decrypt the message; only you can do that with the corresponding private key. Public-key cryptography goes a long way towards solving the
[2]
key-distribution problem.
Public-key methods are also the basis for digital signatures: extra information attached to a digital document to provide evidence that a particular person has seen and agreed to it, much as a pen-and-ink signature does with a paper document. Any asymmetric cipher (RSA, ElGamal, Elliptic Curve, etc.) may be used for digital signatures, though the reverse isn't true. For instance, the DSA algorithm, which is used by the SSH-2 protocol for its
[3]
keys, is a signature-only public-key scheme and can't be used for encryption.
Secret- and public-key encryption algorithms differ in another way: performance. All common public-key algorithms are enormously slower than secret-key ciphers-by orders of magnitude. It is simply infeasible to encrypt large quantities of data using a public-key cipher. For this reason, modern data encryption uses both methods together. Suppose you want to send some data securely to your friend Bob Bitflipper. Here's what a modern encryption program does:
  1. Generate a random key, called the bulk key, for a fast, secret-key algorithm such as 3 DES (a.k.a the bulk cipher).
  2. Encrypt the plaintext with the bulk key.
  3. Secure the bulk key by encrypting it with Bob Bitflipper's public key, so only Bob can decrypt it. Since secret keys are small (a few hundred bits long at most), the speed of the public-key algorithm isn't an issue.
To reverse the operation, Bob's decryption program first decrypts the bulk key, and then
uses it to decrypt the ciphertext. This method yields the advantages of both kinds of encryption technology, and in fact, SSH uses this technique. User data crossing an SSH connection is encrypted using a fast secret-key cipher, the key for which is shared between the client and server using public-key methods.
3.2.3 Hash Functions
In cryptography (and elsewhere in computing and network technology), it is often useful to know if some collection of data has changed. Of course, one can just send along (or keep around) the original data for comparison, but that can be prohibitively expensive both in time and storage. The common tool addressing this need is called a hash function. Hash functions are used by SSH-1 for integrity checking (and have various other uses in cryptography we won't discuss here).
A hash function is simply a mapping from a larger set of data values to a smaller set. For instance, a hash function H might take an input bit string of any length up to 50,000 bits, and uniformly produce a 128-bit output. The idea is that when sending a message m to Alice, I also send along the hash value H(m). Alice computes H(m) independently and compares it to the H(m) value I sent; if they differ, she concludes that the message was modified in transit.
This simple technique can't be completely effective. Since the range of the hash function is strictly smaller than its domain, many different messages have the same hash value. To be useful, H must have the property that the kinds of alterations expected to happen to the messages in transit, must be overwhelmingly likely to cause a change in the message hash. Put another way: given a message m and a typical changed message m', it must be extremely unlikely that H(m) = H(m').
Thus a hash function must be tailored to its intended use. One common use is in networking: datagrams transmitted over a network frequently include a message hash that detects transmission errors due to hardware failure or software bugs. Another use is in cryptography, to implement digital signatures. Signing a large amount of data is prohibitively expensive, since it involves slow public-key operations as well as shipping along a complete encrypted copy of the data. What is actually done is to first hash the document, producing a small hash value, and then sign that, sending the signed hash along instead. A verifier independently computes the hash, then decrypts the signature using the appropriate public key, and compares them. If they are the same, he concludes (with high probability) that the signature is valid, and that the data hasn't changed since the private key holder signed it.
These two uses, however, have different requirements, and a hash function suitable for detecting transmission errors due to line noise might be ineffective at detecting deliberate alterations introduced by a human attacker! A cryptographic hash function must make it computationally infeasible to find two different messages having the same hash or to find a message having a particular fixed hash. Such a function is said to be collision-resistant (or
collision-proof, though that's a bit misleading), and pre-image-resistant . The Cyclic Redundancy Check hash commonly used to detect accidental data changes (e.g., in Ethernet frame transmissions) is an example of a non-collision-resistant hash. It is easy to find CRC-32 hash collisions, and the SSH-1 insertion attack is based on this fact. [Section
3.10.5] Examples of cryptographically strong hash functions are MD5 and SHA-1.
[1]
In his pioneering works on information theory and encryption, the mathematician Claude
Shannon defined a model for cipher security and showed there is a cipher that is perfectly secure under that model: the so-called one-time pad. It is perfectly secure: the encrypted data gives an attacker no information whatsoever about the possible plaintexts. The ciphertext literally can decrypt to any plaintext at all with equal likelihood. The problem with the one-time pad is that it cumbersome and fragile. It requires that keys be as large as the messages they protect, be generated perfectly randomly, and never be reused. If any of these requirements are violated, the one-time pad becomes extremely insecure. The ciphers in common use today aren't perfectly secure in Shannon's sense, but for the best of them, brute-force attacks are infeasible.
[2]
There is still the issue of reliably determining whose public key is whose; but that gets into
public-key infrastructure, or PKI systems, and is a broader topic.
[3]
That's the idea, anyway, although it has been pointed out that it's easy to use a general DSA
implementation for both RSA and ElGamal encryption. That was not the intent, however.
Book: SSH, The Secure Shell: The Definitive Guide Section: Chapter 3. Inside SSH
3.3 The Architecture of an SSH System
SSH has about a dozen distinct, interacting components that produce the features we've covered. [Section 3.1] Figure 3-1 illustrates the major components and their relationships to
one another.
Figure 3.1. SSH architecture
page73image3960
By "component" we don't necessarily mean "program:" SSH also has keys, sessions, and other fun things. In this section we provide a brief overview of all the components, so you can begin to get the big picture of SSH:
Server
Client
"copy this file." In SSH1, SSH2, and OpenSSH, the major clients are ssh and scp. Session
A program that allows incoming SSH connections to a machine, handling authentication, authorization, and so forth. In most Unix SSH implementations, the server is sshd.
A program that connects to SSH servers and makes requests, such as "log me in" or
Key
An ongoing connection between a client and a server. It begins after the client successfully authenticates to a server and ends when the connection terminates. Sessions may be interactive or batch.
A relatively small amount of data, generally from tens to one or two thousand bits, used as a parameter to cryptographic algorithms such as encryption or message authentication. The use of the key binds the algorithm operation in some way to the key holder: in encryption, it ensures that only someone else holding that key (or a related one) can decrypt the message; in authentication, it allows you to later verify that the key holder actually signed the message. There are two kinds of keys: symmetric or secret-key, and asymmetric or public-key. [Section 3.2.2] An
asymmetric key has two parts: the public and private components. SSH deals with four types of keys, as summarized in Table 3-1 and described following the table.
Table 3.1. Keys, Keys, Keys
Name
Lifetime
Created by
Type
Purpose
User key
Persistent
User
Public
Identify a user to the server
Session key
One session
Client (and server)
Secret
Protect communications
Host key
Persistent
Administrator
Public
Identify a server/machine
Server key
One hour
Server
Public
Encrypt the session key (SSH1 only)
User key
A persistent, asymmetric key used by clients as proof of a user's identity. (A single
user may have many keys/identities.)
Host key
A persistent, asymmetric key used by a server as proof of its identity, as well as by a client when proving its host's identity as part of trusted-host authentication. [Section
3.4.2.3] If a machine runs a single SSH server, the host key also uniquely identifies
the machine. (If a machine is running multiple SSH servers, each may have a
different host key, or they may share.) Often confused with the server key.
Server key
A temporary, asymmetric key used in the SSH-1 protocol. It is regenerated by the server at regular intervals (by default every hour) and protects the session key (defined shortly). Often confused with the host key. This key is never explicitly stored on disk, and its private component is never transmitted over the connection in any form; it provides "perfect forward secrecy" for SSH-1 sessions. [Section 3.4.1]
Session key
A randomly generated, symmetric key for encrypting the communication between an SSH client and server. It is shared by the two parties in a secure manner during the SSH connection setup, so that an eavesdropper can't discover it. Both sides then have the session key, which they use to encrypt their communications. When the SSH session ends, the key is destroyed.
Key generator
A program that creates persistent keys (user keys and host keys) for SSH. SSH1,
SSH2, and OpenSSH have the program ssh-keygen. Known hosts database
A collection of host keys. Clients and servers refer to this database to authenticate
one another.
Agent
Signer
page75image12960
SSH-1 uses a single session key, but SSH-2 has several: each direction (server to client, and client to server) has keys for encryption and others for integrity checking. In our discussions we treat all SSH-2's session keys as a unit and speak of "the session key" for convenience. If the context requires it, we specify which individual key we mean.
A program that caches user keys in memory, so users needn't keep retyping their passphrases. The agent responds to requests for key-related operations, such as signing an authenticator, but it doesn't disclose the keys themselves. It is a convenience feature. SSH1, SSH2, and OpenSSH have the agent ssh-agent, and the program ssh-add loads and unloads the key cache.
A program that signs hostbased authentication packets. We explain this in our
discussion of trusted-host authentication. [Section 3.4.2.3] Random seed
A pool of random data used by SSH components to initialize software pseudo-
random number generators.
Configuration file
A collection of settings to tailor the behavior of an SSH client or server.
Not all these components are required in an implementation of SSH. Certainly servers, clients, and keys are mandatory, but many implementations don't have an agent, and some even don't include a key generator.
Book: SSH, The Secure Shell: The Definitive Guide Section: Chapter 3. Inside SSH
3.4 Inside SSH-1
Now that we've seen the major features and components of SSH, let's delve into the details of the SSH-1 protocol. SSH-2 is covered separately. [Section 3.5] The architecture of SSH-1 is summarized in Figure 3-2. We will cover:
  • ●  How the secure session is established
  • ●  Authentication by password, public key, or trusted host
  • ●  Integrity checking
  • ●  Data compression
    Figure 3.2. SSH-1 architecture
    3.4.1 Establishing the Secure Connection
    Before meaningful interaction can take place, the SSH client and server must establish a secure connection. This lets them share keys, passwords, and ultimately, whatever data they transmit to each other.
    We will now explain how the SSH-1 protocol guarantees security of a network connection. Through a multistep process, starting from scratch, the SSH-1 client and server agree on an encryption algorithm and generate and share a secret session key, establishing a secure connection:
page77image9928
1. The client contacts the server.
2. The client and server disclose the SSH protocol versions they support.
3. The client and server switch to a packet-based protocol.
4. The server identifies itself to the client and provides session parameters.
5. The client sends the server a secret (session) key.
6. Both sides turn on encryption and complete server authentication.
7. The secure connection is established.
Now the client and server can communicate by encrypted messages. Let's examine each step in detail; the complete process is summarized in Figure 3-3.
Figure 3.3. SSH-1 protocol exchange
page78image6616
page79image384
1. The client contacts the server.
This is done without fanfare, simply by sending a connection request to the server's TCP port, which is
port 22 by convention.
2. The client and server disclose the SSH protocol versions they support.
These protocols are represented as ASCII strings, such as "SSH-1.5-1.2.27", which means SSH protocol Version 1.5 as implemented by SSH1 Version 1.2.27. You can see this string by connecting to an SSH server port with a Telnet client:
  $ telnet server 22
  Trying 192.168.10.1
  Connected to server (192.168.10.1).
  Escape character is '^]'.
  SSH-1.5-1.2.27
The implementation version (1.2.27) is just a comment and is optional in the string. But, some implementations examine the comment to recognize particular software versions and work around
[4]
known bugs or incompatibilities.
If the client and server decide their versions are compatible, the connection process continues; otherwise either party may decide to terminate the connection. For instance, if an SSH-1-only client encounters an SSH-2-only server, the client disconnects and prints an error message. Other actions are possible: for example, the SSH-2-only server can invoke an SSH-1 server to handle the connection.
3. The client and server switch to a packet-based protocol.
Once the protocol version exchange is complete, both sides switch to a packet-based protocol over the underlying TCP connection. Each packet consists of a 32-bit length field, 1- 8 bytes of random padding to foil known-plaintext attacks, a one-byte packet type code, the packet payload data, and a four-byte integrity check field.
4. The server identifies itself to the client and provides session parameters.
The server sends the following information to the client (all still unencrypted):
  • ❍  Its host key, used to prove the server host identity later.
  • ❍  Its server key, which helps establish the secure connection.
  • ❍  A sequence of eight random bytes, called check bytes. The client must include these check bytes in its next response, or the server rejects the response. This measure protects against some IP spoofing attacks.
  • ❍  Lists of encryption, compression, and authentication methods that the server supports.
At this point, both sides also compute a common 128-bit session identifier, which is used in some
subsequent protocol operations to uniquely identify this SSH session. This is an MD5 hash of the host key, server key, and check bytes taken together.
When the client receives the host key, it asks the question: "Have I spoken with this server before, and if so, what was its host key then?" To answer this question, the client consults its known hosts database. If the newly arrived host key matches a previous one in the database, all is well. However, there are two other possibilities: the server might not appear in the known hosts database, or it might be present but with a different host key. In each of these cases, the client elects to trust the newly arrived key or to reject it. [Section 7.4.3.1] Human guidance may be needed: for example, the client's user can be prompted to accept or reject the key.
If the client rejects the host key, the connection ends. Let's assume the host key is acceptable and continue.
5. The client sends the server a secret (session) key.
Now the client randomly generates a new key for a bulk cipher [Section 3.2.2] that both client and server support; this is called the session key. Its purpose is to encrypt and decrypt messages sent
between the client and the server. All that's needed is to give this session key to the server, and both sides can turn on encryption and begin communicating securely.
Of course, the client can't simply send the session key to the server. Encryption isn't operating yet, and if a third party intercepts this key, it can decrypt the client's and server's messages. Goodbye security! So the client must send the session key securely. This is done by encrypting it twice: once with the server's public host key and once with the server key. This step ensures that only the server can read it. After the session key is double-encrypted, the client sends it to the server, along with the check bytes and a choice of algorithms (picked from the server's list of supported algorithms sent in Step 4.
6. Both sides turn on encryption and complete server authentication.
After sending the session key, both sides begin encrypting the session data with the key and the selected bulk cipher. Before sending anything further, though, the client waits for a confirmation message from the server, which (like all subsequent data) must be encrypted with the session key. This final step provides the server authentication: only the intended server can have decrypted the session key, since it was encrypted with the host key verified earlier against the known hosts list.
Without the session key, an impostor server can't decrypt the subsequent protocol traffic or produce valid traffic in return, and the client will notice and terminate the connection.
Note that server authentication is implicit; there's no explicit exchange to verify the server host key. Therefore it's important for the client to wait for a valid server response using the new session key before sending anything further, in order to verify the server's identity before proceeding. The SSH-1 protocol isn't specific about this point, but SSH-2 requires it when server authentication is implicit in the session key exchange.
Encrypting the session key a second time with the server key provides a property called perfect forward secrecy. This means there are no persistent keys lying around whose disclosure can jeopardize the secrecy of past or future SSH sessions. If the server host key alone is used to protect the session key, then disclosure of the host private key compromises future communications and allows decryption of old, recorded sessions. Using the server key in tandem for this purpose removes this weakness, as it is temporary, never explicitly stored on disk, and replaced periodically (by default, once an hour).
Having stolen the server private key, an interloper must still perform an active man-in-the-middle or server spoofing attack to compromise a session.
7. The secure connection is established.
Since both the client and server now know the session key, and nobody else does, they can send each other encrypted messages (using the bulk cipher they agreed on) only they can decrypt. Also, the client has completed server authentication. We're ready to begin client authentication.
3.4.2 Client Authentication
Once the secure connection is established, the client attempts to authenticate itself to the server. The client may try any authentication methods at its disposal until one succeeds, or all have failed. For example, the six authentication methods defined by the SSH-1.5 protocol, in the order attempted by the SSH1 implementation, are:
[5]
1. Kerberos
2. Rhosts
3. RhostsRSA
4. Public-key
[5]
5. TIS
6. Password (flavors: host login password, Kerberos, SecurID, S/Key, etc.) F-Secure SSH Client for Windows (see Chapter 16) tries these in order:
1. Public-key
2. Password
Knowing the order for your client is a good idea. It helps to diagnose problems when authentication fails or acts unexpectedly.
3.4.2.1 Password authentication
During password authentication, the user supplies a password to the SSH client, which the client transmits securely to the server over the encrypted connection. The server then checks that the given password is acceptable for the target account, and allows the connection if so. In the simplest case, the SSH server checks this through the native password-authentication mechanism of the host operating system.
Password authentication is quite convenient because it requires no additional setup for the user. You don't need to generate a key, create a ~/.ssh directory on the server machine, or edit any configuration files. This is particularly convenient for first-time SSH users and for users who travel a lot and don't carry their private keys. You might not want to use your private keys on other machines, or there may be no way to get them onto the machine in question. If you frequently travel, you should consider setting up SSH to use one-time passwords if
your implementation supports them, improving the security of the password scheme. [Section 3.4.2.5]
On the other hand, password authentication is inconvenient because you have to type a password every time you connect. Also, password authentication is less secure than public-key because the sensitive password is transmitted off the client host. It is protected from snooping while on the network but is vulnerable to capture once it arrives at the server if that machine has been compromised. This is in contrast with public-key authentication, as even a compromised server can't learn your private key through the protocol. Therefore, before choosing password authentication, you should weigh the trustworthiness of the client and the server, as you will be revealing to them the key to your electronic kingdom.
Password authentication is simple in concept, but different Unix variants store and verify passwords in different ways, leading to some complexities. OpenSSH uses PAM for password authentication by default, which must be carefully configured. [Section 4.3] Most Unix systems encrypt passwords with DES (via the crypt( ) library routine), but recently some systems have started using the MD5 hash algorithm, leading to configuration issues. [Section 4.3] The behavior of password authentication also changes if Kerberos [Section 5.5.1.7] or SecurID support [Section 5.5.1.9] is enabled in the SSH server.
3.4.2.2 Public-key authentication
Public-key authentication uses public-key cryptography to verify the client's identity. To access an account on an SSH server machine, the client proves that it possesses a secret: specifically, the private counterpart of an authorized public key. A key is "authorized" if its public component is contained in the account's authorization file (e.g., ~/.ssh/authorized_keys). The sequence of actions is:
  1. The client sends the server a request for public-key authentication with a particular key. The request
    [6]
    contains the key's modulus as an identifier.
    The key is implicitly RSA; the SSH-1 protocol specifies the RSA algorithm particularly and exclusively for public-key operations.
  2. The server reads the target account's authorization file, and looks for an entry with the matching key. If there is no matching entry, this authentication request fails.
  3. If there is a matching entry, the server retrieves the key and notes any restrictions on its use. The server can then reject the request immediately on the basis of a restriction, for example, if the key shouldn't be used from the client host. Otherwise, the process continues.
  4. The server generates a random 256-bit string as a challenge, encrypts it with the client's public key, and sends this to the client.
  5. The client receives the challenge and decrypts it with the corresponding private key. It then combines the challenge with the session identifier, hashes the result with MD5, and returns the hash value to the server as its response to the challenge. The session identifier is mixed in to bind the authenticator to the current session, protecting against replay attacks taking advantage of weak or compromised random- number generation in creating the challenge.
    The hashing operation is there to prevent misuse of the client's private key via the protocol, including a
    [7]
    chosen-plaintext attack. If the client simply returns the decrypted challenge instead, a corrupt server can present any data encrypted with the client's public key, and the unsuspecting client dutifully decrypts and returns it. It might be the data-encryption key for an enciphered email message the
attacker intercepted. Also, remember that with RSA, "decrypting" some data with the private key is actually the same operation as "signing" it. So the server can supply chosen, unencrypted data to the client as a "challenge," to be signed with the client's private key-perhaps a document saying, "OWAH TAGU SIAM" or something even more nefarious.
6. The server computes the same MD5 hash of the challenge and session ID; if the client's reply matches, the authentication succeeds.
The public-key method is the most secure authentication option available in SSH, generally speaking. First of all, the client needs two secrets to authenticate: the private key, and the passphrase to decrypt it. Stealing either one alone doesn't compromise the target account (assuming a strong passphrase). The private key is infeasible to guess and never leaves the client host, making it more difficult to steal than a password. A strong passphrase is difficult to guess by brute force, and if necessary, you can change your passphrase without changing the associated key. Also, public-key authentication doesn't trust any information supplied by the client host; proof of possession of the private key is the sole criterion. This is in contrast to RhostsRSA authentication, in which the server delegates partial responsibility for the authentication process to the client host: having verified the client host's identity and privilege of the client running on it, it trusts the client software not to lie about the user's identity. [Section 3.4.2.3] If someone can impersonate a client host, he can impersonate any user on that host without actually having to steal anything from the user. This can't happen with public-key authentication. [8]
Public-key authentication is also the most flexible method in SSH for its additional control over authorization. You may tag each public key with restrictions to be applied after authentication succeeds: which client hosts may connect, what commands may be run, and so on. [Section 8.2] This isn't an intrinsic advantage of the
[9]
public-key method, of course, but rather an implementation detail of SSH, albeit an important one.
On the down side, public-key authentication is more cumbersome than the other methods. It requires users to generate and maintain their keys and authorization files, with all the attendant possibilities for error: syntax errors in authorized_keys entries, incorrect permissions on SSH directories or files, lost private key files requiring new keys and updates to all target accounts, etc. SSH doesn't provide any management infrastructure for distributing and maintaining keys on a large scale. You can combine SSH with the Kerberos authentication system, which does provide such management, to obtain the advantages of both. [Section 11.4]
3.4.2.3 Trusted-host authentication (Rhosts and RhostsRSA)
Password and public-key authentication require the client to prove its identity by knowledge of a secret: a password or a private key particular to the target account on the server. In particular, the client's location-the computer on which it is running-isn't relevant to authentication.
[10]
page83image25224
One technical limitation regarding public-key authentication arises in connection with the RSAref encryption library. [Section 3.9.1.1] RSAref supports key lengths only up to 1024 bits, whereas the SSH internal RSA software supports longer keys. If you try to use a longer key with SSH/RSAref, you get an error. This can happen with either user or host keys, perhaps preexisting ones if you've recently switched
to RSAref, or keys transferred from systems running the non-RSAref version of SSH. In all these cases, you have to replace the keys with shorter ones.
Trusted-host authentication is different. Rather than making you prove your identity to every host that you
visit, trusted-host authentication establishes trust relationships between machines. If you are logged in as user andrew on machine A, and you connect by SSH to account bob on machine B using trusted-host authentication, the SSH server on machine B doesn't check your identity directly. Instead, it checks the identity of host A, making sure that A is a trusted host. It further checks that the connection is coming from a trusted program on A, one installed by the system administrator that won't lie about andrew's identity. If the connection passes these two tests, the server takes A's word you have been authenticated as andrew and proceeds to make an authorization check that andrew@A is allowed to access the account bob@B.
Let's follow this authentication process step by step:
  1. The SSH client requests a connection from the SSH server.
  2. The SSH server uses its local naming service to look up a hostname for the source address of the client network connection.
  3. The SSH server consults authorization rules in several local files, indicating whether particular hosts are trusted or not. If the server finds a match for the hostname, authentication continues; otherwise it fails.
  4. The server verifies that the remote program is a trusted one by following the old Unix convention of privileged ports. Unix-based TCP and UDP stacks reserve the ports numbered 1 through 1023 as privileged, allowing only processes running as root to listen on them or use them on the local side of a connection. The server simply checks that the source port of the connection is in the privileged range. Assuming the client host is secure, only its superuser can arrange for a program to originate such a connection, so the server believes it is talking to a trusted program.
  5. If all goes well, authentication succeeds.
This process has been practiced for years by the Berkeley r-commands: rsh, rlogin, rcp, rexec, etc. Unfortunately, it is a notoriously weak authentication method within modern networks. IP addresses can be spoofed, naming services can be subverted, and privileged ports aren't so privileged in a world of desktop PCs whose end users commonly have superuser (administrator) privileges. Indeed, some desktop operating systems lack the concept of a user (such as MacOS), while others don't implement the privileged-port convention (Windows), so any user may access any free port.
Nevertheless, trusted-host authentication has advantages. For one, it is simple: you don't have to type passwords or passphrases, or generate, distribute, and maintain keys. It also provides ease of automation. Unattended processes such as cron jobs may have difficulty using SSH if they need a key, passphrase, or password coded into a script, placed in a protected file, or stored in memory. This isn't only a potential security risk but also a maintenance nightmare. If the authenticator ever changes, you must hunt down and change these hard coded copies, a situation just begging for things to break mysteriously later on. Trusted-host authentication gets around this problem neatly.
Since trusted-host authentication is a useful idea, SSH1 supports it in two ways. Rhosts authentication simply behaves as described in Steps 1-5, just like the Berkeley r-commands. This method is disabled by default, since it is quite insecure, though it's still an improvement over rsh since it provides server host authentication, encryption, and integrity. More importantly, though, SSH1 provides a more secure version of the trusted-host method, called RhostsRSA authentication, which improves Steps 2 and 4 using the client's host key.
Step 2 is improved by a stronger check on the identity of the client host. Instead of relying on the source IP address and a naming service such as DNS, SSH uses public-key cryptography. Recall that each host on which
SSH is installed has an asymmetric "host key" identifying it. The host key authenticates the server to the client while establishing the secure connection. In RhostsRSA authentication, the client's host key authenticates the client host to the server. The client host provides its name and public key, and then must prove it holds the corresponding private key via a challenge-response exchange. The server maintains a list of known hosts and their public keys to determine the client's status as a known, trusted host.
Step 4, checking that the server is talking to a trusted program, is improved again through use of the client's host key. The private key is kept protected so only a program with special privileges (e.g., setuid root) can read it. Therefore, if the client can access its local host key at all-which it must do to complete authentication in Step 2-the client must have those special privileges. Therefore the client was installed by the administrator of
[11]
the trusted host and can be trusted. SSH1 retains the privileged-port check, which can't be turned off. SSH2 does away with this check entirely since it doesn't add anything.
3.4.2.3.1 Trusted-host access files
Two pairs of files on the SSH server machine provide access control for trusted-host authentication, in both its weak and strong forms:
  • ●  /etc/hosts.equiv and ~/.rhosts
  • ●  /etc/shosts.equiv and ~/.shosts
    The files in /etc have machine-global scope, while those in the target account's home directory are specific to that account. The hosts.equiv and shosts.equiv files have the same syntax, as do the .rhosts and .shosts files, and by default they are all checked.
    The /etc/hosts.equiv and ~/.rhosts files originated with the insecure r-commands. For backward compatibility, SSH can also use these files for making its trusted-host authentication decisions. If using both the r-commands and SSH, however, you might not want the two systems to have the same configuration. Also, because of their poor security, it's common to disable the r-commands, by turning off the servers in your inetd.conf files and/or removing the software. In that case, you may not want to have any traditional control files lying around, as a defensive measure in case an attacker managed to get one of these services turned on again.
    To separate itself from the r-commands, SSH reads two additional files, /etc/shosts.equiv and ~/.shosts, which have the same syntax and meaning as /etc/hosts.equiv and ~/.rhosts, but are specific to SSH. If you use only the SSH-specific files, you can have SSH trusted-host authentication without leaving any files the r-commands
    [12]
    All four files have the same syntax, and SSH interprets them very similarly-but not identically-to the way the r- commands do. Read the following sections carefully to make sure you understand this behavior.
    3.4.2.3.2 Control file details
    Here is the common format of all four trusted-host control files. Each entry is a single line, containing either one or two tokens separated by tabs and/or spaces. Comments begin with #, continue to the end of the line, and may be placed anywhere; empty and comment-only lines are allowed.
page85image26832
If any of the four access files allows access for a particular connection, it's allowed, even if another of the files forbids it.
would look at.
# example control file entry [+-][@]hostspec [+-][@]userspec # comment
The two tokens indicate host(s) and user(s), respectively; the userspec may be omitted. If the at-sign (@) is present, then the token is interpreted as a netgroup (see Sidebar "Netgroups"), looked up using the innetgr( ) library call, and the resulting list of user or hostnames is substituted. Otherwise, the token is interpreted as a single host or username. Hostnames must be canonical as reported by gethostbyaddr( ) on the server host; other names won't work.
Netgroups
A netgroup defines a list of (host, user, domain) triples. Netgroups are used to define lists of users, machines, or accounts, usually for access-control purposes; for instance, one can usually use a netgroup to specify what hosts are allowed to mount an NFS filesystem (e.g., in the Solaris share command or BSD exportfs).
Different flavors of Unix vary in how they implement netgroups, though you must always be the system administrator to define a netgroup. Possible sources for netgroup definitions include:
  • ●  A plain file, e.g., /etc/netgroup
  • ●  A database file in various formats, e.g., /etc/netgroup.db
  • ●  An information service, such as Sun's YP/NIS
    On many modern Unix flavors, the source of netgroup information is configurable with the Network Service Switch facility; see the file /etc/nsswitch.conf. Be aware that in some versions of SunOS and Solaris, netgroups may be defined only in NIS; it doesn't complain if you specify "files" as the source in nsswitch. conf, but it doesn't work either. Recent Linux systems support /etc/netgroup, though C libraries before glibc 2.1 support netgroups only over NIS.
    Some typical netgroup definitions might look like this:
    # defines a group consisting of two hosts: hostnames
    "print1" and
    # "print2", in the (probably NIS) domains one.foo.org and two.foo.com.
    print-servers        (print1,,one.foo.com) (print2,,two.foo.com)
    # a list of three login servers
    login-servers        (login1,,foo.com) (login2,,foo.com) (login1,,foo.com)
    # Use two existing netgroups to define a list of all hosts, throwing in
    # another.foo.com as well.
    all-hosts            print-servers login-servers (another,,foo.com)
    # A list of users for some access-control purpose.  Mary is allowed from
    # anywhere in the foo.com domain, but Peter only from one host.  Alice
    # is allowed from anywhere at all.
    allowed-users         (,mary,foo.com) (login1,peter,foo.com) (,alice,)
    
    When deciding membership in a netgroup, the thing being matched is always construed as an appropriate triple. A triple (x, y, z) matches a netgroup N if there exists a triple (a, b, c) in N which matches (x, y, z). In turn, you define that these two triples match if and only if the following conditions are met:
page86image22872 page86image23032 page86image23192 page86image23352 page86image23512 page86image23672
x=a or x is null or a is null
page87image416 page87image576 page87image736 page87image896
and:
y=b or y is null or b is null and:
z=c or z is null or c is null
This means that a null field in a triple acts as wildcard. By "null," we mean missing; that is, in the triple (, user, domain), the host part is null. This isn't the same as the empty string: ("", user, domain). In this triple, the host part isn't null. It is the empty string, and the triple can match only another whose host part is also the empty string.
When SSH matches a username U againsta netgroup, it matches the triple (, U,); similarly, when matching a hostname H, it matches (H, ,). You might expect it to use (, U, D) and (H, , D) where D is the host's domain, but it doesn't.
If either or both tokens are preceded by a minus sign (-), the whole entry is considered negated. It doesn't matter which token has the minus sign; the effect is the same. Let's see some examples before explaining the full rules.
The following hostspec allows anyone from fred.flintstone.gov to log in if the remote and local usernames are the same:
# /etc/shosts.equiv
fred.flintstone.gov
The following hostspecs allow anyone from any host in the netgroup "trusted-hosts" to log in, if the remote and local usernames are the same, but not from evil.empire.org, even if it is in the trusted-hosts netgroup.
# /etc/shosts.equiv
-evil.empire.org
@trusted-hosts
This next entry (hostspec and userspec) allows mark@way.too.trusted to log into any local account! Even if a user has -way.too.trusted mark in ~/.shosts, it won't prevent access since the global file is consulted first. You probably never want to do this.
# /etc/shosts.equiv
way.too.trusted mark
On the other hand, the following entries allow anyone from sister.host.org to connect under the same account name, except mark, who can't access any local account. Remember, however, that a target account can override this restriction by placing sister.host.org mark in ~/.shosts. Note also, as shown earlier, that the negated line must come first; in the other order, it's ineffective.
# /etc/shosts.equiv
sister.host.org -mark
sister.host.org
page87image20152 page87image20312
This next hostspec allows user wilma on fred.flintstone.gov to log into the local wilma account: # ~wilma/.shosts
fred.flintstone.gov
This entry allows user fred on fred.flintstone.gov to log into the local wilma account, but no one else-not even wilma@fred.flintstone.gov:
# ~wilma/.shosts
fred.flintstone.gov fred
These entries allow both fred and wilma on fred.flintstone.gov to log into the local wilma account:
# ~wilma/.shosts
fred.flintstone.gov fred
fred.flintstone.gov
Now that we've covered some examples, let's discuss the precise rules. Suppose the client username is C, and the target account of the SSH command is T. Then:
  1. A hostspec entry with no userspec permits access from all hostspec hosts when T = C.
  2. In a per-account file (~/.rhosts or ~/.shosts), a hostspec userspec entry permits access to the containing
    account from hostspec hosts when C is any one of the userspec usernames.
  3. In a global file (/etc/hosts.equiv or /etc/shosts.equiv), a hostspec userspec entry permits access to any
    local target account from any hostspec host, when C is any one of the userspec usernames.
  4. For negated entries, replace "permits" with "denies" in the preceding rules.
Note Rule #3 carefully. You never, ever want to open your machine to such a security hole. The only reasonable use for such a rule is if it is negated, thus disallowing access to any local account for a particular remote account. We present some examples shortly.
The files are checked in the following order (a missing file is simply skipped, with no effect on the authorization decision):
1. /etc/hosts.equiv 2. /etc/shosts.equiv 3. ~/.shosts
4. ~/.rhosts
SSH makes a special exception when the target user is root: it doesn't check the global files. Access to the root account can be granted only via the root account's /.rhosts and /.shosts files. If you block the use of those files with the IgnoreRootRhosts server directive, this effectively prevents access to the root account via trusted-host authentication.
When checking these files, there are two rules to keep in mind. The first rule is: the first accepting line wins. That is, if you have two netgroups:
set     (one,,) (two,,) (three,,)
subset  (one,,) (two,,)
the following /etc/shosts.equiv file permits access only from host three: -@subset
@set
But this next one allows access from all three:
@set
-@subset
The second line has no effect, because all its hosts have already been accepted by a previous line.
The second rule is: if any file accepts the connection, it's allowed. That is, if /etc/shosts.equiv forbids a connection but the target user's ~/.shosts file accepts it, then it is accepted. Therefore the sysadmin can't rely on the global file to block connections. Similarly, if your per-account file forbids a connection, it can be overridden by a global file that accepts it. Keep these facts carefully in mind when using trusted-host
[13]
authentication.
3.4.2.3.3 Netgroups as wildcards
You may have noticed the rule syntax has no wildcards; this omission is deliberate. The r-commands recognize bare + and - characters as positive and negative wildcards, respectively, and a number of attacks are based on surreptitiously adding a "+" to someone's .rhosts file, immediately allowing anyone to rlogin as that user. So SSH deliberately ignores these wildcards. You'll see messages to that effect in the server's debugging output if it encounters such a wildcard:
Remote: Ignoring wild host/user names in /etc/shosts.equiv
However, there's still a way to get the effect of a wildcard: using the wildcards available in netgroups. An empty netgroup:
empty  # nothing here
matches nothing at all. However, this netgroup:
wild (,,)
matches everything. In fact, a netgroup containing (,,) anywhere matches everything, regardless of what else is in the netgroup. So this entry:
# ~/.shosts
@wild
[14]
allows access from any host at all, as long as the remote and local usernames match. This one:
# ~/.shosts
way.too.trusted @wild
allows any user on way.too.trusted to log into this account, while this entry: # ~/.shosts
@wild @wild
allows any user access from anywhere.
Given this wildcard behavior, it's important to pay careful attention to netgroup definitions. It's easier to create a wildcard netgroup than you might think. Including the null triple (,,) is the obvious approach. However, remember that the order of elements in a netgroup triple is (host,user,domain). Suppose you define a group "oops" like this:
oops        (fred,,) (wilma,,) (barney,,)
You intend for this to be a group of usernames, but you've placed the usernames in the host slots, and the username fields are left null. If you use this group as the userspec of a rule, it will act as a wildcard. Thus this entry:
# ~/.shosts
home.flintstones.gov @oops
allows anyone on home.flintstones.gov, not just your three friends, to log into your account. Beware!
3.4.2.3.4 Summary
Trusted-host authentication is convenient for users and administrators, because it can set up automatic authentication between hosts based on username correspondence and inter-host trust relationships. This removes the burden of typing passwords or dealing with key management. However, it is heavily dependent on the correct administration and security of the hosts involved; compromising one trusted host can give an attacker automatic access to all accounts on other hosts. Also, the rules for the access control files are complicated, fragile, and easy to get wrong in ways that compromise security. In an environment more concerned with eavesdropping and disclosure than active attacks, it may be acceptable to deploy RhostsRSA (SSH-2 "hostbased") authentication for general user authentication. In a more security-conscious scenario, however, it is probably inappropriate, though it may be acceptable for limited use in special-purpose accounts, such as for unattended batch jobs. [Section 11.1.3]
We don't recommend the use of weak ("Rhosts") trusted-host authentication at all in SSH1 and OpenSSH/1. It is totally insecure.
3.4.2.4 Kerberos authentication
[15]
SSH1 and OpenSSH provide support for Kerberos-based authentication; SSH2 doesn't yet. [Section 11.4]
Table 3-2 summarizes the support features in these products.
Table 3.2. Kerberos Authentication Support in SSH
Product
Kerberos Version
Tickets
Password Authentication
AFS
Forwarding
SSH1
5
Yes
Yes
No
Yes
OpenSSH
4
Yes
Yes
Yes
Only with AFS
The following list explains the columns:
Tickets
Password Authentication
AFS
Option to perform server-side password authentication using Kerberos. Instead of checking the password using the operating system's account database, the SSH server instead attempts to obtain Kerberos initial credentials for the target user (a "ticket-granting-ticket" or TGT). If this succeeds, the user is authenticated. Also, the server stores the TGT for the session so that the user has access to it, thus removing the need for an explicit kinit.
The Andrew File System (http://www.faqs.org/faqs/afs-faq/), or AFS, uses Kerberos-4 in a specialized way for its authentication. OpenSSH has extra support for obtaining and forwarding AFS credentials.
This can be critical in environments using AFS for file sharing. Before it performs authentication, sshd must read the target account's home directory, for instance to check ~/.shosts, or ~/.ssh/ authorized_keys. If the home directory is shared via AFS, then depending on AFS permissions sshd might not be able to read it unless it has valid AFS credentials for the owning user. The OpenSSH AFS code provides this, forwarding the source user's Kerberos-4 TGT and AFS ticket to the remote host for use by sshd.
Performs standard Kerberos authentication. The client obtains a ticket for the "host" (v5) or
"rcmd" (v4) service on the server and sends that to the SSH server as proof of identity; the server validates it in the standard fashion. Both SSH1 and OpenSSH do Kerberos mutual authentication. This isn't strictly necessary given that SSH has already authenticated the server as part of connection setup, but the extra check can't hurt.

Forwarding
Kerberos credentials are normally usable only on the machine to which they are issued. The Kerberos-5 protocol allows a user to forward credentials from one machine to another on which he has been authenticated, avoiding the need for repeated kinit invocations. SSH1 supports this with the KerberosTgtPassing option. Kerberos-4 doesn't do ticket forwarding, so OpenSSH doesn't provide this feature-unless it is using AFS, whose modified Kerberos-4 implementation provides a form of ticket forwarding.
page92image928
OpenSSH provides Kerberos support only when using the SSH-1 protocol.
3.4.2.5 One-time passwords
Password authentication is convenient because it can be used easily from anywhere. If you travel a lot and use other people's computers, passwords might be your best bet for SSH authentication. However, it's precisely in that situation that you're most concerned about someone stealing your password-by monitoring keyboard activity on a hacked computer or by old-fashioned shoulder-surfing. One-time password, or OTP systems, preserve the convenience of password access while mitigating the risk: each login requires a different, unpredictable password. Here are the properties of some OTP systems:
  • ●  With the free S/Key software OTP system, you carry a printed list of passwords or calculate the next one needed using a piece of software on your laptop or PDA.
  • ●  With the SecurID system from RSA Security, Inc., you carry a small hardware token (credit-card or key-fob size) with an LCD screen, which displays a passcode that changes frequently and is synchronized with the SecurID server, which verifies the passcode.
  • ●  The OTP system from Trusted Information Systems, Inc. (TIS) is a variant called challenge-response : the server displays a challenge, which you type into your software or hardware token. The token supplies the corresponding response, which you supply to be authenticated.
    SSH1 supports SecurID as a variant behavior of password authentication, and TIS as a separate method with the TISAuthentication configuration keyword (as noted earlier, this is actually a separate authentication type in the SSH-1 protocol). OpenSSH doesn't support TIS but instead reuses the TIS message types in the SSH-1 protocol to implement S/Key. This works because both TIS and S/Key fit the model of a challenge/ response exchange.
    Using these systems involves obtaining the requisite libraries and header files, compiling SSH with the appropriate configure switches, enabling the right SSH authentication method, and setting up the system according to its instructions. If you are using SecurID or TIS, the requisite libraries and header files should have come with the software or be available from the vendor. S/Key is widely available on the Net, though it has diverged into many versions, and we don't know a canonical site for it. One popular implementation is found in the logdaemon package by Wietse Venema; see http://www.porcupine.org/wietse/. The details of these external packages are mostly outside the scope of SSH proper, so we won't delve into them.
    3.4.3 Integrity Checking
    The SSH-1 protocol uses a weak integrity check: a 32-bit cyclic redundancy check or CRC-32. This sort of check is sufficient for detecting accidental changes to data, but isn't effective against deliberate corruption. In fact, the "insertion attack" of Futoransky and Kargieman specifically targets this weakness in SSH-1. [Section 3.10.5] The use of the CRC-32 integrity check is a serious inherent weakness in SSH-1 that helped prompt the evolution of SSH-2, which uses cryptographically strong integrity checking invulnerable to this attack.
    3.4.4 Compression
    The SSH-1 protocol supports compression of session data using the "deflate" algorithm of the GNU gzip utility ( ftp://ftp.gnu.org/pub/gnu/gzip/ ). Packet data bytes in each direction are compressed separately, each as a single large stream without regard to packet boundaries.

While not typically needed on LAN or fast WAN links, compression can improve speed noticeably over slower links, such as an analog modem line. It is especially beneficial for file transfers, X forwarding, and running curses-style programs in a terminal session, such as text editors. Also, since compression is done before encryption, using compression can reduce delays due to encryption. This may be especially effective with 3DES, which is quite slow.
[4]
Some system administrators remove the comment, preferring not to announce their software package and version
to the world, which provides clues to an attacker.
[5]
This method isn't available by default; it must be requested at compile time.
[6]
An RSA key consists of two parts: the exponent and the modulus. The modulus is the long number in the public
key (.pub) file.
[7]
In a chosen-plaintext attack, the cryptanalyst is allowed to examine plaintext/ciphertext pairs of her choosing,
encrypted with the key she's trying to break. The RSA algorithm is particularly vulnerable to chosen-plaintext attacks, so it's important for a protocol using RSA to avoid them.
[8]
Don't confuse impersonating the client host with compromising it, however. If you actually break into the client
host and compromise its security, all bets are off; you can then steal the keys, passwords, etc., of any users on that host. SSH doesn't protect against host compromise.
[9]
We wish this were done differently. Rather than entangling the authentication and authorization functions in this
way, SSH should be able to apply any restriction to any connection, regardless of the authentication method. However, no implementation of SSH, to our knowledge, keeps authentication and authorization truly orthogonal.
[10]
The term "trusted-host" is our own; it refers to the Rhosts, SSH-1 RhostsRSA, and SSH-2 hostbased
authentication methods as a related group.
[11] SSH1 has a UsePrivilegedPort configuration keyword, but it tells the client not to use a privileged port in its source socket, which renders the session unusable for rhosts or RhostsRSA authentication. The purpose of this feature is to get around firewalls that might block connections coming from privileged ports and requires that some other authentication method be used.
[12]
Unfortunately, you can't configure the server to look at one set but not the other. If it looks at ~/.shosts, then it
also considers ~/.rhosts, and both global files are always considered.
[13] By setting the server's IgnoreRhosts keyword to yes, you can cause the server to ignore the per-account files completely and consult the global files exclusively instead. [Section 5.5.1.3]
[14]
If strong trusted-host authentication is in use, this means any host verified by public key against the server's
known hosts database.
[15]
At press time, experimental Kerberos support is being integrated into SSH2 2.3.0. 

No comments:

Post a Comment