1769 dladm show-link truncates OVER field
[unleashed.git] / usr / src / cmd / ssh / README.altprivsep
blobf91dbbd2a117a89c4013a695cb9faf0b0bb1eadf
1    Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
2    Use is subject to license terms.
4         Sun's Alternative "Privilege Separation" for OpenSSH
7 Table of Contents
9 1.    Introduction
10 2.    What is "Privilege?"
11 3.    Analysis of the SSH Protocols
12 3.1.  Privileged Resources, Operations, in the SSH Protocols
13 4.    OpenSSH's Privilege Separation
14 5.    SUNWssh's Alternative Privilege Separation
15 6.    Comparison of the OpenSSH and SUNWssh PrivSep Models
16 7.    Future Directions
17 8.    Guide to the AltPrivSep Source Code
18 A.    References
24 1.  Introduction
26     Implementations of SSH servers require some degree of privilege in
27     order to function properly.  Often such implementations retain such
28     privilege throughout normal operation even while users are logged
29     in.  This means that vulnerabilities in the implementation of the
30     protocols can be exploited in such ways as to escalate the privilege
31     that would normally be accorded to mer-mortal users.
33     The OpenSSH team introduced support for "privilege separation" in
34     the OpenSSH ssh server some years ago to minimize the extent of
35     extant, undiscovered vulnerabilities in the OpenSSH server source
36     code.  The basic concept is to have a multi-process server
37     implementation where one process, the "monitor" is privileged and
38     implements a smaller protocol than the ssh protocols, and thus is,
39     hopefully, less likely to sport exploitable security bugs.
41     The ssh team at Sun agrees with the basic OpenSSH privilege
42     separation concept, but disagrees with its design.
44     Here we present our alternative to the OpenSSH design.  We begin
45     with the question of just what is "privilege" and follow on with an
46     analysis of the SSH protocols vis-a-vis privilege.  Then we briefly
47     describe the OpenSSH model, followed by an exposition of our
48     alternative model.
51 2.  What is "Privilege?"
53     Privilege, in a traditional Unix sense, is that which the "root"
54     user can do that other users cannot directly do.  In Solaris 10
55     there is a new approach to this sort of privilege with the aim of
56     running much of the operating system with the Least Privilege
57     required; root's privilege is broken down into many privileges and
58     these are managed through privilege sets.  We won't go into the
59     details of Solaris 10's Least Privilege facility here.
61     But privilege is also access to data and resources that can be used
62     to escalate the privilege of those who have access to them.  For
63     example: secret, or private cryptographic keys used in
64     authentication.  Network security typically requires the use of
65     cryptographic keys for authentication.
68 3.  Analysis of the SSH Protocols
70     There are two or, rather three SSH protocols:
72      - version 1
73      - version 1.5
74      - version 2
76     Version 1 and 1.5 are much the same, from our point of view; version
77     2 is significantly different from the other two.
79     Familiarity by the reader with the specifications for these
80     protocols is not assumed, but would be beneficial to the reader.
82     Quite roughly, these protocols consist of the following:
84         a) initial version exchange (for protocol version negotiation)
85         b) a binary encoding of message data
86         c) message syntaxes for the protocols' messages
87         d) specifications on use of cryptography for transport
88            privacy (encryption) and integrity protection
89         e) a key exchange protocol (which also authenticates servers to
90            clients)
91         f) a protocol for user authentication
92         g) a session protocol
93         h) a re-keying protocol (v2-only)
95     Some of these parts of the ssh protocols are quite complex, some
96     quite straightforward.  Altogether implementation of the ssh
97     protocols requires a source code base of significant size.
99     The OpenSSH implementation relies on OpenSSL for cryptographic
100     service, on libz for compression service and miscellaneous other
101     libraries.  Besides these OpenSSH consists of several tens of
102     thousands of lines of source code in C.
104     SUNWssh is based on OpenSSH, so it is comparable in size and
105     complexity to OpenSSH.
107     There is, then, plenty of space for security bugs in the OpenSSH,
108     and, therefore, also in the SUNWssh source code bases.
110     The OpenSSH team designed and implemented a "privilege separation"
111     feature in their ssh server to reduce the risk that a security bug
112     in OpenSSH could be successfully exploited and an attacker's
113     privilege escalated.
116 3.1.  Privileged Resources, Operations, in the SSH Protocols
118     What privileges does an SSH server need then?
120     Observation with Solaris 10's ppriv(1) and truss(1) commands as well
121     as analysis of the ssh protocols leads to conclude as follows.
123     No privilege or privileged resources are needed to implement the
124     parts (a)-(d) mentioned in section 3.
127     For key exchange and server authentication (e) an ssh server requires:
129      - Access to the host's ssh private keys.
131      - Access to the host's GSS-API acceptor credentials.  [SSHv2-only]
134     An ssh server requires practically all privileges for user
135     authentication (f) (at least PAM does), particularly
136     PRIV_PROC_SETID, for logging the user in.
139     Post-authentication an ssh server requires the following privileges:
141      - Those required for auditing a user's subsequent logout.
143        That is, PRIV_PROC_AUDIT.
146      - Those required for record keeping (i.e., utmpx/wtmpx logging).
148        That is, either open file descriptor for those files or
149        PRIV_FILE_DAC_WRITE or otherwise access to those files, perhaps
150        through a special user id or group id which would be granted
151        write access through the ACLs on those files.
153        Since SSHv2 allows clients to open many channels with
154        pseudo-terminals a server may need to open and close utmpx/wtmpx
155        records multiple times in the lifetime of an SSHv2 connection.
158      - Those required for accessing the host's ssh private keys for
159        SSHv2 re-keying.  [SSHv2-only]
161        These keys can be (and are) loaded at server startup time,
162        requiring PRIV_FILE_DAC_READ, or access through file ACLs, at
163        that time, but not thence.
166      - Those required for accessing the host's GSS-API acceptor
167        credentials for SSHv2 re-keying.
169        These credentials may require a large set of privileges.  The
170        Solaris 10 Kerberos V GSS-API mechanism, for example, requires
171        PRIV_FILE_DAC_READ (for access to the system keytab) and
172        PRIV_FILE_DAC_WRITE (for access to the Kerberos V replay cache).
175     It is worth pointing out that because of a wrinkle in the
176     specification of the SSHv2 protocol and various implementations,
177     access to a host's ssh private keys can allow one not only to
178     impersonate the host as a server (which is, in practice, difficult),
179     but also to impersonate the host as a client (which is quite easy to
180     do) using "hostbased" user authentication.
182     It is entirely possible to have one-process server implementation
183     that drops most privileges and access to privileged resources after
184     user authentication succeeds.  Such an implementation would make
185     some privileges, such as PRIV_PROC_SETID, available to any attacker
186     that successfully exploited a security bug in the ssh server.
188     But such an implementation would also have to retain access to
189     resources needed for authenticating the server, which, as described
190     above, can be used to impersonate the server, in some cases with
191     ease.
194 4.  OpenSSH's Privilege Separation
196     The OpenSSH privilege separation model is quite complex.
198     It consists of a monitor, which retains all privileges and access to
199     privileged resources, and two processes which run with much less
200     privilege: one process running as a special user, "sshd," for
201     hosting all phases of the SSH protocols up to and including
202     authentication, and one process running as the actual user that logs
203     in and which hosts all phases of the SSH protocols post-user-
204     authentication.
206     The monitor and its companion processes speak a private protocol
207     over IPC.  This protocol is intended to be smaller and simpler than
208     the SSH wire protocols.
210     In practice the OpenSSH monitor protocols relating to user
211     authentication are neither smaller nor simpler than the SSH user
212     authentication protocols; and though they are different they also
213     transport much the same data, including RSA/DSA signatures,
214     usernames, PAM conversations, and GSS-API context and MIC tokens.
216     The key exchange protocols have been broken down into their
217     essentials and the monitor serves only services such as signing
218     server replies with private host keys.
220     Note also that the OpenSSH monitor protocol uses the same encodings
221     as the SSH protocols and uses the same implementation of those
222     encodings.
225 5.  SUNWssh's Alternative Privilege Separation
227     The Sun Microsystems ssh team believes that the OpenSSH team has
228     reached the point of diminishing returns in attempting to separate
229     processing of the user authentication protocols and that the OpenSSH
230     approach to privilege separation of the key exchange protocols has
231     led to a situation in which the monitor acts as an oracle, willing
232     to sign anything provided by the unprivileged processes that talk to
233     it.
235     The Sun ssh team proposes a somewhat different privilege separation
236     implementation that shares with the OpenSSH model the goal of
237     minimizing and simplifying the protocol spoken by the monitor, but
238     little source code.
240     We eschew any temptation to apply the privilege separation concept
241     to the version negotiation, initial key exchange and user
242     authentication phases of the ssh protocols (but see section 7).
244     Instead we focus on separating processing of auditing, record
245     keeping and re-keying from processing of the session protocols.  We
246     also wish to avoid creating any oracles in the monitor.
248     This approach allows us to have a very simple monitor protocol.  Our
249     monitor protocol consists of the following operations:
251      - record a new pseudo-terminal session
252      - record the end of a pseudo-terminal session
253      - process a re-key protocol messages
254      - get keys negotiated during re-keying to the session process to it
255        can use them
257     Logout auditing is done when the session process dies and so does
258     not require a monitor protocol message.
260     By processing all re-key protocol messages in the monitor we prevent
261     the creation of oracles in the monitor.  This is so because the
262     monitor signs only material which it has generated and over which an
263     attacker would have little influence (through the attackers offered
264     DH public key, for example).
266     Odds and ends:
268      - If the monitor receives SIGHUP, SIGTERM or SIGINT it will call
269        fatal_cleanup(), and thence will forcibly shutdown(3SOCKET) the
270        ssh connection socket, causing its child to exit, and audit a
271        logout.
273      - The monitor does not attempt to update utmpx/wtmpx independently
274        of its child -- it depends on the child asking it to.
276      - The child now is unable to chown() ptys back to root.  That's Ok,
277        other services on Solaris do the same and everything still works
278        because of grantpt(3C).
280      - The sshd server process (the one that will become a monitor)
281        forks a child process before the key exchange starts. The reason
282        for it is that if we forked after that we would end up using
283        PKCS#11 sessions initialized in the monitor unless
284        UseOpenSSLEngine was explicitly set to 'no'. Using any existing
285        PKCS#11 sessions or object handles over fork is what the PKCS#11
286        standard explicitly prohibits. To solve that, we would have to
287        rekey before fork and then newly initialize the engine in the
288        child, together with the new crypto contexts initialized with the
289        keys produced by the key re-exchange. And, that wouldn't help in
290        situations where the client does not support rekeying which also
291        includes the whole protocol version 1. The pre-fork solution is
292        simpler and also much faster. So, the key exchange and
293        authentication is fully done in the child server process while
294        the monitor waits aside to read the authentication context that
295        is needed for further operation. The child drops privileges after
296        the authentication finishes.
298        With the ssh client, the situation is slightly more complicated.
299        Given the fact that the user can request to go to the background
300        during the connection using the ~& sequence we must be prepared
301        to rekey before forking, to reinitialize the engine in the child
302        after that, and then set the new crypto contexts with the new
303        keys. If the server we are communicating with does not support
304        rekeying we will not use the engine at all. We expect this
305        situation to be extremely rare and will not offer any workaround
306        for that. This also includes the protocol version 1. However,
307        this version is already considered obsolete and should not be used
308        if possible.
310 6.  Comparison of the OpenSSH and SUNWssh PrivSep Models
312     The OpenSSH server involves three processes which we will term
313     "pre-session," "session" and "monitor."
315     The OpenSSH pre-session process implements:
317      - the ssh version string exchange
318      - the ssh message encoding/decoding
319      - most of the initial key exchange protocols
320      - transport protection
321      - part of the user authentication protocols
323     The OpenSSH session process implements:
325      - the ssh message encoding/decoding
326      - transport protection
327      - most of the re-keying protocols
328      - the session protocols
330     The OpenSSH monitor process implements:
332      - the ssh message encoding/decoding
333      - parts of the key exchange and re-key protocols (primarily signing
334        of server replies with host private keys)
335      - most of the user authentication protocols, specifically:
337         - evaluation of ~/.ssh/authorized_keys (for pubkey userauth)
338         - evaluation of known hosts files (for hostbased userauth)
339         - evaluation of .shosts/.rhosts files (for hostbased userauth)
340         - verification of signatures w/ public keys (pubkey, hostbased)
341         - PAM API calls, conversation function
342         - GSS-API calls
344        Note that any vulnerabilities in the parsing of authorized_keys,
345        known hosts and .shosts/rhosts files are as exploitable in the
346        monitor as in a server w/o privilege separation.
348        Similarly for any vulnerabilities in PAM modules and GSS-API
349        mechanisms.
351     The SUNWssh server involves two processes which we will term
352     "session" and "monitor."
354     The SUNWssh monitor process implements:
356      - the ssh version string exchange
357      - the ssh message encoding/decoding
358      - transport protection
359      - all of the key exchange and re-key protocols
360      - all of the user authentication protocols
362     The SUNWssh session process implements:
364      - the ssh message encoding/decoding
365      - transport protection
366      - the session protocols
368     Obviously all of these processes also implement their side of the
369     monitor protocols.
371     The OpenSSH 3.5p1 monitor protocol, on Solaris, has approximately 20
372     monitor request and corresponding response messages.
374     The SUNWssh monitor protocol has 5 monitor request and response
375     messages; additionally, the monitor processes standard re-key
376     messages (but note: the monitor and the session process IPC is
377     completely unencrypted), which amounts to about 14 more messages
378     altogether.
380     Much of the OpenSSH monitor protocol is a variation of the
381     on-the-wire ssh protocols, with some contents re-packaging.  We
382     believe this does not afford the monitor much additional, if any
383     protection from attacks in the key exchange and user authentication
384     protocols.
386     The re-packaging that is done in the OpenSSH monitor protocol is
387     risky business.  By separating the act of signing some blob of data
388     from computing that blob of data one can create an oracle; this is
389     exactly what happened in the OpenSSH case.
391     As you can see in the next section, the SUNWssh privilege separation
392     could evolve somewhat in the OpenSSH direction by saving the monitor
393     all transport protection work, but we cannot save the monitor much,
394     if any work relating to authentication or key exchange.
397 7.  Future Directions
399     The SUNWssh server privilege separation implementation could stand
400     several improvements.
402     The first improvement would be to have a single system-wide monitor.
403     This would reduce resource consumption.  The work needed to
404     implement such an enhancement is very similar to the work needed to
405     produce an SSH API and library, and it is not trivial.  If this is
406     not done then at least dropping PRIV_PROC_SETID and instead setting
407     the saved-set-user-id in the monitor to that of the logged in user
408     would be nice.
410     The second enhancement would be to add a "none" host key algorithm
411     to SSHv2 and a corresponding option in SUNWssh to disallow re-keying
412     with any other host key algorithm.  This would allow customers to
413     configure their server and monitor so that no re-key protocol
414     messages need be processed by the monitor.
416     A third enhancement would be to enhance the GSS-API mechanisms to
417     require fewer privileges.  In practice this means overhauling the
418     Kerberos V mechanism's replay cache.  This would allow the monitor
419     to run with fewer privileges.
421     Further, even without improving the Kerberos V mechanism's replay
422     cache it should be possible to drop at least PRIV_PROC_FORK/EXEC/
423     SESSION.
425     A fourth enhancement would to have the unprivileged process handle
426     all transport protection and proxy to the monitor all key exchange
427     and user authentication protocol messages.  This is a variation on
428     the OpenSSH model, but without the re-packaging of ssh message
429     contents seen there.  After authentication succeeds the monitor
430     could either change the unprivileged process' credentials (as can be
431     done with ppriv(1) or the unprivileged process would, as in OpenSSH,
432     pass the session keys/IVs/keystate to the monitor which would then
433     pass them to a new process, the session process, that would then run
434     as the logged in user.
437 8.  Guide to the AltPrivSep Source Code
440     First, a brief introduction to the SUNWssh/OpenSSH source code.
442     The source code is organized as follows:
444         $SRC/cmd/ssh/etc/
445             |
446             +-> config files
448         $SRC/cmd/ssh/include/
449             |
450             +-> header files (note: none are installed/shipped)
452         $SRC/cmd/ssh/libopenbsd-compat/common/
453             |
454             +-> misc. portability source code
456         $SRC/cmd/ssh/libssh/common/
457             |
458             +-> implementation of encoding, transport protection,
459                 various wrappers around cryptography, the key exchange
460                 and host authentication protocols, the session
461                 protocols, and misc. other code
463                 cipher.c
464                 mac.c
465                 compress.c
466                 packet.c
467                     |
468                     +-> transport protocol
470                 buffer.c
471                 bufaux.c
472                     |
473                     +-> encoding
475                 channels.c
476                 nchan.c
477                     |
478                     +-> session protocol
480                 kex.c
481                 kexdh.c
482                 kexgex.c
483                     |
484                     +-> key exchange/re-key code common to ssh and sshd
486                 kexdhs.c
487                 kexgexs.c
488                 kexgsss.c
489                     |
490                     +-> key exchange/re-key code (server only)
492                 kexdhc.c
493                 kexgexc.c
494                 kexgssc.c
495                     |
496                     +-> key exchange/re-key code (client only)
498                 dh.c
499                 rsa.c
500                 mpaux.c
501                 ssh-rsa.c
502                 ssh-dss.c
503                 ssh-gss.c
504                     |
505                     +-> crypto wrappers/utilities
507                 log.c
508                     |
509                     +-> logging, including debug logging, on stderr or
510                         syslog
513         $SRC/cmd/ssh/ssh/
514             |
515             +-> ssh(1)
517         $SRC/cmd/ssh/sshd/
518             |
519             +-> sshd(1M), including auditing, implementation of user
520                 authentication and the OpenSSH and SUNWssh monitors
522                 sshd.c
523                     |
524                     +-> main()
526                 auth*.c
527                     |
528                     +-> user authentication
530                 serverloop.c
531                 session.c
532                     |
533                     +-> session protocols
535                 bsmaudit.[ch]
536                 sshlogin.c
537                 loginrec.c
538                     |
539                     +-> auditing and record-keeping
541         $SRC/cmd/ssh/<misc commands>/
542             |
543             +-> scp, sftp, sftp-server, ssh-agent, ssh-add, ...
546     The SUNWssh altprivsep adds two new source files:
548         $SRC/cmd/ssh/include/altprivsep.h
549         $SRC/cmd/ssh/sshd/altprivsep.c
550             |
551             +-> monitor start routine, altprivsep_packet_*() routines
552                 for communication with the monitor, routines to help
553                 with key exchanges, service procedures for the monitor,
554                 etc...
556     and modifies the following:
558         $SRC/cmd/ssh/include/config.h
559             |
560             +> adds cpp define "ALTPRIVSEP"
562         $SRC/cmd/ssh/include/ssh2.h
563             |
564             +-> adds private message type "SSH2_PRIV_MSG_ALTPRIVSEP" (254)
566         $SRC/cmd/ssh/include/packet.h
567             |
568             +-> adds prototypes for several simple utility functions,
569                 some of which are specifically meant to avoid having to
570                 link altprivsep.c into ssh(1)
572         $SRC/cmd/ssh/libssh/common/kex.c
573         $SRC/cmd/ssh/libssh/common/packet.c
574             |
575             +-> implements the hooks needed to proxy re-key messages
576                 to/from the monitor
578         $SRC/cmd/ssh/sshd/Makefile
579             |
580             +-> adds altprivsep.o to list of objects linked into sshd(1M)
582         $SRC/cmd/ssh/sshd/serverloop.c
583             |
584             +-> adds an event loop for the monitor
585                 modifies the usual event loops for SSHv2
587         $SRC/cmd/ssh/sshd/session.c
588             |
589             +-> modifies do_login() and session_pty_cleanup2() to call
590                 altprivsep_record_login/logout() instead of
591                 record_login/logout().
593                 modifies do_exec_pty() so that the server waits for the
594                 call to altprivsep_record_login() in child process to
595                 complete before returning so that the server and the
596                 child processes do not compete for monitor IPC I/O.
598         $SRC/cmd/ssh/include/log.h
599         $SRC/cmd/ssh/libssh/common/log.c
600             |
601             +-> adds an internal interface, set_log_txt_prefix() so that
602                 the monitor's debug and log messages get prefixed with a
603                 string ("monitor ") that indicates they are from the
604                 monitor
606         $SRC/cmd/ssh/sshd/sshd.c
607             |
608             +-> modifies the body of code that follows the user
609                 authentication phase of the ssh protocols so as to start
610                 the monitor and move the relevant code into the monitor
611                 or session processes as appropriate while dropping
612                 privileges and access to privileged resources in the
613                 session process
615     The monitor uses the packet.h interfaces to communicate with the
616     session process as though it were its ssh client peer, but always
617     uses the "none" cipher, mac and compression algorithms and installs
618     even handlers only for the relevant key exchange messages and the
619     private monitor message used for the other monitor services.
621     The monitor serves the following services:
623      - APS_MSG_NEWKEYS_REQ      -> used to obtain keys/IVs after re-keys
624      - APS_MSG_RECORD_LOGIN     -> used to update utmpx/wtmpx
625      - APS_MSG_RECORD_LOGOUT    -> used to update utmpx/wtmpx
627     The session and monitor processes communicate over a pipe.
629     All monitor IPC I/O from the session process is blocking (though the
630     pipe is set to non-blocking I/O).  The monitor protocol is entirely
631     synchronous and relies on the re-key protocols being entirely
632     synchronous also (which they are, unlike the session protocols).
634     The kex.c and packet.c files are minimally modified, primarily to
635     prevent the monitor from handling SSH_MSG_NEWKEYS messages as a
636     normal ssh server should, instead letting the session process
637     process SSH_MSG_NEWKEYS messages by requesting the new keys
638     negotiated with client from the monitor.
640     Note that for SSHv1 no on-the-wire messages are processed by the
641     monitor after authentication.  In fact, the monitor thinks it's
642     running SSHv2, even if the on-the-wire protocol is v1.
645 A.  References
647     The IETF SECSH Working Group:
649         http://www.ietf.org/html.charters/secsh-charter.html
651     The SSHv2 architecture, assigned numbers:
653         http://www.ietf.org/internet-drafts/draft-ietf-secsh-architecture-16.txt
654         http://www.ietf.org/internet-drafts/draft-ietf-secsh-assignednumbers-06.txt
656     New cipher modes for SSHv2:
658         http://www.ietf.org/internet-drafts/draft-ietf-secsh-newmodes-02.txt
660     The SSHv2 "transport," including initial key exchange and re-key
661     protocols, but excluding negotiable DH group size and GSS-API-based
662     key exchange:
664         http://www.ietf.org/internet-drafts/draft-ietf-secsh-transport-18.txt
666     Additional key exchange protocols for SSHv2:
668         http://www.ietf.org/internet-drafts/draft-ietf-secsh-gsskeyex-08.txt
669         http://www.ietf.org/internet-drafts/draft-ietf-secsh-dh-group-exchange-04.txt
671     Base user authentication spec for SSHv2 (includes none, password,
672     pubkey and hostbased user authentication):
674         http://www.ietf.org/internet-drafts/draft-ietf-secsh-userauth-21.txt
676     SSHv2 user authentication using PAM-style prompting:
678         http://www.ietf.org/internet-drafts/draft-ietf-secsh-auth-kbdinteract-06.txt
680     SSHv2 user authentication using the GSS-API:
682         http://www.ietf.org/internet-drafts/draft-ietf-secsh-gsskeyex-08.txt
684     SSHv2 "session" protocol (i.e., the protocol used for pty sessions,
685     port forwarding, agent forwarding, X display forwarding, etc...):
687         http://www.ietf.org/internet-drafts/draft-ietf-secsh-connect-19.txt