3.4. Inside SSH-1Now 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, "Inside SSH-2"] The architecture of SSH-1 is summarized in Figure 3-2. We will cover:
Figure 3-2. SSH-1 architecture
3.4.1. Establishing the Secure ConnectionBefore 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:
Figure 3-3. SSH-1 protocol exchange
3.4.2. Client AuthenticationOnce 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:
22.214.171.124. Password authenticationDuring 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 126.96.36.199, "One-time passwords"] 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, "OpenSSH"] 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, "OpenSSH"] The behavior of password authentication also changes if Kerberos [Section 188.8.131.52, "Kerberos authentication"] or SecurID support [Section 184.108.40.206, "SecurID authentication"] is enabled in the SSH server.
220.127.116.11. Public-key authenticationPublic-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:
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.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, "Public Key-Based Configuration "] This isn't an intrinsic advantage of the public-key method, of course, but rather an implementation detail of SSH, albeit an important one.
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.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, "Kerberos and SSH"]
WARNING: One technical limitation regarding public-key authentication arises in connection with the RSAref encryption library. [Section 18.104.22.168, "Rivest-Shamir-Adleman (RSA)"] 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.
22.214.171.124. 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. 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.
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.Let's follow this authentication process step by step:
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.
126.96.36.199.1. Trusted-host access filesTwo pairs of files on the SSH server machine provide access control for trusted-host authentication, in both its weak and strong forms:
WARNING: If any of the four access files allows access for a particular connection, it's allowed, even if another of the files forbids it.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 would look at.
188.8.131.52.2. Control file detailsHere 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.
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 the 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.# example control file entry [+-][@]hostspec [+-][@]userspec # comment
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:
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 fred.flintstone.gov
This next entry (hostspec and userspec) allows email@example.com 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 -evil.empire.org @trusted-hosts
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 way.too.trusted mark
This next hostspec allows user wilma on fred.flintstone.gov to log into the local wilma account:# /etc/shosts.equiv sister.host.org -mark sister.host.org
This entry allows user fred on fred.flintstone.gov to log into the local wilma account, but no one else -- not even firstname.lastname@example.org:# ~wilma/.shosts fred.flintstone.gov
These entries allow both fred and wilma on fred.flintstone.gov to log into the local wilma account:# ~wilma/.shosts fred.flintstone.gov fred
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:# ~wilma/.shosts fred.flintstone.gov fred fred.flintstone.gov
the following /etc/shosts.equiv file permits access only from host three:set (one,,) (two,,) (three,,) subset (one,,) (two,,)
But this next one allows access from all three:-@subset @set
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 authentication.@set -@subset
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 184.108.40.206, "Rhosts authentication"]
220.127.116.11.3. Netgroups as wildcardsYou 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:
However, there's still a way to get the effect of a wildcard: using the wildcards available in netgroups. An empty netgroup:Remote: Ignoring wild host/user names in /etc/shosts.equiv
matches nothing at all. However, this netgroup:empty # nothing here
matches everything. In fact, a netgroup containing (,,) anywhere matches everything, regardless of what else is in the netgroup. So this entry:wild (,,)
allows access from any host at all, as long as the remote and local usernames match. This one:# ~/.shosts @wild
If strong trusted-host authentication is in use, this means any host verified by public key against the server's known hosts database.
allows any user on way.too.trusted to log into this account, while this entry:# ~/.shosts way.too.trusted @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:# ~/.shosts @wild @wild
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:oops (fred,,) (wilma,,) (barney,,)
allows anyone on home.flintstones.gov, not just your three friends, to log into your account. Beware!# ~/.shosts home.flintstones.gov @oops
18.104.22.168.4. SummaryTrusted-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, "Trusted-Host Authentication"] We don't recommend the use of weak ("Rhosts") trusted-host authentication at all in SSH1 and OpenSSH/1. It is totally insecure.
22.214.171.124. Kerberos authenticationSSH1 and OpenSSH provide support for Kerberos-based authentication; SSH2 doesn't yet. [Section 11.4, "Kerberos and SSH"] Table 3-2 summarizes the support features in these products.
Table 3-2. Kerberos Authentication Support in SSH
The following list explains the columns:
TIP: OpenSSH provides Kerberos support only when using the SSH-1 protocol.
126.96.36.199. One-time passwordsPassword 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:
3.4.3. Integrity CheckingThe 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 Insertion Attack"] 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. CompressionThe 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.
Copyright © 2002 O'Reilly & Associates. All rights reserved.