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