1 Copyright 2007 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 v1. 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