1 Copyright 2008 Sun Microsystems, Inc. All rights reserved. 2 Use is subject to license terms. 3 4 Sun's Alternative "Privilege Separation" for OpenSSH 5 6 7 Table of Contents 8 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 19 20 21 22 23 24 1. Introduction 25 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. 32 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. 40 41 The ssh team at Sun agrees with the basic OpenSSH privilege 42 separation concept, but disagrees with its design. 43 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. 49 50 51 2. What is "Privilege?" 52 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. 60 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. 66 67 68 3. Analysis of the SSH Protocols 69 70 There are two or, rather three SSH protocols: 71 72 - version 1 73 - version 1.5 74 - version 2 75 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. 78 79 Familiarity by the reader with the specifications for these 80 protocols is not assumed, but would be beneficial to the reader. 81 82 Quite roughly, these protocols consist of the following: 83 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) 94 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. 98 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. 103 104 SUNWssh is based on OpenSSH, so it is comparable in size and 105 complexity to OpenSSH. 106 107 There is, then, plenty of space for security bugs in the OpenSSH, 108 and, therefore, also in the SUNWssh source code bases. 109 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. 114 115 116 3.1. Privileged Resources, Operations, in the SSH Protocols 117 118 What privileges does an SSH server need then? 119 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. 122 123 No privilege or privileged resources are needed to implement the 124 parts (a)-(d) mentioned in section 3. 125 126 127 For key exchange and server authentication (e) an ssh server requires: 128 129 - Access to the host's ssh private keys. 130 131 - Access to the host's GSS-API acceptor credentials. [SSHv2-only] 132 133 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. 137 138 139 Post-authentication an ssh server requires the following privileges: 140 141 - Those required for auditing a user's subsequent logout. 142 143 That is, PRIV_PROC_AUDIT. 144 145 146 - Those required for record keeping (i.e., utmpx/wtmpx logging). 147 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. 152 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. 156 157 158 - Those required for accessing the host's ssh private keys for 159 SSHv2 re-keying. [SSHv2-only] 160 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. 164 165 166 - Those required for accessing the host's GSS-API acceptor 167 credentials for SSHv2 re-keying. 168 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). 173 174 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. 181 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. 187 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. 192 193 194 4. OpenSSH's Privilege Separation 195 196 The OpenSSH privilege separation model is quite complex. 197 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. 205 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. 209 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. 215 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. 219 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. 223 224 225 5. SUNWssh's Alternative Privilege Separation 226 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. 234 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. 239 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). 243 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. 247 248 This approach allows us to have a very simple monitor protocol. Our 249 monitor protocol consists of the following operations: 250 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 256 257 Logout auditing is done when the session process dies and so does 258 not require a monitor protocol message. 259 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). 265 266 Odds and ends: 267 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. 272 273 - The monitor does not attempt to update utmpx/wtmpx independently 274 of its child -- it depends on the child asking it to. 275 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). 279 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. 297 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. 309 310 6. Comparison of the OpenSSH and SUNWssh PrivSep Models 311 312 The OpenSSH server involves three processes which we will term 313 "pre-session," "session" and "monitor." 314 315 The OpenSSH pre-session process implements: 316 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 322 323 The OpenSSH session process implements: 324 325 - the ssh message encoding/decoding 326 - transport protection 327 - most of the re-keying protocols 328 - the session protocols 329 330 The OpenSSH monitor process implements: 331 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: 336 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 343 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. 347 348 Similarly for any vulnerabilities in PAM modules and GSS-API 349 mechanisms. 350 351 The SUNWssh server involves two processes which we will term 352 "session" and "monitor." 353 354 The SUNWssh monitor process implements: 355 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 361 362 The SUNWssh session process implements: 363 364 - the ssh message encoding/decoding 365 - transport protection 366 - the session protocols 367 368 Obviously all of these processes also implement their side of the 369 monitor protocols. 370 371 The OpenSSH 3.5p1 monitor protocol, on Solaris, has approximately 20 372 monitor request and corresponding response messages. 373 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. 379 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. 385 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. 390 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. 395 396 397 7. Future Directions 398 399 The SUNWssh server privilege separation implementation could stand 400 several improvements. 401 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. 409 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. 415 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. 420 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. 424 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. 435 436 437 8. Guide to the AltPrivSep Source Code 438 439 440 First, a brief introduction to the SUNWssh/OpenSSH source code. 441 442 The source code is organized as follows: 443 444 $SRC/cmd/ssh/etc/ 445 | 446 +-> config files 447 448 $SRC/cmd/ssh/include/ 449 | 450 +-> header files (note: none are installed/shipped) 451 452 $SRC/cmd/ssh/libopenbsd-compat/common/ 453 | 454 +-> misc. portability source code 455 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 462 463 cipher.c 464 mac.c 465 compress.c 466 packet.c 467 | 468 +-> transport protocol 469 470 buffer.c 471 bufaux.c 472 | 473 +-> encoding 474 475 channels.c 476 nchan.c 477 | 478 +-> session protocol 479 480 kex.c 481 kexdh.c 482 kexgex.c 483 | 484 +-> key exchange/re-key code common to ssh and sshd 485 486 kexdhs.c 487 kexgexs.c 488 kexgsss.c 489 | 490 +-> key exchange/re-key code (server only) 491 492 kexdhc.c 493 kexgexc.c 494 kexgssc.c 495 | 496 +-> key exchange/re-key code (client only) 497 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 506 507 log.c 508 | 509 +-> logging, including debug logging, on stderr or 510 syslog 511 512 513 $SRC/cmd/ssh/ssh/ 514 | 515 +-> ssh(1) 516 517 $SRC/cmd/ssh/sshd/ 518 | 519 +-> sshd(1M), including auditing, implementation of user 520 authentication and the OpenSSH and SUNWssh monitors 521 522 sshd.c 523 | 524 +-> main() 525 526 auth*.c 527 | 528 +-> user authentication 529 530 serverloop.c 531 session.c 532 | 533 +-> session protocols 534 535 bsmaudit.[ch] 536 sshlogin.c 537 loginrec.c 538 | 539 +-> auditing and record-keeping 540 541 $SRC/cmd/ssh/<misc commands>/ 542 | 543 +-> scp, sftp, sftp-server, ssh-agent, ssh-add, ... 544 545 546 The SUNWssh altprivsep adds two new source files: 547 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... 555 556 and modifies the following: 557 558 $SRC/cmd/ssh/include/config.h 559 | 560 +> adds cpp define "ALTPRIVSEP" 561 562 $SRC/cmd/ssh/include/ssh2.h 563 | 564 +-> adds private message type "SSH2_PRIV_MSG_ALTPRIVSEP" (254) 565 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) 571 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 577 578 $SRC/cmd/ssh/sshd/Makefile 579 | 580 +-> adds altprivsep.o to list of objects linked into sshd(1M) 581 582 $SRC/cmd/ssh/sshd/serverloop.c 583 | 584 +-> adds an event loop for the monitor 585 modifies the usual event loops for SSHv2 586 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(). 592 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. 597 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 605 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 614 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. 620 621 The monitor serves the following services: 622 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 626 627 The session and monitor processes communicate over a pipe. 628 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). 633 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. 639 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. 643 644 645 A. References 646 647 The IETF SECSH Working Group: 648 649 http://www.ietf.org/html.charters/secsh-charter.html 650 651 The SSHv2 architecture, assigned numbers: 652 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 655 656 New cipher modes for SSHv2: 657 658 http://www.ietf.org/internet-drafts/draft-ietf-secsh-newmodes-02.txt 659 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: 663 664 http://www.ietf.org/internet-drafts/draft-ietf-secsh-transport-18.txt 665 666 Additional key exchange protocols for SSHv2: 667 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 670 671 Base user authentication spec for SSHv2 (includes none, password, 672 pubkey and hostbased user authentication): 673 674 http://www.ietf.org/internet-drafts/draft-ietf-secsh-userauth-21.txt 675 676 SSHv2 user authentication using PAM-style prompting: 677 678 http://www.ietf.org/internet-drafts/draft-ietf-secsh-auth-kbdinteract-06.txt 679 680 SSHv2 user authentication using the GSS-API: 681 682 http://www.ietf.org/internet-drafts/draft-ietf-secsh-gsskeyex-08.txt 683 684 SSHv2 "session" protocol (i.e., the protocol used for pty sessions, 685 port forwarding, agent forwarding, X display forwarding, etc...): 686 687 http://www.ietf.org/internet-drafts/draft-ietf-secsh-connect-19.txt