Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 53 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
53
Dung lượng
1,6 MB
Nội dung
CHAPTER 7 ■ SECURING NETWORK CONNECTIONS I: SSL 131 Accept-Ranges: bytes Content-Length: 141 Connection: close Content-Type: text/html; charset=ISO-8859-1 <html> <head> <meta http-equiv="refresh" content="0;url=/xampp/"> </head> <body bgcolor=#ffffff> <p>Hello world.</p> </body> </html> Metadata: Array ( [stream_type] => tcp_socket/ssl [mode] => r+ [unread_bytes] => 0 [timed_out] => [blocked] => 1 [eof] => 1 ) After the initialization message, the dump of the stream begins with the raw HTTP response from the server, the one-line header (setting the content type), and then the entity-body of the response. Then, the stream metadata array is dumped. This section (here edited slightly for simplicity; a complete list of metadata properties is at http://php.net/stream-get-meta-data) includes the type of the stream, the mode (read/write in this case), and the number of bytes that were not read. You checked the timed_out property in your script to determine whether the connection had timed out; if it had, this would have been set to 1. The blocked property is a bit obscure, but it works like this: when a stream is in blocking mode, any PHP function that reads from the stream is going to wait for some response from the server. While this is convenient, there are times when you may want to use a loop that checks for output on the stream while also doing other things in the background. This can be handy when requesting information from slow servers, or when requesting large amounts of data over a slow connection, because it allows you to use your own logic to determine when the connection has timed out. You can use the stream_set_blocking() function to change the blocked property of a stream. Finally, the eof property tells you (in this case, somewhat redundantly, since you know already that there were no unread bytes) that you successfully reached the end of the target file. ■Caution Microsoft’s IIS violates the SSL protocol by failing to send a close_notify indicator before closing the connection. This is indicated by PHP’s reporting an “SSL: Fatal Protocol Error” at the end of the data. See the PHP manual page at http://php.net/wrappers to work around this issue. SnyderSouthwell_5084C07.fm Page 131 Friday, July 8, 2005 11:37 AM 132 CHAPTER 7 ■ SECURING NETWORK CONNECTIONS I: SSL The HTTPS Wrapper Using the TLS transport directly provides you with absolute control over all aspects of the communication, but as you can see, it also requires a lot of code. In cases where such a fine degree of control is unnecessary (for example, any time you don’t have to worry about constructing complex POST requests or specifying short timeouts), the built-in https:// wrapper provides the same functionality as that we demonstrated earlier with quite a bit less effort on your part. Again, PHP 4.3.0 and above supports the https:// wrapper only if PHP has been compiled with OpenSSL support. If you are using the https:// wrapper, the stream itself provides access to the content of the resource, and the returned headers are stored in the (with HTTP instead of HTTPS, slightly misnamed) $http_response_header variable, which is accessible with the stream_get_meta_data() function. We demonstrate here using PHP how to read the contents of a remote file, where the server is accessed with an SSL connection (that is, using a Certificate). This code can be found also as httpsDemo.php in the Chapter 7 folder of the downloadable archive of code for Pro PHP Security at http://www.apress.com. <?php header( 'Content-Type: text/plain' ); $httpsUri = 'https://localhost/index.html'; // create a context $options = array( 'http' => array( 'user_agent' => 'sslConnections.php' ), 'ssl' => array( 'allow_self_signed' => TRUE ) ); $context = stream_context_create( $options ); // open a stream via HTTPS $stream = @fopen( $httpsUri, 'r', FALSE, $context ); if ( !$stream ) exit( "Could not open $httpsUri." ); print "Successfully opened $httpsUri; results are shown below.\r\n\r\n"; print "Resource:\r\n"; // get resource $resource = stream_get_contents( $stream ); print_r( $resource ); print "\r\n"; print "Metadata:\r\n"; // look at the metadata $metadata = stream_get_meta_data( $stream ); print_r( $metadata ); // free the stream fclose( $stream ); ?> SnyderSouthwell_5084C07.fm Page 132 Friday, July 8, 2005 11:37 AM CHAPTER 7 ■ SECURING NETWORK CONNECTIONS I: SSL 133 This script is straightforward. You want to view a remote file using a secure connection, so you set variables to contain the fully qualified URI of the file and the options that the connection will use. In order to set the options, you need to create a PHP context resource that holds the options. As we mentioned before, when you create a context, you pass an array of options to stream_context_create(). This is actually an associative array of associative arrays, one array of options for each wrapper or transport being used in the stream. So you create an array with two arrays of options, one for the HTTPS wrapper and one for the SSL transport underneath it. In the HTTPS options, you set the User-Agent string to use (not because this is particularly important, but for demonstration purposes, just because you can), and in the SSL options you tell the system to accept a self-signed Certificate. You then open a stream using the fopen() function, in read-only mode and without using the include path, and suppressing display of any errors (which could be a security risk, exposing for example your file structure to an attacker) with the @ operator. A clear advantage of using wrappers is that you do not need to build and send the request yourself (as you did earlier with the transport); the wrapper handles that for you. Then you simply display what is returned by the stream. The remote file must of course be readable by the remote webserver, and the remote webserver must be up and processing requests for this operation to succeed. The output of this script on our test system is as follows: Successfully opened https://localhost/, results are shown below. Resource: <html> <head> <meta http-equiv="refresh" content="0;url=/xampp/"> </head> <body bgcolor=#ffffff> <p>Hello world.</p> </body> </html> Metadata: Array ( [wrapper_data] => Array ( [0] => HTTP/1.1 200 OK [1] => Date: Thu, 17 Mar 2005 15:10:03 GMT [2] => Server: Apache/2.0.53 (Unix) mod_ssl/2.0.53 OpenSSL/0.9.7d ➥ PHP/5.0.3 DAV/2 mod_perl/1.999.21 Perl/v5.8.6 [3] => Accept-Ranges: bytes [4] => Content-Length: 141 [5] => Connection: close [6] => Content-Type: text/html; charset=ISO-8859-1 ) [wrapper_type] => HTTP [stream_type] => tcp_socket/ssl [mode] => r+ SnyderSouthwell_5084C07.fm Page 133 Friday, July 8, 2005 11:37 AM 134 CHAPTER 7 ■ SECURING NETWORK CONNECTIONS I: SSL [unread_bytes] => 0 [seekable] => [uri] => https://localhost/ [timed_out] => [blocked] => 1 [eof] => ) The resource is simply the entity body of the requested file. The metadata as usual provides us with a lot of data about the operation. The wrapper_data property gives us an array consisting of the seven lines of the raw HTTP response. The remaining properties are either self-descriptive or were discussed earlier. The FTP and FTPS Wrappers The built-in ftp:// wrapper provides FTP support. Its more secure relative, the ftps:// wrapper, like the https:// wrapper we have just discussed, provides simpler and equivalent functionality to that available with the ssl:// and tls:// transports. Once again, PHP 4.3.0 and above support these wrappers only if PHP has been compiled with OpenSSL support. It should be noted that the FTPS support in PHP is designed to gracefully fall back to a normal, plaintext authenticated FTP session if the remote FTP server doesn’t support SSL. This is, from a security standpoint, a very poor implementation. If you need to ensure that your files are transmitted securely, we encourage you to leave FTPS alone and continue on to our discus- sion of scp and sftp in Chapter 8. Nevertheless, if you have no choice but to connect to an SSL- enabled FTP server, you can do so using PHP. Ideally, your FTP server should be configured to accept connections only via SSL, so that if SSL isn’t available for some reason, PHP won’t transmit your passwords and files in the clear. We will demonstrate the use of the FTP module’s built-in ftp_ssl_connect() function and the ftps:// wrapper, to clarify their differences. We begin with the simpler ftp_ssl_connect() function, the code for which follows. It can be found also as ftpsDemo.php in the Chapter 7 folder of the downloadable archive of code for Pro PHP Security at http://www.apress.com. <?php header( 'Content-Type: text/plain' ); $ftpsServer = 'ftps.example.net'; $ftpsPort = 990; $ftpsUsername = 'jexample'; $ftpsPassword = 'wefpo4302e'; // make ssl connection $ftps = ftp_ssl_connect( $ftpsServer, $ftpsPort ); if ( !$ftps ) exit( "Could not make FTP-SSL connection to $ftpsServer." ); print "Successfully connected via FTP-SSL to $ftpsServer.\r\n"; SnyderSouthwell_5084C07.fm Page 134 Friday, July 8, 2005 11:37 AM CHAPTER 7 ■ SECURING NETWORK CONNECTIONS I: SSL 135 // log in if ( !ftp_login( $ftps, $ftpsUsername, $ftpsPassword ) ) { exit( "Unable to log in as $ftpsUsername.\r\n" ); } else { print "Logged in as $ftpsUsername.\r\n"; } // carry out FTP commands $cwd = ftp_pwd( $ftps ); print "Current working directory: $cwd\r\n"; // // close the connection ftp_close( $ftps ); ?> This code is very simple. After setting a variable to the name of your target server, you use the ftp_ssl_connect() function to make the connection, and print a message. You log in, carry out whatever commands you wish (for demonstration purposes here, just one simple one), and close the connection. The output from this code on our system follows: Successfully connected via FTP-SSL to example.org. Logged in as jexample. Current working directory: /home/jexample After an informational message, you simply view a record of the commands that were executed. The problem with this, again, is that the server will uncomplainingly fall back to standard FTP if for some reason SSL is not available. So while the transaction is indeed secure whenever SSL is available to manage the transfers, this method leaves the door open to insecurity. And so now we demonstrate the use of the streams using a more secure ftps:// wrapper, the code for which follows. It can be found also as ftpsWrapperDemo.php in the Chapter 7 folder of the downloadable archive of code for Pro PHP Security at http://www.apress.com. <?php header( 'Content-Type: text/plain' ); $ftpsUri = 'ftps://jexample:wefpo4302e@example.net/public_html/idex.css'; $stream = fopen( $ftpsUri, 'r' ); if ( !$stream ) exit( "Could not open $ftpsUri." ); print "Successfully opened $ftpsUri; results are shown below.\r\n\r\n"; print "File data:\r\n"; print stream_get_contents( $stream ); SnyderSouthwell_5084C07.fm Page 135 Friday, July 8, 2005 11:37 AM 136 CHAPTER 7 ■ SECURING NETWORK CONNECTIONS I: SSL print "Metadata:\r\n"; // look at the metadata $metadata = stream_get_meta_data( $stream ); print_r( $metadata ); // free the stream fclose( $stream ); ?> This code again is perfectly straightforward (it is essentially identical to the https:// wrapper code shown earlier). You open a stream to a specific file on the server using the ftps:// wrapper, and then print out the stream and metadata contents. The output from this code follows: Successfully opened ftps://jexample:wefpo4302e@example.net/public_html/idex.css;➥ results are shown below. File data: a:link { color:#388; text-decoration:none; } a:visited { color:#776; text-decoration:none; } a:hover { color:#333; text-decoration:underline; } Metadata: Array ( [wrapper_data] => [wrapper_type] => FTP [stream_type] => tcp_socket/ssl [mode] => r+ [unread_bytes] => 0 [seekable] => [uri] => ftps://jexample:wefpo4302e@example.net/public_html/idex.css [timed_out] => [blocked] => 1 [eof] => 1 ) SnyderSouthwell_5084C07.fm Page 136 Friday, July 8, 2005 11:37 AM CHAPTER 7 ■ SECURING NETWORK CONNECTIONS I: SSL 137 What is most striking about this output is how much more data about the operation is available to you as a result of using the streams model (with its accompanying metadata) rather than the FTP module’s functions. And again, this method is much more secure than FTP-SSL because there is no chance of accidentally carrying out the transfers insecurely. Secure IMAP and POP Support Using TLS Transport Interacting with mailboxes can be tricky because of the considerable security danger of exposing mailbox passwords. In such a setting, the security offered by SSL is invaluable. Unfortunately, it is a bit tricky to set up, because PHP’s IMAP module must be explicitly told to use SSL or TLS. If you do so, then you will be able to take advantage of the streams model for communication. For more information, see the PHP manual page at http://php.net/imap-open. PHP’s imap_open function takes as its first parameter a mailbox name. This consists of two parts: a server part and an optional mailbox path. The server part itself is complicated; it consists of the name or IP address of the server, plus an optional port with a prepended : (colon), plus a protocol designation (either SSL or TLS) with a prepended / (slash), with the entire server part enclosed in { } (curly brackets). Such a server part might look something like this: {my.imap.host:199/tls} It is that /tls protocol designation that forces the function to take advantage of TLS. A default value for the mailbox path is INBOX, which points to the mailbox of the current user. The other parameters to the imap_open function are a username, a password, and some additional optional parameters (listed on the manual page). And now we demonstrate the use of the tls:// Transport Layer with PHP’s imap_open function to read an IMAP mailbox securely, the code for which follows. It can be found also as imapDemo.php in the Chapter 7 folder of the downloadable archive of code for Pro PHP Security at http://www.apress.com. <?php // force tls in the mailbox identifier $mailbox = "{localhost:993/imap/tls}INBOX"; $user = 'username'; $pass = 'password'; // open the mailbox $mbox = imap_open( $mailbox, $user, $pass ); if ( !$mbox ) exit( "Could not open $mailbox." ); print "Successfully opened $mailbox.\n"; // carry out imap calls // free the mailbox imap_close( $mbox ); ?> SnyderSouthwell_5084C07.fm Page 137 Friday, July 8, 2005 11:37 AM 138 CHAPTER 7 ■ SECURING NETWORK CONNECTIONS I: SSL This code is once again perfectly straightforward, since PHP’s functions are doing all the work for you. It is, however, worth noting the /imap option in the $mailbox specification, which might seem redundant with the imap_open() function call. It is required because imap_open() can also open POP mailboxes. Summary After defining the necessary background concepts (the SSL and TLS protocols, Certificates, Certificate Authorities, Certificate Chains, and Certificate Revocation Lists), we described the SSL Record and Handshake Protocols. We then turned to the topic of providing SSL on your servers. We described how to set the many and complex directives in Apache’s mod_ssl module, and provided a sample SSL config- uration file. We next described how to obtain the necessary Server Certificate. Then, we described some ways in which SSL is already built in to existing applications. Finally, we provided several PHP scripts that use the SSL protocol to interact securely with a remote server in a whole variety of ways. In Chapter 8, we’ll move on to a different way to secure network connections, Secure Shell, used more commonly for administrative and developer connections than for application user interfaces. SnyderSouthwell_5084C07.fm Page 138 Friday, July 8, 2005 11:37 AM 139 ■ ■ ■ CHAPTER 8 Securing Network Connections II: SSH I n Chapter 7, we discussed the first of the two most prominent methods for securing network connections: Secure Sockets Layer (SSL) and its relative, Transport Layer Security (TLS). In this chapter, we turn to the second method, Secure Shell (SSH), which unlike SSL is most commonly used to secure connections for administrative purposes. Secure Shell will forward either a command line or a window from a remote host to a client, by means of which you can interact with that remote host as if you were physically present. Think of it as a console interface to the world, and you’ll have some idea of its potential. A Secure Shell client suite typically includes support for a command shell, file transfer, network port forwarding, and X11 window forwarding capability. We will cover all of these topics in this chapter. PHP’s PECL extension library has the ability to speak SSH2, and in this chapter we will show you some ways to use it for accomplishing system administration tasks on remote servers. Definitions Operators of Secure Shell services need to be familiar with a number of concepts in order to properly use them, therefore we’ll begin by introducing you to those concepts, in preparation for actually implementing and using Secure Shell on your servers. The Original Secure Shell Secure Shell is a connection protocol for secure remote login and other secure network services (like command execution and file transfer) over an insecure network. It is a replacement for notoriously insecure utilities like the eV]_Ve protocol and BSD’s original file transfer utility, cTa, which not only transmit passwords in plaintext, but also can allow unauthorized access in a variety of other ways (for example, by failing to prevent hostname spoofing). Secure Shell was developed in 1995 by Tatu Ylönen after his graduation from Helsinki University, and was first released under a GNU Public License. The term SSH is a trademark of SSH Communications Security, the company founded by Ylönen (who is its CTO), and the vendor of SSH Tectia (see Yeea+ hhhddYT`^ ). Commercial implementations of Secure Shell are typi- cally free for university and other noncommercial use, but must be licensed for commercial use. An Open Source distribution of SSH also exists, OpenSSH (see Yeea+ hhh`aV_ddYT`^ ), which we will discuss at length later in this chapter. SnyderSouthwell_5084.book Page 139 Wednesday, July 27, 2005 12:24 PM 140 CHAPTER 8 ■ SECURING NETWORK CONNECTIONS II: SSH The Secure Shell connection protocol employs three separate activity layers (subprotocols, as it were): •A Transport Layer, which establishes an SSH session ID, authenticates the host (ensuring that you are talking to the right server), and ensures a confidential exchange of information by providing a reliable symmetric key to use for encryption of messages. This layer is roughly comparable to SSL’s Handshake Protocol. •An Authentication Layer, which authenticates the client (so that the server knows who it is talking to). Unlike SSL, which leaves authentication up to applications, Secure Shell handles authentication on its own. To some extent, this makes it superior to SSL for administrative operations, because the authentication routines are centralized, trans- parent, and well tested. But it also means that a Secure Shell user must have an account on the server. This is why SSH is typically an administrative tool rather than a way for a multitude of users to carry out secure web transactions. •A Connection Layer, which establishes multiple discrete and multiplexed channels (thus allowing different activities, such as X11 forwarding, file transfer, and shell operations, in a single authenticated session). This layer is roughly comparable to SSL’s Record Protocol. The SSH protocol requires encryption but does not specify any particular encryption algorithms. Rather, it simply recommends the use of any of a whole variety of well-established and well-tested algorithms with key length of 128 bits or more; we discussed the most common of these, 3DES, AES, and Blowfish in the symmetric camp, and RSA and Diffie-Hellman-Merkle in the asymmetric camp, in Chapter 5. Secure Shell Protocol Versions There are two principal versions of the Secure Shell connection protocol in use today: version 1, which was used in the original implementation of Secure Shell, and version 2, which was developed later to address a weakness in the original protocol, and to include newer encryption algorithms as well as Diffie-Hellmann-Merkle key exchange. The two protocols are, unfortunately, so different as to not be forward or backward compatible. Therefore, most general-use clients and servers implement both, allowing the user or the system administrator to make the decision about which to use. We recommend SSHv2 for all applications, all the time. Disable version 1 if you can. To understand why, let’s take a closer look at the two protocols. Secure Shell Protocol Version 1 Every server running SSHv1 possesses a permanent RSA key (actually a public and private key pair), with a key size of 1024 bits (which is typically considered sufficient for security). This host key can be used to verify the identity of the server. Whenever a client requests a connection, a new daemon is forked that has responsibility for all aspects of that connection. The first responsibility of this forked daemon is to generate another RSA key pair, this one normally 768 bits, which can be used to identify this session on this server. This key is always kept in memory, never written to disk, and for that reason it is also called ephemeral. The ephemeral key has a lifetime of only one hour (unless it is not used) before it is regenerated. SnyderSouthwell_5084.book Page 140 Wednesday, July 27, 2005 12:24 PM [...]... recommend that you consider using it along with something as powerful as SSH, unless you actually require the flexibility it provides Information about PAM is available at Yeea+ hhh\Vc_V]`cX afS ]Z_fi ]ZSd aR^ 143 SnyderSouthwell_50 84. book Page 144 Wednesday, July 27, 2005 12: 24 PM 144 CHAPTER 8 ■ SECURING NETWORK CONNECTIONS II: SSH Using OpenSSH for Secure Shell While there are many different Secure... allows you to ignore a number of directives that apply only to protocol 1 This simplification makes your configuration file easier to read 147 SnyderSouthwell_50 84. book Page 148 Wednesday, July 27, 2005 12: 24 PM 148 CHAPTER 8 ■ SECURING NETWORK CONNECTIONS II: SSH Setting Cryptographic Parameters 4ZaYVcdRVd#&'TST$UVdTSdS]`hWZdYTST >24dY^RTdYR"Y^RTcZaV^U"'!Y^RT^U& These options set fairly... Secure Shell protocol Finally, after authentication has been accomplished, the Connection Layer manages all communication, again by using the ephemeral key and the chosen cipher to encrypt each message before transmission 141 SnyderSouthwell_50 84. book Page 142 Wednesday, July 27, 2005 12: 24 PM 142 CHAPTER 8 ■ SECURING NETWORK CONNECTIONS II: SSH The careful reader will have noticed already the security. .. simpler and safer than the default settings This code can be found also as ddYUPT`_WZX in the Chapter 8 folder of the downloadable archive of code for Pro PHP Security at Yeea+ hhhRacVddT`^ SnyderSouthwell_50 84. book Page 149 Wednesday, July 27, 2005 12: 24 PM CHAPTER 8 ■ SECURING NETWORK CONNECTIONS II: SSH A`ce## dR^a]VRUUcVddVd`_]jTYR_XVW`cj`fc`h__VVUd =ZdeV_2UUcVdd"#(!!" =ZdeV_2UUcVdd"*#"')"#$%&... password, using SSH’s PubkeyAuthentication So which method should you use? 153 SnyderSouthwell_50 84. book Page 1 54 Wednesday, July 27, 2005 12: 24 PM 1 54 CHAPTER 8 ■ SECURING NETWORK CONNECTIONS II: SSH In many ways, using a strong password (or even better, a strong passphrase) provides the highest level of security But passwords are not invulnerable; they could theoretically be copied by someone looking... recommend that it not be permitted (although we admit that it could be useful to facilitate the work of certain kinds of unattended processes, like data backups and software updates) So version 2 of the SSH communication protocol provides a number of important improvements to message security, by not reusing the same server key, by closing a potentially dangerous loophole in the Authentication Layer, by disallowing... . archive of code for Pro PHP Security at Yeea+ hhhRacVddT`^. SnyderSouthwell_50 84. book Page 148 Wednesday, July 27, 2005 12: 24 PM CHAPTER 8 ■ SECURING NETWORK CONNECTIONS II: SSH 149 A`ce## dR^a]VRUUcVddVd`_]jTYR_XVW`cj`fc`h__VVUd =ZdeV_2UUcVdd"#(!!" =ZdeV_2UUcVdd"*#"')"#$%& cVdecZTeRTTVddR_Uac`e`T`]]VgV] 2]]`h8c`fadddYhYVV] AVc^ZeC``e=`XZ__` Ac`e`T`]# 9`de<Vj]`TReZ`_dW`cac`e`T`]gVcdZ`_# 9`de<Vj. flexibility it provides. Information about PAM is available at Yeea+ hhhVc_V]`cX afS ]Z_fi ]ZSd aR^ . SnyderSouthwell_50 84. book Page 143 Wednesday, July 27, 2005 12: 24 PM 144 CHAPTER 8 ■ . chapter. SnyderSouthwell_50 84. book Page 139 Wednesday, July 27, 2005 12: 24 PM 140 CHAPTER 8 ■ SECURING NETWORK CONNECTIONS II: SSH The Secure Shell connection protocol employs three separate activity layers (subprotocols,