Secure your connections with SSH

ArticleCategory:

System Administration

AuthorImage:

Bernard Perrot

TranslationInfo:[Author and translation history]

original in fr Bernard Perrot  

fr to en Guy Passemard  

AboutTheAuthor

Bernard has been System and Network Engineer for the CNRS (French National Scientific Research Center) since 1982. He has been in charge of missions concerning computer system security at the "Institut National de Physique Nucléaire et de Physique des Particules" (In2p3). Now, he is working for the Institute of Mathematical Research (IRMAR) in the Physical and Mathematical Sciences (SPM) department.

Abstract

This article was first published in a Linux Magazine France special issue focusing on security. The editor, the authors and the translators kindly allowed LinuxFocus to publish every article from this special issue. Accordingly, LinuxFocus will bring them to you as soon as they are translated to English. Thanks to all the people involved in this work. This abstract will be reproduced for each article having the same origin.

The ambition of this article is to take a good look at SSH, and why it is used. This isn't a tutorial or installation guide, rather an introduction to the vocabulary and the features of SSH. The links and documentation all along this article, will give you all implementation details.

ArticleIllustration:

ssh

ArticleBody:[The article body]

What is SSH used for ?

First of all (and historically), SSH (the command ssh) is a secure version of the rsh (and rlogin) commands. SSH means "Secure SHell" as rsh means "Remote SHell". So, when rsh can give you easy access to a remote shell, but without a mechanism of user authentication, ssh provides the same service but with high multi level security.

If we wanted to be very brief for a user who doesn't want to know more (or do more), one could stop here and say administrator has done his job and installed the software (this is quite easy today), all you need is the ssh command replacing the telnet, rsh or rlogin commands, and everything works the same but with more security.

So, when you were doing:

% rlogin serveur.org (or telnet serveur.org)

you now do:

% ssh serveur.org

and it's already much better!

To end the short summary, I will suggest that today, all security incidents that could have been avoided by the simple usage of SSH in place of rsh (rlogin,telnet) are mainly a consequence of the victims' negligence.

What are the needs ?

To give more details, here are some of the most crucial and fragile aspects of interactive connections which one wishes to see resolved:

To respond to these needs, some solutions exist that are not really satisfying:

And there is SSH, a good solution to:

SSH version 1 and SSH version 2

As nothing is perfect in this world, there are two incompatible versions of the SSH protocol: the 1.x version (1.3 and 1.5) and the 2.0 version. To pass from one version to the other is not painful for the user, having at hand the right client and the right server compatible with the version.

The SSH version 1 protocol is integrated, whereas SSH version 2 has redefined the previous protocol into three "layers":

  1. SSH Transport Layer Protocol (SSH-TRANS)
  2. SSH Authentication Protocol (SSH-AUTH)
  3. SSH Connection Protocol (SSH-CONN)

Each protocol layer is specifically defined in a document (draft) normalized by IETF, followed by the fourth draft describing the architecture (SSH Protocol Architecture, SSH-ARCH). One will find all the details at: http://www.ietf.org/html.charters/secsh-charter.html

Without going into too many details, here is what you find in SSHv2:

The main technical differences between SSH version 1 and 2 are:

SSH version 1

SSH version 2

monolithic (integrated) design

separation of the authentication, connection and transport functions into layers

integrity via CRC32 (not secure)

integrity via HMAC (hash encryption)

one and only one channel per session

unrestricted number of channels per session

negotiation using only a symmetric cipher in the channel, session identification with unique key on both sides

more detailed negotiation (symmetric cipher, public keys, compression, ...), and a separate session key, compression and integrity on both sides

only RSA for the public key algorithm

RSA and DSA for the public key algorithm

session key transmitted by the client side

session key negotiated thru the Diffie-Hellman protocol

session key valid for the entire session

renewable session key

Handling a bunch of keys

SSH key types, let me quickly define them:

The user adds a pass phrase which protects the private key part of the above keys.This protection is assured by encrypting the file containing the private key with a symmetric algorithm. The secret key used to encrypt the file is derived from the pass phrase.

Authentication methods

There are several user identification methods, the choice is made from needs described in the security policies. The authorized methods are activated or not in the server's configuration file. Here are the principal categories:

Also, it is useful to know at least two more elements concerning authentication:

The encryption algorithms

One must distinguish those for encrypting communication channels (encrypting with secret keys) and those used for authentication (encrypting with public keys).

For authentication, we can choose between RSA and DSA with version 2 of the protocol, and only RSA for version 1 (so no choice ...). Historically DSA was chosen, as RSA was in some countries patented. Since the end of the summer of year 2000, RSA is free of rights, and so this constraint has disappeared. I don't really have a preference on the good or bad choice, (just that DSA is a "pure" NSA product)

For symmetric encryption there is almost too much to choose from.... The protocol imposes a common algorithm that has to be present in all implementations : the triple-DES with three keys. Accordingly, it will be used if the negotiation between the client and server fails on other algorithms. If you can, try to negotiate with another algorithm, which is better, as the 3DES is now one of the least performing algorithms. Nevertheless we will put aside, unless necessary, the exotic or old ones (arc4, DES, RC4, ...) and limit our self to:

Personally, I question myself about the interest to propose so many algorithms: even though the protocol allows the possibility to negotiate a "private one" ( a particular group of users, for example), this seems to me essential, but for normal use, I think that with time, AES will be called to become the standard. If AES should get compromised, then security problems would be greater than those induced by SSH...

Port Forwarding, tunneling

SSH enables redirection (forwarding) of any TCP data flow through a "tunnel" in an SSH session. This means that the application data flow, instead of being directly managed by the client and server ports, is "encapsulated" in a "tunnel" created at connection (session) time. (refer to the following diagram).

This is done with no special effort (by the user) for the X11 protocol, with transparent handling of displays and allows continuous propagation when they are made via multiple hops.

For other flows, there is a command line option, for each side:

This powerful feature has sometime lead to SSH being called "a tunnel for the poor". One must understand that poverty here means: those who do not have administrator privileges on the client side. Only in particular cases can a local port be forwarded with lower privileges ( port > 1024) and without super-user rights ("root"). On the other hand, when privileged local port forwarding is needed, it either has to be done on a root account, or the client will have to be installed with super-user privileges ("suid") (In fact, a privileged local port allows redefinition of a standard service).

As with IP, it's quite easy to put anything in anything (and the contrary), it's not only possible to forward legacy TCP flows, but also PPP connections, which lets us make a "real" IP tunnel in IP (which is encrypted, therefore secure). The method exceeds the frame of this article, you can read the "Linux VPN-HOWTO" for details and setup scripts (you can also find native VPN solutions for Linux, like "stunnel" which you should consider before making a final choice).

Keep in mind that the first possibility is to redirect telnet flows: This could seem totally useless, as SSH implements interactive connection by default. However, while forwarding telnet connections, you may use your preferred client instead of the SSH interactive mode. You could particularly appreciate this in a Windowstm or MacOStm environment where the SSH client may not show the user's favorite ergonomy. For example, the "terminal emulation" part of the "Mindterm" client (Java's SSH client, present on all modern systems) suffers from the lack of performance of the Java language: it can be advantageous to use this client only to open the SSH tunnel.

In the same way, you can also start a distant client like "xterm" (for instance, using automatic X11 forwarding in SSH), which allows us to use SSH on X terminals.

Note that the tunnel stays open as long as there is a flow of data, even if it does not come from the initiator. So, the "sleep" command becomes very useful to open an SSH tunnel to forward a new TCP connection.

% ssh -n -f -L 2323:serveur.org:23 serveur.org sleep 60

% telnet localhost 2323

... welcome to serveur.org ...

The first line opens the tunnel, starts the command "sleep 60" on the server, and forwards the local port number 2323 towards the distant (telnet) port number 23 . The second starts a telnet client on the local port number 2323, and then will use the (encrypted) tunnel to connect to the server's telnetd deamon. The "sleep" command will be interrupted after a minute (there's only a minute lapse time to start telnet) , but SSH will close the tunnel only when the last client has finished.

Main distributions: available for free

We have to distinguish between clients and/or servers on the different platforms and you should know that SSH version 1 and SSH version 2 are incompatible. The references at the end of the article will help you find other implementations, not listed in the following table which is limited to free products with sufficiently stable features.

product

platform

protocol

link

notes

OpenSSH

Unix

versions 1 and 2

www.openssh.com

details below

TTSSH

Windowstm

version 1

www.zip.com.au/~roca/ttssh.html

 

Putty

Windowstm

version 1 and 2

www.chiark.greenend.org.uk/~sgtatham/putty

only beta

Tealnet

Windowstm

version 1 and 2

telneat.lipetsk.ru

 

SSH secure shell

Windowstm

versions 1 and 2

www.ssh.com

free for non commercial use

NiftytelnetSSH

MacOStm

version 1

www.lysator.liu.se/~jonasw/freeware/niftyssh/

 

MacSSH

MacOStm

version 2

www.macssh.com

 

MindTerm

Java

version 1

www.mindbright.se

v2 now commercial

Notice that MindTerm is both an independent implementation of Java (you just need a Java runtime ) and a servlet that can be executed inside a compatible well designed Web browser. Unfortunately, the last versions of this excellent distribution have just become commercial products.

OpenSSH

Today this distribution is probably the one to use in a Unix/Linux environment (continuous support, good response time, open-source and free).

OpenSSH development began with the original version (SHH 1.2.12) of Tatu Ylonen (the last really free) in the OpenBSD 2.6 project (via OSSH). Now, OpenSSH is developed by two groups, one developing only for the OpenBSD project, the other continuously adapting the code to make a portable version.

All this has some consequences, particularly the code has become more and more, a constant monster adaptation (I feel the "sendmail" syndrome appearing at the horizon and this is not healthy for an application dedicated to encryption which should be extremely rigorous ).

Besides clean and readable coding, two other points annoy me:

In my opinion (and I am not alone), a multiplatform encrytion product should have a demonstrated, determined and constant behavior whatever the platform is, as well as taking into account (eliminating) the platform's particular characteristics and their evolution.

This said, we have to admit that, the competitor's implementations are neither numerous nor attractive. I believe that it's more pragmatic to consider that today OpenSSH is the worst implementation excluding all others ...! A useful project for the community would be to redesign and to rewrite the code.

Bad news ...

SSH isn't miraculous! It does well what it is made for, but you can't ask for more. Particularly it will not prevent "authorized" connections: if an account is compromised , it will be possible for the intruder to connect himself via SSH to your computer, even though it's the only way, as he controls the authentication. SSH is fully reliable only when it is correlated by a practical and coherent security policy: if someone uses only one password, and he doesn't use SSH everywhere, the potential risk is only slightly diminished. You can admit that in this situation SSH can "backfire" as the intruder can use a secured encrypted connection with tunneling, he will be able to do almost all he wants without any possibility of efficient tracing for you.

In the same style, one must also take in account well made "rootkits" which generally contain a SSH deamon to make a discreet return to your system, but with a few modifications: it doesn't listen on port 22 of course, it has the delicacy to stop logging, it's named by an ordinary deamon ( for example httpd), also invisible for a "ps" command (which also has been somewhat modified by the rootkit).

On the contrary, one must not be too worried by the danger that can represent a SSH deamon which could let intruders be even more undercover: you know (I hope) that it is possible to put anything in almost anything in IP, including "misappropriation" of the essential protocols via a firewall: HTML tunneling, ICMP tunneling , DNS tunneling, .... So don't turn on your computer if you want a 100% secure system ;-).

SSH is not exempt of security "loopholes" derived from the implementation (many have been corrected in the past, as there is no perfect program), but also at the protocol level. These "loopholes", even though they may be announced as very alarming, generally concern weaknesses that are difficult to employ being technically complex to manipulate: One must keep in mind that the security incidents that could have been avoided by the use of SSH are daily, whereas those shown to be caused by weak points of SSH are somewhat theoretical. It should be interesting to read the study concerning "man in the middle" attacks: http://www.hsc.fr/ressources/presentations/mitm/index.html. Nevertheless it will be necessary to take in account these potential vulnerabilities for "high security;" applications (banking, military, ...), where the means used by the cracker, highly motivated by the stakes and the profits, can be considerable.

I often like to point out an incomprehensible weakness of the protocol concerning the "padding" (known as covered channel): in both version 1 and 2 the packets, have a length which is a multiple of 64 bits, and are padded with a random number. This is quite unusual and therefore sparing a classical fault that is well known in encrypting products: a "hidden" (or "subliminal") channel. Usually , we "pad" with a verified sequence as for example, give the value n for the byte rank n (self describing padding). In SSH, the sequence being (by definition) randomized, it cannot be checked. Consequently, it is possible that one of the parties communicating could pervert / compromise the communication for example used by a third party who is listening. One can also imagine a corrupted implementation unknown by the two parties (easy to realize on a product provided with only binaries as generally are commercial products). This can easily be done and in this case one only needs to "infect" the client or the server. To leave such an incredible fault in the protocol, even though it is universally known that the installation of a covered channel in an encryption product is THE classic and basic way to corrupt the communication, seems unbelievable to me . It can be interesting to read Bruce Schneier's remarks concerning the implementation of such elements in products influenced by government agencies. (http://www.counterpane.com/crypto-gram-9902.html#backdoors).

I will end this topic with the last bug I found during the portage of SSH to SSF (French version of SSH), it is in the coding of Unix versions before 1.2.25. The consequence was that the random generator produced ... predictable... results (this situation is regrettable in a cryptographic product, I won't go into the technical details but one could compromise a communication while simply eavesdropping). At the time SSH's development team had corrected the problem (only one line to modify), but curiously enough without sending any alert, not even a mention in the "changelog" of the product... one wouldn't have wanted it to be known, he wouldn't have acted differently. Of course there is no relationship with the link to the above article.

Conclusion

I will repeat what I wrote in the introduction: SSH, neither produces miracles, nor solves alone all security problems, but makes it possible to handle efficiently most fragile aspects of the historical interactive connection programs (telnet, rsh...).

Bibliography, essential links

The following two books cover SSH version 1 and SSH version 2:

And if you want to spend some money, here's the place to start ...:

Exploiting the covered channel (induced by the random padding in SSHv1)

Here is a way to exploit the covered (subliminal) channel made possible by the usage of random padding in SSHv1 (and v2). I decline all responsibility of heart attacks that may affect the most paranoid.

The SSHv1 packets have the following structure:

offset

(bytes)

name

length

(bytes)

description

0

size

4

packet size, field size without padding, thus:

size = length(type)+length(data)+length(CRC)

4

padding

p =1 to 8

random padding : size adjusted so that the ciphered part is a multiple of eight

4+p

type

1

packet type

5+p

data

n (variable >= 0)

 

5+p+n

checksum

4

CRC32

Only one field isn't encrypted: the "size". The length of the encrypted part is always a multiple of eight, adjusted by "padding". The padding is always performed, if the length of the last three fields is already a multiple of 8 then the padding will be eight bytes long (5+p+n remainder 0 modulo 8). Considering the ciphering function C, symmetric, used in CBC mode, and the deciphering function C-1. To simplify this demonstration, we shall take only the packets with eight bytes padding. As one of the packets arrives, instead of padding it with a random number, we will place a value C-1(M), of eight bytes in this case. This means the deciphering of a message M with the function C used to encrypt the channel (the fact that M is "deciphered" without being beforehand ciphered has no importance from a strict mathematical point of view, I will not detail here the practical implementation. ). Next, we carry out the normal processing of the packet, that is the ciphering by blocks of eight bytes.

The result will be :

offset

contents

notes

0

size

4 bytes not ciphered

4

8 bytes padding (ciphered)

so C(C-1(M))

12... end

type, data, CRC

 

What is amazing here? The first encrypted block contains C(C-1(M)). So as C is a symmetric encryption function, C(C-1(M)) = M. This first block is sent decrypted in a crypted data flow! This only means that anyone eavesdropping on the communication who has knowledge of the stratagem will know how to exploit the information. Of course, one can assume that the message M is itself encrypted (against a public key, for example, which avoids putting a secret in the perverted code), which still keeps it from being decrypted for someone who's not informed.

For example, it takes three packets of this type to pass the triple-DES(168 bit) session key, after which the flux sniffer can decrypt all the communication. When the key is sent, it's no longer necessary to "pre-decipher" the perverted padding before injecting it into the packet, it is possible to use paddings of any sizes if one wants to add even more information.

The usage of this covered channel is absolutely undetectable ! (One must be careful to encrypt each element of the message as previously explained, so that the entropy of the block doesn't reveal the stratagem. Undetectable because the padding is randomized, which eliminates possible validation tests. Random Padding should never be applied in cryptographic products.

What renders this channel even more dangerous than others in the protocol is induced by messages like SSH_MSG_IGNORE where you can use it without having knowledge of the encrypted key.

To avoid the perversive effects of random padding, one just has to define in the protocol the use deterministic padding: commonly called "self describing padding", meaning that the offset byte n contains n. Random padding has remained in SSH v2, it's a choice, so keep it in mind...

To conclude, I will just say that if I criticize the covered channel, it's because I would like a product like SSH, which claims to be of high security, to really offer a maximum of security. Now you are able to imagine that there exists many potential tampering opportunities in commercial products: only open source products can offer a solution to the primary requirement, the possibility to check the code (even though the checking often needs to be done).

mirror server hosted at Truenetwork, Russian Federation.