Using an SSL capable web server, Secure Socket Layer (SSL), is a great way of improving the security of your web site without having to change one single line of code. What SSL does is use cryptography to protect the flow of information between the web server and the browser. Not only does SSL encrypt all the data flowing over the Internet, it also provides the means for both parties to authenticate each other. This way, you can buy things on-line without any third party being able to see your credit card information. These characteristics make SSL very well suited for use in applications where sensitive information needs to be exchanged, such as e-commerce and web based email.
SSL uses an encryption technique called public key cryptography, where the server end of the connection sends the client a public key for encrypting information which only the server can decrypt with the private key it holds. The client uses the public key to encrypt and send the server its own key, identifying it uniquely to the server and preventing onlookers at points between the two systems from mimicking either server or client (generally known as a man-in-the-middle attack).
Secure HTTP is usually distinguished from regular unencrypted HTTP by being served on a different port number, 443 instead of 80. Clients told to access a URL with Secure HTTP automatically connect to port 443 rather than 80, making it easy for the server to tell the difference and respond appropriately.
There are several solutions for implementing SSL with Apache including the Apache-SSL project and the commercial StrongHold and Raven SSL implementations.
In this section, we're going to look at implementing SSL with the mod_ssl module and the OpenSSL library. This has a slight edge over Apache-SSL because it abstracts the actual SSL functionality into a module, making it possible to load dynamically. It also compiles happily on both UNIX and Windows platforms.
Using Apache as a specific example of a webserver, we will just explain how to set it up for use with SSL.
Downloading OpenSSL and ModSSL
mod_ssl requires patches to be made to the original Apache source code. This is somewhat strange, since the object of mod_ssl was to remove all cryptography code from 'regular' Apache, allowing it to be distributed freely, and there seems to be no good reason why the patches aren't incorporated into Apache as standard.
The Apache source must be patched with the correct version of mod_ssl. For this reason the mod_ssl package comes with the Apache version number built in, for example mod_ssl-2.4.4-1.3.9. This translates as 'mod_ssl version 2.4.4 for Apache 1.3.9'. mod_ssl has its own web site from which current releases can be downloaded at http://www.modssl.org/.
mod_ssl tends to track the current release quite rapidly, but it is possible that a version of mod_ssl is not yet available for the latest Apache release. In this case we must either wait for mod_ssl to catch up or use a slightly earlier version of the Apache source.
OpenSSL also has its own web site, at http://www.openssl.org/.
In addition, US sites will need the RSAREF library to comply with patent restriction. This is no longer available from RSA's own web site but can be found on a few European FTP servers (RSAREF is patented only in the USA), for example: ftp://ftp.replay.com/pub/crypto/crypto/LIBS/rsa/.
Prebuilt packages are available for both mod_ssl and OpenSSL for some platforms; packages for Linux systems are available from rpmfind.net and http://nonus.debian.org.
Be careful unpacking the archive; it does not put its contents into a single subdirectory. Instead use something like:
Building and Installing the OpenSSL library After unpacking OpenSSL, change down into the top directory and run the config script:
This should automatically configure the library build for the target platform. If the config script guesses wrongly (probably because we're using a platform that it doesn't recognize) we can override it by using the Configure script instead, as we will see later.
If we want to install the libraries then we can also set the installation paths. Historically, the default install location for both the OpenSSL libraries and their support files is /usr/local/ssl; we can change this by specifying arguments to the script:
It isn't actually necessary to install OpenSSL completely, as we can tell mod_ssl where to look for the OpenSSL libraries when we come to build it. However if we want to use them for other applications or we want to build them as dynamically linked libraries, it is useful to install them permanently.
In addition, the following options, none of which have double minus prefixes, can be used to customize the library:
Explicity enables or disables the use of threaded code in the library. Threaded code is more efficient, but may cause problems on some platforms. The default is to let the config script figure it out; this option might need to be set for more obscure platforms.
Does not use assembly code to build the library. The OpenSSL package comes with fast assembly language routines for several different processor types and platforms and the config script will pick one if it finds a suitable match. This option forces the build process to resort to slower C-based routines instead. Normally the config script will work this out automatically; use this option to override it.
Relvant to x86 processor architectures only. The default assembly code provided for these processors requires a 486 or better. Specifying this option causes OpenSSL to be built with 386 compatible assembly code.
Excludes a particular cipher from the library. The list of ciphers included (and which can be specified here) is: bf, cast, des, dh, dsa, hmac, md2, md5, mdc2, rc2, rc4, rc5, rsa, sha. For example:
Causes OpenSSL to be built with the RSAREF reference implementation rather than its own internal implementation. Inclusion of the RSAREF library may be required legally. Read the section below before choosing to enable or ignore this option.
-D, -l, -L, -f, -K
Passes flags to the compiler or linker stages; for example: -L/usr/local/lib For example, to configure OpenSSL to use threads, exclude the md2 and rc2 ciphers, and use RSAREF, we would use:
Once the build process is configured, the library can be built and tested with:
If we are also installing the libraries, we can also use:
The brave can do all three steps in one go with:
This creates and installs the OpenSSL libraries as statically linked libraries with a .a suffix.
Building OpenSSL as Dynamically Linked Libraries
The process for building the libraries as dynamically linked libraries is a little more complicated and depends on the platform. Linux administrators can use the provided make target linux-shared:
The installation step does not understand the shared library filenames, so to install them we need to install them directly with something like:
Since install is also responsible for setting up the certificate directories and other supporting files, we might want to build the static libraries first, install them and the supporting files, then build the shared libraries and install them as a second step:
Other platforms can try one of the configuration scripts kept in the shlib subdirectory. Currently scripts exist for IRIX, Solaris and Windows. Experienced administrators can also try feeding parameters to the compiler and linker with the -D, -l, -L, -f and -K config script options.
Specifying the Platform and Compiler Explicitly
OpenSSL also comes with an alternative configuration script Configure that allows us to specify the target platform and compiler explicitly, rather than have the config script try to work it out itself. Running Configure on its own will produce a syntax usage line and an alarmingly long list of possible target platforms and variations:
The possible options that can be given to Configure are identical to the config options above with the sole exception of the final os/compiler option, which is obligatory and picked from the list above. For example, to build a debug version of OpenSSL on Linux we could use:
This should only be necessary if the config script guesses wrongly or we need to add our own platform to the list if none of the existing ones work.
Building OpenSSL with the RSAREF toolkit
Apache servers that are to run within the US need to build OpenSSL with the RSAREF library in order to comply with patents held by RSA, at least until they expire. To do this we unpack the RSAREF source code as outlined above and execute:
Makefiles exist for UNIX, DOS (Windows) and Macintosh platforms; we use whichever is the appropriate makefile for the server platform. To build OpenSSL with the RSAREF library, we copy the RSAREF library to the OpenSSL root directory and give the rsaref option to the config script:
The RSAREF library is not actively maintained and is now quite old. Unfortunately, it is a necessary evil for using SSL with Apache in the US. Administrators compiling onto more obscure or modern platforms, especially 64 bit architectures, may run into problems. In these cases consult the mod_ssl installation documentation which covers a few of these issues.
Building and Installing mod_ssl
Once the OpenSSL libraries - and optionally the RSAREF library - have been built, we can build mod_ssl. In order to function, mod_ssl needs to patch the Apache source code to extend the Apache API, so we must use the configuration script supplied with mod_ssl rather than the one supplied with Apache. Handily, mod_ssl knows how to drive Apache's configuration script and will pass APACI options to it if we specify them to mod_ssl's configuration script.
The one-step way to build Apache and mod_ssl is to give mod_ssl's configuration script something like the following:
This creates a statically linked Apache with mod_ssl included into the binary. As well as passing the --enable-module to Apache's configuration script, this also invisibly passed --enable-rule=EAPI to activate the patches made to Apache's source code.
Here we've assumed that we originally unpacked Apache and OpenSSL into directories under /usr/local/src and have already been into the OpenSSL directory and built the libraries there. Of course, in reality the source code for the different packages can go anywhere so long as we tell mod_ssl's configure script where to find them.
We can supply any APACI options to this configuration script, and mod_ssl will pass them to Apache's own configuration script after it has patched the Apache source code. For example, to specify Apache's install directory and target name and build most modules with all built modules made into dynamically loadable modules (including mod_ssl), we could put:
Here --prefix, --target, --enable-module and --enable-shared options are all passed as options to Apache's configuration script.
Retaining Use of Apache's configure script with mod_ssl
If mod_ssl is the only module that needs to be configured externally, it is easy to use the configure script supplied by mod_ssl and use it to pass APACI options to the Apache configure script. However, if we have several modules needing special treatment things get more complex - we cannot drive Apache's configuration from all of them at once.
As an alternative we can use mod_ssl's configure script to make the EAPI patches to Apache only, then use Apache's configure script to set up Apache as usual, or go on to another module and use its configure script. Once Apache is built with EAPI included we can return to mod_ssl's source code and build it as a loadable module by telling it to use apxs. The steps to do this are:
1. Build OpenSSL (and possibly RSAREF)
We first build the OpenSSL libraries, without installing them. In this case we're building for a site outside the US, so we have to disable the IDEA cipher:
Alternatively, US sites would use RSAREF (built previously):
2. Patch Apache's source code
Next we need to patch the extended API that mod_ssl needs into Apache, but without running Apache's configuration script.
3. Do other third-party module preparations
We can now go to other modules with non-trivial installation procedures and carry out any necessary preparations. Note that some modules (mod_php being one) need to be built after the mod_ssl patches have been applied to work, and need -DEAPI added to their compiler flags at the configuration stage. For this reason it is always a better idea to deal with the EAPI patches before handling other third-party modules.
Some modules, like mod_ssl, can also drive Apache's configuration from their own configuration scripts, so we could do the rest of the configuration here if we only had one other module to configure. Otherwise, we go on to the next step.
4. Configure and build EAPI-patched Apache
Because we're going to build mod_ssl later we must enable mod_so, either explicitly with --enable-module=so or implicitly by using --enable-shared. In this case, we're going to compile all modules as dynamic modules. We're also going to test this server before we use it in anger, so we give it a different installation root and target name to distinguish it from the existing installation.
In order to enable the EAPI interface required by mod_ssl, we need to enable the EAPI rule which was added to Apache's configuration options when we patched the source in stage 2.
If the source is patched correctly and the EAPI rule has been activated, we should see -DEAPI included in the list of flags passed to the compiler during the build process.
5. Build and install mod_ssl with apxs
Now we can build mod_ssl using apxs. This works because we previously built Apache with the EAPI patches in place; we don't need to apply them again. The --with-rsa option is only necessary if we're building with the RSAREF library.
Strangely, although the makefile generated by configure uses apxs to install libssl.so (the filename under which mod_ssl is created), it does not add the necessary lines to the configuration file. We can fix this easily with:
This actually does the installation too, so the make install is redundant. If we already have the directives in httpd.conf for loading mod_ssl (from a previous installation, perhaps), make install is just fine, as well as being shorter to type.
Once mod_ssl is installed and running in Apache, we can check to see if it is present by generating an information page with mod_info. If present mod_ssl will announce itself on the Apache version line.
Basic SSL Configuration
In order to have Apache respond to SSL connections we also need make sure it is listening to port 443, the default port for SSL. By default Apache listens to all ports and all interfaces, but if we're being more restrained we'll need to put something like:
To actually enable SSL we need to tell Apache how and when to use it, by entering SSL directives into its configuration. mod_ssl provides a lot of directives, but the ones of crucial importance are:
If we're loading SSL dynamically, these directives must be located after the LoadModule/AddModule directives for Apache to understand them. If we put the directives at the server level (that is, outside a virtual host container), then the entire server will be SSL enabled and ordinary HTTP connections will no longer work on any port. However, we can also put all three directives in a IP-based virtual host to enable SSL for one host only; in this case a host dedicated to port 443, the SSL port:
In order for Apache to support SSL this is all we need in the configuration; Apache will accept both unencrypted and encrypted connections for any page on the server. This is not what we ultimately want, but we can enforce use of SSL in specific areas, as we will see later. For a proper SSL server we would probably also want to define SSLRandomFile, as described later. mod_ssl also supports a range of other SSL directives which we can use to customize SSL in various ways. For example, a simple and obvious thing to do is enforce the use of SSL in a specific location, which we can do with:
This rejects ordinary HTTP connections that try to access resources in the secure section of the site. We can also automatically redirect clients to use SSL, as we will see later.
©1998 Wrox Press Limited, US and UK.
blog comments powered by Disqus