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