> Apache Security: Chapter 4. SSL and TLS


4 SSL and TLS

Like many other Internet protocols created before it, HTTP was designed under the assumption that data transmission would be secure. This is a perfectly valid assumption; it makes sense to put a separate communication layer in place to worry about issues such as confidentiality and data integrity. Unfortunately, a solution to secure data transmission was not offered at the same time as HTTP. It arrived years later, initially as a proprietary protocol.

By today’s standards, the Internet was not a very secure place in the early days. It took us many years to put mechanisms in place for secure communication. Even today, millions of users are using insecure, plaintext communication protocols to transmit valuable, private, and confidential information.

Not taking steps to secure HTTP communication can lead to the following weaknesses:

Since these are serious problems, the only cases where additional security measures are not required are with a web site where all areas are open to the public or with a web site that does not contain any information worth protecting. Some cases require protection:

To secure HTTP, the Secure Sockets Layer (SSL) protocol is used. This chapter begins by covering cryptography from a practical point of view. You only need to understand the basic principles. We do not need to go into mathematical details and discuss differences between algorithms for most real-life requirements. After documenting various types of encryption, this chapter will introduce SSL and describe how to use the OpenSSL libraries and the mod_ssl Apache module. Adding SSL capabilities to the web server is easy, but getting the certificate infrastructure right requires more work. The end of the chapter discusses the impact of SSL on performance and explains how to determine if SSL will represent a bottleneck.

Cryptography is a mathematical science used to secure storage and transmission of data. The process involves two steps: encryption transforms information into unreadable data, and decryption converts unreadable data back into a readable form. When cryptography was first used, confidentiality was achieved by keeping the transformation algorithms secret, but people figured out those algorithms. Today, algorithms are kept public and well documented, but they require a secret piece of information; a key, to hide and reveal data. Here are three terms you need to know:

Cryptography aims to achieve four goals:

The point of cryptography is to make it easy to hide (encrypt) information yet make it difficult and time consuming for anyone without the decryption key to decrypt encrypted information.

No one technique or algorithm can be used to achieve all the goals listed above. Instead, several concepts and techniques have to be combined to achieve the full effect. There are four important concepts to cover:

Do not be intimidated by the large number of encryption methods in use. Mathematicians are always looking for better and faster methods, making the number constantly grow. You certainly do not need to be aware of the inner details of these algorithms to use them. You do, however, have to be aware of legal issues that accompany them:

Symmetric encryption (also known as private key encryption or secret key encryption) is a fast encryption method that uses a single key to encrypt and decrypt data. On its own it offers data confidentiality (and to some extent, authentication) provided the parties involved in communication safely exchange the secret key in advance. An example of the use of symmetric encryption is shown in Figure 4-1.

Here are six commonly used symmetric encryption algorithms:

A best encryption algorithm does not exist. All algorithms from the list have been thoroughly researched and are considered to be technically secure. Other issues that need to be taken into consideration are the interoperability, key length, speed, and legal issues. The key-length argument renders DES and 3DES (for new implementations) obsolete. It is widely believed that the minimum secure key length for symmetric encryption today is 80 bits. Encryption of at least 128 bits is recommended for all new applications. Having been adopted as a standard by the U.S. government, AES is the closest to being the algorithm of choice.

Symmetric encryption has inherent problems that show up as soon as the number of parties involved is increased to more than two:

In spite of these problems, a major advantage to symmetric encryption is its speed, which makes it the only choice when large amounts of data need to be encrypted (for storage or transmission).

Asymmetric encryption (also known as public key encryption) tries to solve the problems found in symmetric encryption algorithms. Instead of one secret key, public-key encryption requires two keys, one of which is called a public key and the other a private key. The two keys, the encryption algorithm, and the decryption algorithm are mathematically related: information encrypted with a public key can be decrypted (using the same algorithm) only if the private key is known. The reverse also holds: data encrypted using the private key can be decrypted only with the public key.

The key names give away their intended usage. The public key can be distributed freely to everyone. Whoever is in the possession of the public key can use the key and the corresponding encryption algorithm to encrypt a message that can only be decrypted by the owner of the private key that corresponds to the public key. This is illustrated in Figure 4-2, in which Bob encrypts a message using Alice’s public key and sends the result to Alice. (The names Alice and Bob are commonly used in explanations related to cryptography. For more information, read the corresponding Wikipedia entry: http://en.wikipedia.org/wiki/Alice_and_Bob.) Alice then decrypts the message using her private key.

There exists another use for the private key. When information is encrypted with a private key, anyone (anyone with access to the public key, that is) can decrypt it with the public key. This is not as useless as it may seem at first glance. Because no key other than the public key can unlock the message, the recipient is certain the encrypted message was sent from the private key owner. This technique of encrypting with a private key, illustrated in Figure 4-3, is known as a digital signature because it is the equivalent of a real signature in everyday life.

Here are three asymmetric encryption methods in use today:

Public-key encryption does have a significant drawback: it is much slower than symmetric encryption, so even today’s computers cannot use this type of encryption alone and achieve acceptably fast communication speeds. Because of this, it is mostly used to digitally sign small amounts of data.

Public-key cryptography seems to solve the scalability problem we mentioned earlier. If every person has a two-key pair, anyone on the Internet will be able to communicate securely with anyone else. One problem remains, which is the problem of key distribution. How do you find someone’s public key? And how do you know the key you have really belongs to them? I will address these issues in a moment.

One-way encryption is the process performed by certain mathematical functions that generate “random“ output when given some data on input. These functions are called hash functions or message digest functions. The word hash is used to refer to the output produced by a hash function. Hash functions have the following attributes:

Hash functions have two common uses. One is to store some information without storing the data itself. For example, hash functions are frequently used for safe password storage. Instead of storing passwords in plaintext—where they can be accessed by whoever has access to the system—it is better to store only password hashes. Since the same password always produces the same hash, the system can still perform its main function—password verification—but the risk of user password database compromise is gone.

The other common use is to quickly verify data integrity. (You may have done this, as shown in Chapter 2, when you verified the integrity of the downloaded Apache distribution.) If a hash output is provided for a file, the recipient can calculate the hash himself and compare the result with the provided value. A difference in values means the file was changed or corrupted.

Hash functions are free of usage, export, or patent restrictions, and that led to their popularity and unrestricted usage growth.

Here are three popular hash functions:

Today, it is believed a hash function should produce output at least 160 bits long. Therefore, the SHA-1 algorithm is recommended as the hash algorithm of choice for new applications.

Encryption algorithms alone are insufficient to verify someone’s identity in the digital world. This is especially true if you need to verify the identity of someone you have never met. Public key infrastructure (PKI) is a concept that allows identities to be bound to certificates and provides a way to verify that certificates are genuine. It uses public-key encryption, digital certificates, and certificate authorities to do this.

A certificate authority (CA) is an entity that signs certificates. If you trust a CA then you will probably trust the certificate it signed, too. Anyone can be a CA, and you can even sign your own certificate (we will do exactly that later). There are three kinds of certificates:

I have mentioned that digital certificates can be used to sign other digital certificates. This is what CAs do. They have one very important certificate, called the root certificate, which they use to sign other people’s certificates. CAs sign their own root certificates and certificates from trusted authorities are accepted as valid. Such certificates are distributed with software that uses them (e.g., web browsers). A partial list of authorities accepted by my browser, Mozilla 1.7, is given in Figure 4-4. (I added the Apache Security CA, whose creation is shown later in this chapter, after importing into the browser the root certificate for it.)

Identity validation through certificate authorities represents a well-organized identity verification model. A small number of trusted certificate authorities have the last word in saying who is legitimate. Another approach to identity verification is to avoid the use of authorities, and base verification on a distributed, peer-to-peer operation where users’ identities are confirmed by other users. This is how a web of trust is formed. It is a method commonly used among security-conscious computer users today.

This is how the web of trust works:

A web of trust example is given in Figure 4-5.

The web of trust is difficult but not impossible to achieve. As long as every person in the chain ensures the next person is who he claims he is, and as long as every member remains vigilant, there is a good chance of success. However, misuse is possible and likely. That is why the user of the web of trust must decide what trust means in each case. Having one path from one person to another is good, but having multiple independent paths is better.

The web of trust concept is well suited for use by individuals and by programs like PGP (Pretty Good Privacy) or GnuPG. You can find out more about the web of trust concept in the GnuPG documentation:

Now that we have the basic elements covered, let’s examine how these pieces fall into place:

If you want to continue studying cryptography, read Applied Cryptography by Bruce Schneier (Wiley), considered to be a major work in the field.

Around 1995, Netscape Navigator was dominating the browser market with around a 70 percent share. When Netscape created SSL in 1994, it became an instant standard. Microsoft tried to compete, releasing a technology equivalent, Private Communication Technology (PCT), but it had no chance due to Internet Explorer’s small market share. It was not until 1996, when Microsoft released Internet Explorer 3, that Netscape’s position was challenged.

The first commercial SSL implementation to be released was SSLv2, which appeared in 1994. Version 3 followed in 1995. Netscape also released the SSLv3 reference implementation and worked with the Internet Engineering Task Force (IETF) to turn SSL into a standard. The official name of the standard is Transport Layer Security (TLS), and it is defined in RFC 2246 (http://www.ietf.org/rfc/rfc2246.txt). TLS is currently at version 1.0, but that version is practically the same as SSLv3.1. In spite of the official standard having a different name everyone continues to call the technology SSL, so that is what I will do, too.

SSL lives above TCP and below HTTP in the Open Systems Interconnection (OSI) model, as illustrated in Figure 4-6. Though initially implemented to secure HTTP, SSL now secures many connection-oriented protocols. Examples are SMTP, POP, IMAP, and FTP.

In the early days, web hosting required exclusive use of one IP address per hosted web site. But soon hosting providers started running out of IP addresses as the number of web sites grew exponentially. To allow many web sites to share the same IP address, a concept called name-based virtual hosting was devised. When it is deployed, the name of the target web site is transported in the Host request header. However, SSL still requires one exclusive IP address per web site. Looking at the OSI model, it is easy to see why. The HTTP request is wrapped inside the encrypted channel, which can be decrypted with the correct server key. But without looking into the request, the web server cannot access the Host header and, therefore, cannot use that information to choose the key. The only information available to the server is the incoming IP address.

Because only a small number of web sites require SSL, this has not been a major problem. Still, a way of upgrading from non-SSL to SSL communication has been designed (see RFC2817 at http://www.ietf.org/rfc/rfc2817.txt).

The answer is yes and no. From a technical point of view, transmission can be made secure provided proper encryption algorithms are used together with key lengths of sufficiently large sizes. For example, bulk encryption using the RC4 algorithm and a key length of 128 bits, with an initial handshake using 1024-bit RSA, is considered to be reasonably secure for the moment. But SSL can be a complex protocol to configure and use. Some level of knowledge is required to deploy a reasonably safe installation. (See Eric Murray’s study, “SSL Security Survey,” at http://www.meer.net/~ericm/papers/ssl_servers.html.) Learn the cryptography and SSL basics and read the complete product documentation related to SSL before you make your first configuration attempt.

Looking at the issue of SSL security from the point of view of a client who wishes to participate in an SSL session, there is a problem known as the man-in-the-middle (MITM) attack. MITM attacks refer to the situation where an attacker can intercept communication between two parties. Each party believes that it is talking to the other party but, in fact, everything goes through the attacker first. MITM attacks can be performed with little difficulty provided the attacker is on the same local network as the victim. (It is far more difficult for an attacker not on the same local network to execute an MITM attack.) There is a collection of tools that help automate such attacks; it’s called dsniff (http://www.monkey.org/~dugsong/dsniff/).

When a client application is preparing to establish communication with an SSL server it starts with a domain name and resolves it to the numerical IP address first. This is the weakest point of the process. Using dsniff, it is trivial to intercept domain name resolution requests and send a fake IP address (one the attacker controls) in response. Believing the given IP address is correct, the client will send all traffic for that domain name to the attacker. The attacker will talk to the real server on the victim’s behalf. This is all the work required to intercept nonencrypted protocols. But since the SSL protocol specifies server authentication in the handshake phase, the attacker needs to put in more effort when that protocol is used. The attacker cannot successfully pose as the target server since he is not in the possession of its private key. He can attempt to send some other certificate to the client, one for which he has the private key. There are four things the attacker can do:

The only solution to MITM attacks is to enable both server and client authentication. In this case, the attacker will not be able to prove himself to the server as being the genuine client, and as a result the handshake phase of the session fails. Please note: the MITM problem presented here is not a weakness of SSL but rather a weakness of the domain name resolution system that is currently in widespread use. An extension to DNS, Domain Name System Security Extensions (DNSSEC), is being developed to allow for secure DNS resolution and avoidance of the MITM problem. More information is available at http://www.dnssec.net.

Some nontechnical issues related to how SSL is used make the end result not as secure as it could be:

It is not an end-to-end solution

SSL creates a secure channel for transmission, but does not care what happens to data before it reaches the channel and after it is decrypted. It secures transmission but does not secure storage. Many people seem to forget this, or do not care. I have seen many web sites that have SSL installed on the web server level, only to send credit card details to an email address using some form-to-email script. Unattended software handling sensitive data must always use public-key cryptography to store data securely.

Users lack understanding of browser warnings

You will find that many end users do not care about security and do not understand the implications of their actions. I have observed how people dismiss browser warnings that come up because certificates are self-signed, invalid, or expired. This makes MITM attacks easy to execute. If an attacker manages to redirect the user to his web site instead of the original, the user will blindly ignore the warning and enter the trap.

The solution to this is to change the way browsers behave, and make them refuse connections to sites with invalid certificates. Unfortunately, this will not happen soon. Until then, the only thing we can do is to try to educate our users.

User interfaces are inadequate

Today’s Internet browsers are educating users about SSL and security. You typically get a small yellow icon in a corner somewhere when you connect to a secure web site. That is not enough. User interfaces should be changed to constantly remind the user the communication is secure, in an effort to raise awareness. A good way to do this would be to have a bold red line surrounding the browser window.

Browsers have inadequate functionality

In fact, browsers do not pay much attention to security at all. Imagine an attacker who copies the design of a web site, purchases a valid certificate from a well-known CA in the name of the target web site (it has been done), and installs the web site at a server somewhere. If he manages to intercept users’ domain name resolution traffic (by breaking into an ISP’s DNS server or by performing a MITM attack, for example), whenever someone requests the target web site he will send them to the phony version instead. Thinking she is at the correct site, the user will attempt to authenticate to the web site and thus disclose her username and password to the attacker. The correct thing for a browser to do is to compare the copy of the certificate it stored upon first visit to the web site requested by the user with the copy offered to it now. Any changes could result in immediate termination of the session.

Attacks do not have to be technology oriented. Without having to perform traffic interception, attackers can register a domain name that differs from an original domain name in a character or two, put a copy of the original site there and wait for someone to mistype the original URL. Sooner or later someone will come in. An even more successful approach is to spam millions of users with messages that appear to come from the original site and put links to the phony site inside the email messages. This type of attack is called phishing and it’s discussed in more detail in Chapter 10.

OpenSSL is the open source implementation (toolkit) of many cryptographic protocols. Almost all open source and many commercial packages rely on it for their cryptographic needs. OpenSSL is licensed under a BSD-like license, which allows commercial exploitation of the source code. You probably have OpenSSL installed on your computer if you are running a Unix system. If you are not running a Unix system or you are but you do not have OpenSSL installed, download the latest version from the web site (http://www.openssl.org). The installation is easy:

$ ./config
$ make
# make install

Do not download and install a new copy of OpenSSL if one is already installed on your system. You will find that other applications rely on the pre-installed version of OpenSSL. Adding another version on top will only lead to confusion and possible incompatibilities.

OpenSSL is a set of libraries, but it also includes a tool, openssl, which makes most of the functionality available from the command line. To avoid clutter, only one binary is used as a façade for many commands supported by OpenSSL. The first parameter to the binary is the name of the command to be executed.

The standard port for HTTP communication over SSL is port 443. To connect to a remote web server using SSL, type something like the following, where this example shows connecting to Thawte’s web site:

$ openssl s_client -host www.thawte.com -port 443

As soon as the connection with the server is established, the command window is filled with a lot of information about the connection. Some of the information displayed on the screen is quite useful. Near the top is information about the certificate chain, as shown below. A certificate chain is a collection of certificates that make a path from the first point of contact (the web site www.thawte.com, in the example above) to a trusted root certificate. In this case, the chain references two certificates, as shown in the following output. For each certificate, the first line shows the information about the certificate itself, and the second line shows information about the certificate it was signed with. Certificate information is displayed in condensed format: the forward slash is a separator, and the uppercase letters stand for certificate fields (e.g., C for country, ST for state). You will get familiar with these fields later when you start creating your own certificates. Here is the certificate chain:

Certificate chain
 0 s:/C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting (Pty)
   i:/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
 1 s:/C=ZA/O=Thawte Consulting (Pty) Ltd./CN=Thawte SGC CA
   i:/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority

You may be wondering what VeriSign is doing signing a Thawte certificate; Thawte is a CA, after all. VeriSign recently bought Thawte; though they remain as two different business entities, they are sharing a common root certificate.

The details of the negotiated connection with the remote server are near the end of the output:

New, TLSv1/SSLv3, Cipher is EDH-RSA-DES-CBC3-SHA
Server public key is 1024 bit
    Protocol  : TLSv1
    Cipher    : EDH-RSA-DES-CBC3-SHA
    Session-ID: 6E9DBBBA986C501A88F0B7ADAFEC6529291C739EB4CC2114EE62036D9B
    Master-Key: 0D90A33260738C7B8CBCC1F2A5DC3BE79D9D4E2FC7C649E5A541594F37
    Key-Arg   : None
    Krb5 Principal: None
    Start Time: 1090586684
    Timeout   : 300 (sec)
    Verify return code: 20 (unable to get local issuer certificate)

To understand these values, you would have to have a deep understanding of the SSL protocol. For our level of involvement, it is enough to recognize the protocol being used, which can be seen on the fourth line above. In our case, the TLSv1 protocol is used. However, it is worrisome that the last line reports an error in certificate verification. The problem arises because openssl does not have enough information to verify the authenticity of the last certificate in the chain. The last certificate in the chain is a root certificate that belongs to VeriSign. In most cases, you would have to download the root certificate from a trusted location. Since VeriSign is a well-known CA, however, its root certificate is distributed with OpenSSL. You just need to tell the tool where to look for it.

The certificate is a part of the OpenSSL supported files. The exact location depends on the operating system. On Red Hat systems, it is in /usr/share/ssl. On Debian, it is in /usr/local/ssl. To find the location of the OpenSSL configuration and shared files, type:

$ openssl ca
Using configuration from /usr/share/ssl/openssl.cnf

The first line of the command output will tell you where the certificates are. Bundled certificates are provided in a single file that resides in the /certs subfolder of the folder that contains openssl.cnf in a file called ca-bundle.crt. Armed with the path to the certificate bundle, you can attempt to talk SSL to the web server again, supplying the path to the openssl binary in the CAfile parameter:

$ openssl s_client -host www.thawte.com -port 443 \
> -CAfile /usr/share/ssl/certs/ca-bundle.crt 
New, TLSv1/SSLv3, Cipher is EDH-RSA-DES-CBC3-SHA
Server public key is 1024 bit
    Protocol  : TLSv1
    Cipher    : EDH-RSA-DES-CBC3-SHA
    Session-ID: F2C04CD240C5CA0DF03C8D15555DB1891B71DA6688FA78A920C808362C
    Master-Key: 5F662B2E538E628BDE2E9E0F324CE88D57CCB93FCFCCFB52761AA0728B
    Key-Arg   : None
    Krb5 Principal: None
    Start Time: 1090588540
    Timeout   : 300 (sec)
    Verify return code: 0 (ok)

This time, no verification errors occur. You have established a cryptographically secure communication channel with a web server whose identity has been confirmed. At this point, you can type an HTTP request just as you would if connecting via a Telnet command:


HTTP/1.1 200 OK
Date: Fri, 23 Jul 2004 11:36:49 GMT
Server: Apache
Connection: close
Content-Type: text/html

If you are using Apache from the 2.x branch, the support for SSL is included with the distribution. For Apache 1, it is a separate download of one of two implementations. You can use mod_ssl (http://www.modssl.org) or Apache-SSL (http://www.apache-ssl.org). Neither of these two web sites discusses why you would choose one instead of the other. Historically, mod_ssl was created out of Apache-SSL, but that was a long time ago and the two implementations have little in common (in terms of source code) now. The mod_ssl implementation made it into Apache 2 and is more widely used, so it makes sense to make it our choice here.

Neither of these implementations is a simple Apache module. The Apache 1 programming interface does not provide enough functionality to support SSL, so mod_ssl and Apache-SSL rely on modifying the Apache source code during installation.

Once SSL is enabled, the server will not start unless a private key and a certificate are properly configured. Private keys are commonly protected with passwords (also known as passphrases) to add additional protection for the keys. But when generating a private key for a web server, you are likely to leave it unprotected because a password-protected private key would require the password to be manually typed every time the web server is started or reconfigured. This sort of protection is not realistic. It is possible to tell Apache to ask an external program for a passphrase (using the SSLPassPhraseDialog directive), and some people use this option to keep the private keys encrypted and avoid manual interventions. This approach is probably slightly more secure but not much. To be used to unlock the private key, the passphrase must be available in cleartext. Someone who is after the private key is likely to be determined enough to continue to look for the passphrase.

The following generates a nonprotected, 1,024-bit server private key using the RSA algorithm (as instructed by the genrsa command) and stores it in server.key:

# cd /usr/local/apache/conf
# mkdir ssl
# cd ssl
# openssl genrsa -out server.key 1024
Generating RSA private key, 1024 bit long modulus
e is 65537 (0x10001)

Only the private key was generated:

# cat server.key

But the public key can be extracted from the private key:

# openssl rsa -in server.key -pubout
writing RSA key
-----END PUBLIC KEY-----

The next step is to create a certificate-signing request (CSR). This is a formal request asking a certificate authority to sign a certificate, and it contains the public key of the entity requesting the certificate and information about the entity. The information becomes part of the certificate.

CSR creation is an interactive process, which takes the private server key as input. Read the instructions given by the openssl tool carefully: if you want a field to be empty, you must enter a single dot (.) and not just press Return because doing so would populate the field with the default value.

# openssl req -new -key server.key -out server.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
Country Name (2 letter code) [GB]:
State or Province Name (full name) [Berkshire]:.
Locality Name (eg, city) [Newbury]:London
Organization Name (eg, company) [My Company Ltd]:Apache Security
Organizational Unit Name (eg, section) [  ]:.
Common Name (eg, your name or your server's hostname) [  ]:
Email Address [  ]:webmaster@apachesecurity.net
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password [  ]:
An optional company name [  ]:

After a CSR is generated, you use it to sign your own certificate and/or send it to a public CA and ask him to sign the certificate. Both approaches are described in the sections that follow.

For testing purposes, you should sign your own certificate; it may be days before the CA completes the certificate generation process. You have the files you need: the CSR and the private key. The x509 command with the -req switch creates a self-signed certificate. Other switches on the following command line instruct openssl to create a certificate valid for 365 days using the private key specified in server.key:

# openssl x509 -req -days 365 -in server.csr \
> -signkey server.key -out server.crt
Signature ok
Getting Private key

Use the x509 command to examine the contents of the certificate you have created:

# openssl x509 -text -in server.crt>
        Version: 1 (0x0)
        Serial Number: 0 (0x0)
        Signature Algorithm: md5WithRSAEncryption
        Issuer: C=GB, L=London, O=Apache Security,
            Not Before: Jul 26 13:36:34 2004 GMT
            Not After : Jul 26 13:36:34 2005 GMT
        Subject: C=GB, L=London, O=Apache Security,
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public Key: (1024 bit)
                Modulus (1024 bit):
                Exponent: 65537 (0x10001)
    Signature Algorithm: md5WithRSAEncryption


A minimal SSL configuration consists of three directives in the Apache configuration file:

# Enable SSL
SSLEngine On
# Path to the server certificate
SSLCertificateFile /usr/local/apache/conf/ssl/server.crt
# Path to the server private key
SSLCertificateKeyFile /usr/local/apache/conf/ssl/server.key

You may wish to make the default configuration slightly more secure by adjusting the allowed protocols. SSLv2 is known to be flawed. (For details, see http://www.meer.net/~ericm/papers/ssl_servers.html#1.2.) Unless your installation has to support browsers that do not speak SSLv3 (which is unlikely), there is no reason to allow SSLv2. The following disallows it:

# Allow SSLv3 and TLSv1 but not SSLv2
SSLProtocol All -SSLv2

One other useful configuration option is the following, which disallows the situation where, though the server supports high-grade encryption, the client negotiates a low-grade (e.g., 40-bit) protocol suite, which offers little protection:

# Disallow ciphers that are weak (obsolete or
# known to be flawed in some way). The use of
# an exclamation mark in front of a cipher code
# tells Apache never to use it. EXP refers to 40-bit
# and 56-bit ciphers, NULL ciphers offer no encryption.
# ADH refers to Anonymous Diffie-Hellman key exchange
# which effectively disables server certificate validation,
# and LOW refers to other low strength ciphers.

After the certificate is installed, you can test it by opening the web site in your browser. You should get no warnings for a certificate issued by a well-known CA. You will get at least one warning if you are using a self-signed certificate for testing. In the Appendix A, I introduce SSLDigger, a tool designed to evaluate the strength of a site’s SSL protection.

If you are running a web site that needs to be available only over SSL, then avoid a chance of making the same content available through a non-SSL channel and create a virtual host that points to an empty folder. Use a RedirectPermanent directive to redirect users to the correct (secure) location:

    ServerName www.apachesecurity.net
    DirectoryRoot /var/www/empty
    RedirectPermanent / https://www.apachesecurity.net/

If the site contains SSL and non-SSL content, separating the content into two virtual hosts and separate directories decreases the chance of providing sensitive information without SSL. If the content must be put under the same directory tree, consider creating a special folder where the secure content will go. Then tell Apache to allow access to that folder only when SSL is used:

<Directory /var/www/htdocs/secure>
    # SSL must be used to access this location
    # Do not allow SSLRequireSSL to be overriden
    # by some other authorization directive
    SSLOptions +StrictRequire

A slightly more user-friendly approach to ensuring content is served over SSL is to use a few mod_rewrite rules to detect access to non-SSL content and redirect the user to the correct location, as demonstrated in Apache Cookbook by Ken Coar and Rich Bowen (O’Reilly) in Recipe 5.15 and online at http://rewrite.drbacchus.com/rewritewiki/SSL:

RewriteEngine On
RewriteCond %{HTTPS} !=on
RewriteRule ^/secure(.*) https://%{SERVER_NAME}/secure$1 [R,L]

If neither of these two choices is possible (separating the content into two virtual hosts and separate directories or placing the content in a special folder that can only be accessed using SSL), the burden of controlling SSL access will be on the shoulders of the programmers. You should check (during final site testing) that the secure content available, for example at https://www.example.com/my-sensitive-data/, cannot be accessed using a nonsecure URL, such as http://www.example.com/my-sensitive-data/.

If you want to become a CA, everything you need is included in the OpenSSL toolkit. This step is only feasible in a few high-end cases in which security is critical and you need to be in full control of the process. T he utilities provided with OpenSSL will perform the required cryptographic computations and automatically track issued certificates using a simple, file-based database. To be honest, the process can be cryptic (no pun intended) and frustrating at times, but that is because experts tend to make applications for use by other experts. Besides, polishing applications is not nearly as challenging as inventing something new. Efforts are under way to provide more user-friendly and complete solutions. Two popular projects are:

After choosing a machine to run the CA operations on, remove the existing OpenSSL installation. Unlike what I suggested for web servers, for CA operation it is better to download the latest version of the OpenSSL toolkit from the main distribution site. The installation process is simple. You do not want the toolkit to integrate into the operating system (you may need to move it around later), so specify a new location for it. The following will configure, compile, and install the toolkit to /opt/openssl:

$ ./configure --prefix=/opt/openssl
$ make
$ make test
# make install

Included with the OpenSSL distribution is a convenience tool CA.pl (called CA.sh or CA in some distributions), which simplifies CA operations. The CA.pl tool was designed to perform a set of common operations with little variation as an alternative to knowing the OpenSSL commands by heart. This is particularly evident with the usage of default filenames, designed to be able to transition seamlessly from one step (e.g., generate a CSR) to another (e.g., sign the CSR).

Before the CA keys are generated, there are three things you may want to change:

The file CA.pl was not designed to use the full path to the openssl binary. Consequently, if two OpenSSL installations are on the machine, it will probably call the one installed by the system. This needs to be changed unless you have removed the previous installation as I suggested before. The five lines are near the top of the CA.pl file:

$REQ="openssl req $SSLEAY_CONFIG";
$CA="openssl ca $SSLEAY_CONFIG";
$VERIFY="openssl verify";
$X509="openssl x509";
$PKCS12="openssl pkcs12";

The five lines need to be changed to the following:

$VERIFY="$OPENSSL verify";
$X509="$OPENSSL x509";
$PKCS12="$OPENSSL pkcs12";

You are ready to create a CA:

# cd /opt/openssl
# ./ssl/misc/CA.pl -newca

In the first stage of CA.pl execution to create a CA, you will be asked to provide the CA certificate name (this refers to any existing CA certificates you might have, so leave it blank by pressing return) and a passphrase (choose a long password). In the second stage, you will be required to enter the same fields as you did for a standard web server certificate (e.g., country, state, city). After the script ends, the following files and directories appear in /opt/openssl/demoCA:

All CA-related data is stored in the specified files and directories.

To use SSL, each web server must be supplied with a server certificate. Before issuing a first certificate, you may need to adjust the default policy, specified in the openssl.cnf file. The policy controls which of the fields in the CA certificate must match fields in the issued certificates. The default policy requires the fields countryName, stateOrProvinceName, and organizationName to match:

[ policy_match ]
countryName = match
stateOrProvinceName = match
organizationName = match
organizationalUnitName = optional
commonName = supplied
emailAddress = optional

Option values have the following meanings:

To create a certificate, assuming you were given a CSR by some other web server administrator in your organization, rename the CSR file to newreq.pem and execute the following command to sign it:

# CA.pl -signreq

That is all there is to it. You will be asked to type in the CA passphrase, and you will be given an opportunity to verify the details are in order. When you type in your passphrase, only asterisks will be shown, helping to keep your passphrase private.

# CA.pl -signreq
Using configuration from /opt/openssl/ssl/openssl.cnf
Enter pass phrase for ./demoCA/private/cakey.pem:******
Check that the request matches the signature
Signature ok
Certificate Details:
        Serial Number: 1 (0x1)
            Not Before: Jul 23 17:25:01 2004 GMT
            Not After : Jul 23 17:25:01 2005 GMT
            countryName               = GB
            localityName              = London
            organizationName          = Apache Security
            commonName                = www.apachesecurity.net
            emailAddress              = webmaster@apachesecurity.net
        X509v3 extensions:
            X509v3 Basic Constraints:
            Netscape Comment:
                OpenSSL Generated Certificate
            X509v3 Subject Key Identifier:
            X509v3 Authority Key Identifier:
                DirName:/C=GB/L=London/O=Apache Security/CN=Apache Security
Certificate is to be certified until Jul 23 17:25:01 2005 GMT (365 days)
Sign the certificate? [y/n]:y
1 out of 1 certificate requests certified, commit? [y/n]y
Write out database with 1 new entries
Data Base Updated
Signed certificate is in newcert.pem

You can also create a private key and a CSR on the spot (which you may do if you are the only person in charge of certificates). When the private key needs a passphrase, use the -newreq switch:

# CA.pl -newreq

When a private key without a passphrase is needed, use the -newreq-nodes switch:

# CA.pl -newreq-nodes

Now you can again use the CA.pl -signreq command to create a certificate.

SSL has a reputation for being slow. This reputation originated in its early days when it was slow compared to the processing power of computers. Things have improved. Unless you are in charge of a very large web installation, I doubt you will experience performance problems with SSL.

Since OpenSSL comes with a benchmark script, we do not have to guess how fast the cryptographic functions SSL requires are. The script will run a series of computing-intensive tests and display the results. Execute the script via the following:

$ openssl speed

The following results were obtained from running the script on a machine with two 2.8 GHz Pentium 4 Xeon processors. The benchmark uses only one processor for its measurements. In real-life situations, both processors will be used; therefore, the processing capacity on a dual server will be twice as large.

The following are the benchmark results of one-way and symmetrical algorithms:

type          16 bytes    64 bytes   256 bytes  1024 bytes  8192 bytes
md2            1841.78k    3965.80k    5464.83k    5947.39k    6223.19k
md4           17326.58k   55490.11k  138188.97k  211403.09k  263528.45k
md5           12795.17k   41788.59k  117776.81k  234883.07k  332759.04k
hmac(md5)      8847.31k   32256.23k  101450.50k  217330.69k  320913.41k
sha1           9529.72k   29872.66k   75258.54k  117943.64k  141710.68k
rmd160        10551.10k   31148.82k   62616.23k  116250.38k  101944.89k
rc4           90858.18k  102016.45k  104585.22k  105199.27k  105250.82k
des cbc       45279.25k   47156.76k   47537.41k   47827.29k   47950.51k
des ede3      17932.17k   18639.27k   18866.43k   18930.35k   18945.37k
rc2 cbc       11813.34k   12087.81k   12000.34k   12156.25k   12113.24k
blowfish cbc  80290.79k   83618.41k   84170.92k   84815.87k   84093.61k
cast cbc      30767.63k   32477.40k   32840.53k   32925.35k   32863.57k
aes-128 cbc   51152.56k   52996.52k   54039.55k   54286.68k   53947.05k
aes-192 cbc   45540.74k   46613.01k   47561.56k   47818.41k   47396.18k
aes-256 cbc   40427.22k   41204.46k   42097.83k   42277.21k   42125.99k

Looking at the first column of results for RC4 (a widely used algorithm today), you can see that it offers a processing speed of 90 MBps, and that is using one processor. This is so fast that it is unlikely to create a processing bottleneck.

The benchmark results obtained for asymmetrical algorithms were:

                  sign    verify    sign/s verify/s
rsa  512 bits   0.0008s   0.0001s   1187.4  13406.5
rsa 1024 bits   0.0041s   0.0002s    242.0   4584.5
rsa 2048 bits   0.0250s   0.0007s     40.0   1362.2
rsa 4096 bits   0.1705s   0.0026s      5.9    379.0
                  sign    verify    sign/s verify/s
dsa  512 bits   0.0007s   0.0009s   1372.6   1134.0
dsa 1024 bits   0.0021s   0.0026s    473.9    389.9
dsa 2048 bits   0.0071s   0.0087s    141.4    114.4

These benchmarks are slightly different. Since asymmetric encryption is not used for data transport but instead is used only during the initial handshake for authentication validation, the results show how many signing operations can be completed in a second. Assuming 1,024-bit RSA keys are used, the processor we benchmarked is capable of completing 242 signing operations per second. Indeed, this seems much slower than our symmetrical encryption tests.

Asymmetrical encryption methods are used at the beginning of each SSL session. The results above show that the processor tested above, when 1,024-bit RSA keys are used, is limited to accepting 242 new connections every second. A large number of sites have nowhere near this number of new connections in a second but this number is not out of the reach of busier e-commerce operations.

Certain technological advances work to our advantage. The HTTP 1.1 Keep-Alive feature allows a client to keep a connection with the server open and reuse it across several requests. If this feature is enabled on the server, it will help reduce the impact of SSL since only one signing operation is required per connection.

But the most important performance enhancement feature is the one built into SSLv3: session caching. When an SSLv3 connection is intially established, a session is created and given a unique session ID. The client can disconnect from the server, but when it comes to the server the next time, the client can use the session ID to reestablish the session without having to perform the expensive cryptographic operation.

The ability to resume sessions has enormous impact on the performance of a web server. Using the openssl tool, you can check that your web server performs as expected:

$ openssl s_client -connect www.thawte.com:443 -state -reconnect

It will connect to the server five times, reusing the session ID created the first time. A line in the output such as this one will confirm the session ID was reused:

Reused, TLSv1/SSLv3, Cipher is EDH-RSA-DES-CBC3-SHA

More information about the performance impact of SSL and various approaches to increasing processing speeds can be found in the following resources: