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