Installing a Secure Web Server: Introduction

When you enter a secure web session (for instance, for making a purchase on-line), the protocol in the URL changes from http to https. This means that the session is encrypted, using Secure Sockets Layer, SSL. The main browsers have a little icon at the bottom of a page to tell users whether they are in plain or secure mode:

  Netscape Internet Explorer
Plain (unencrypted) http
Secure (encrypted) https
  Lower left corner of page Lower right corner of page

In both cases, you should be able to double-click on the padlock icon to get further information about the security for that particular page. What you will be able to see with a page which has been encrypted is something like the example below, certification that the web server is what it claims to be.

In this section we explore the basic steps in building a web server capable of doing encryption, and what is involved in certification.

Building a Secure Version of Apache

The first step in building a web server which can do SSL is to install openssl (cf. the discussion in UNX02 on Security. On a normal Linux system, it should suffice to do the quick installation procedure. From within the untarred archive, do

./configure
make
make test
make install
This should install the encryption package to /usr/local/ssl.

The next step is to build a version of Apache which can exploit this. A number of commercial vendors sell such products (see the related projects page on the Apache site), but currently some of these at least are not available outside the U.S. mod_ssl is a very good Apache module which can be added in (and combined with mod_perl etc.) to the Apache compilation process.

Let us suppose we have a /usr/install/ directory as detailed in the compilation section, and now create a similar

/usr/install/mod_ssl
The first step of the revised compilation procedure is to apply mod_ssl to the Apache source tree. From within /usr/install, we do
 cd mod_ssl
 ./configure --with-apache=../apache
 cd ..
i.e. we tell it the relative path to the Apache source directory (assuming, as before, that we have made this /usr/install/apache).

The next step could be to include mod_perl or jserv in the compilation process. For this illustration, we'll suppose we're combining mod_ssl with mod_perl. Since we may be compiling several different versions of apache (e.g. for testing purposes), decide on a directory location for the finished article which indicates what version it is, or what combination of modules it incorporates - e.g. /usr/local/apacheperlssl in this case. When you want to run this particular version, just make a symlink /usr/local/httpd to point to it. Having completed the mod_perl step (as in compilation), we now do

 cd apache
 SSL_BASE=/usr/local/ssl
 ./configure --prefix=/usr/local/apacheperlssl --enable-module-ssl \
  --activate-module=src/modules/perl/libperl.a  --enable-module=perl
 make
 make certificate
 make install
That is, we first set a temporary environment variable to be sure that the Apache compilation knows where to find openssl. After compiling Apache, there is an extra step: to make a test certificate. Strictly speaking, this may not be necessary - if you already have a certificate for the server, the 'make certificate' step allows you to specify that one. But if you do make a new certificate, it will be generated by an entirely spurious CA (Certificate Authority), with a clear warning not to use it in a production environment. The test certificate is precisely for test purposes: we can test that we can run the httpd in secure mode, and that our browsers can access it with https.

When you generate a certificate for a web server, you have to supply the kind of information shown in the above image. Since this first one is just for testing purposes, you can put anything, but here are the kinds of questions you have to answer:

Question Example
2 letter country code e.g. GB in the case of the UK
State or province name you could just hit carriage return here
Locality e.g. London
Organisation Name i.e. company name; Middlesex University in the above example
Oranisational Unit the relevant department of the organisation
Common name the domain name of the web server - bicss.mdx.ac.uk in the above
Email address (optional): address of someone to email (e.g. web server adminstrator)

Once successfully compiled, a mod_ssl version of Apache will have an httpd.conf file with a whole extra section concerning SSL. If, for instance, you create a URL path alias in this section of the conf file, and not in the main section, the aliased path will be known only to clients accessing the web server through https. Furthermore, the <Location> directive in the mod_ssl extension allows full regular expression syntax, allowing very powerful specification of per-directory access control. In the following example, where the URL path /secure is mapped to a directory under /usr/local/httpd/, the <Location> directive contains in effect a recursive rule for access. It requires that access to this directory has either been referred to from a particular CGI script, authenticate.pl, or else it comes from a page whose URL matches the pattern starting https://www.foobar.co.uk/secure/ ...- i.e. from another page within that directory:

Alias /secure/ "/usr/local/httpd/htdocs/sslonly/"
<Location /secure/>
    Options Indexes FollowSymLinks
    SSLRequireSSL
    SSLRequire   %{HTTP_REFERER} eq "https://www.foobar.co.uk/authenticate.pl" \
              or %{HTTP_REFERER} =~ m@https://www.foobar.co.uk/secure/@ 
</Location>
So, a user who simply types in a plain http URL, as in http://www.foobar.co.uk/secure/ ... will receive a 'Not found' 404 error page. A user who has engaged in an https session and tries to access the URL directly (without e.g. having been referred on from the authenticate.pl page) will be given a 403 'Forbidden' error page.

Public Key Cryptography

We want to ensure that no-one can eavesdrop on communications between a browser and our secure web server, when sensitive information is being transmitted. The normal way to ensure secrecy is to use some form of key, to encrypt and decrypt the messages. But how can an arbitrary pair of computers on the internet share an encryption key? If you use the same channel of communication to send the key as the messages themselves, and there's a worry that the messages can be intercepted by an eavesdropper, then the key can also be intercepted.

The ingenious solution developed as public key cryptography is for each participant to have a pair of keys. Unlike conventional cryptography, where a single key is used both to scramble and unscramble a message, these keys are asymmetrical: one key is used to encrypt messages to a particular person, the other to decrypt them. The encrypting key is made publicly available, so that anyone who wishes to send messages securely to its owner can use it. Hence it is known as the public key. The other key, which is used for decoding messages, is held only by its owner, and is therefore their private key. The public key cannot be used to decode messages, nor can one figure out from it what the decoding, private key is.

This system can be used for emails and other forms of internet communication. Here's a simplified account of how it works with the world-wide web. When a browser is about to establish a secure http session with a web server, each will have its own pair of keys:

Each party has a public and a private key

If the person using the browser wishes to proceed, there can be an exchange of public keys. The generation and exchange of keys is performed automatically

Exchange of public keys

Now, if the user of the browser requests a page of sensitive information, the web server can use the browser's public key to encypher the text, and send that scrambled information over the internet. At the other end the browser will use its private key to decode the message and present it to the user as ordinary text.

Encryption and decryption over the net

So while the information is in transit across the internet, it is encrypted. Even if a hacker has intercepted the user's public key, this will be of no help to them in decoding the message. And it works in the opposite direction too: the user can securely submit sensitive information like a credit card number back to the web server.

Strictly speaking, this account is a simplification of what happens, but it illustrates the essential security of this kind of asymmetric encryption. Because there is quite an overhead to public-private key encryption/decryption, in fact the browser and server only do this once, at the beginning of an https session, to exchange securely a shared secret for that session. Consequently, there is a delay at the beginning of an https session, while this exchange takes place; after that, the exchange of data is much faster.

You can use openssl to generate a private key for a web server. From within /usr/local/ssl, the command

bin/openssl genrsa -des3 -out myserver.key 1024
will generate a key in a small file called 'myserver.key' (you can call this file whatever you want). You will be asked to supply a password to be supplied whenever this key is used - most obviously, when the web server starts up in secure mode. The password guarantees that no-one can simply steal the key and use it to impersonate your web server, so it is important to memorise it.

Having successfully compiled a secure version of apache, we can run it in plain http mode - which means that if we have accepted the default it is listening for requests on port 80 - and in https mode, listening on both port 80 and port 443. The following sequence of commands tests the apache daemon, first starting it in as a plain http server, with no SSL; then stopping it, then restarting it to accept both http and https requests:

/usr/local/httpd/bin/apachectl start 
/usr/local/httpd/bin/apachectl stop 
/usr/local/httpd/bin/apachectl startssl 
In this latter case, we will need to access the encryption key, and so will be asked for its password. There is a way to remove this request for the pass phrase at startup. For instance, we will need to remove this pass phrase request if there is a cron job which restarts the web server automatically (as discussed previously), or if we wish to ensure that, should the whole server reboot, it will restart the web server in secure mode.

Certificates

Why do we need certificates? Consider this email example: you want to send a message securely to dogberry@foobar.co.uk. So you need his public key to encrypt your message to him. You receive an email purporting to be from dogberry@foobar.co.uk, with that digital key. But how do you know it really is dogberry who sent that message? It's very easy to impersonate an email account. A solution is for dogberry to go through a process whereby his public key is certified as his by a trusted third party. So you will be assured that the email you received with the key is indeed his if it comes with a digital certificate attached from a trusted certifying authority.

In the case of the web it could go like this. In theory, a malicious hacker could undertake a 'Denial of Service' attack on your secure web server and cause it to crash. He then starts up a computer on the net which impersonates your server. This server could then be used e.g. to obtain credit card details from users who thought that they were communicating with the real server. To avoid this, the real web server needs to have a digital certificate, certifying that it really is that server. The hacker who crashed the real server cannot obtain this certificate, and so cannot impersonate this crucial security detail.

In the above illustration, the Certification Authority, or CA, is BT Trustwise, the UK affiliate of Verisign. In order to have your web server certified by a CA, you need to generate a Certificate Signing Request, or .csr file; from this the CA will generate a certificate, .crt file. You can use openssl to generate this from the .key file generated earlier:

bin/openssl req -new -days 365 -key myserver.key -out myserver.csr
Normally, as a security precaution, and as requested here, a certificate will be valid for one year; after that, it can still be used, but a browser will issue an alert notifying the user of its expiry. This .csr file can then be sent - by some secure channel of communication - to a CA like Verisign.

Alternatively, you can use openssl to create your own CA, and certify your own web server. To create a CA, you need to go through similar steps as for the web server: firstly, generate a private key, then generate a certificate. Another alternative, if you have a server configuration of NT, is to use Microsoft's own product, MS Certificate Server, to process your .csr into a .crt. Why bother with Verisign, then? Because browsers such as Netscape are preconfigured to know about trusted CAs, like Verisign and Thawte, and so will automatically accept certificates signed by them. But with an unknown CA, Netscape will force users to go through a sequence of four alert boxes, to get them to consider carefully if they want to accept this secure session. (Again this illustrates how there is always an element of trust at some point in all of this. Can you trust the source from which you obtained your copy of your browser? Are you sure that a hacker did not plant a version of a browser pre-configured to accept a bogus CA, which he is then using to certify impostor web sites? To see what CAs your browser accepts, in Netscape click the Security padlock icon, and find under Certificates the sub-heading Signers.

© INGENIO.co.uk