Try as we might, protecting Apache directories based on a username and password does not give you true security by any stretch of the imagination . Even if a directory's contents are protected with an authentication mechanism, the data is still transferred over the network unencrypted. A sniffer can easily pick up the contents of a Web page regardless of whether a user entered a password to access the page.
To secure your private information, encryption must be taken to the level of the HTTPthat is, all web traffic must be protected. This is accomplished by using SSL and https the SSL-protected version of the HTTP. Apache support for SSL is added through the use of the mod_ssl module. Be aware that this adds an additional layer of complexity to Apache, and the potential for even more security holes.
For example, since the introduction of Mac OS X, the following mod_ssl exploits have surfaced:
http://archives.neohapsis.com/archives/bugtraq/2002-02/0313.html
http://cve.mitre.org/cgi-bin/cvename.cgi? name =CAN-2002-0653
Both exploits involve buffer overflows that enable users to potentially execute arbitrary code on the server. Although there's nothing you can do to avoid problems like this (other than shutting your computer off and curling up in a corner), it does serve as yet another poignant reminder that system security is highly dependent on keeping installed components up to date and being aware of the critical errors as they are discovered .
To build Apache with SSL support, you need a few components before you can get started. Unlike most Apache modules, the mod_ssl software must be compiled at the same time as the Apache source code. In addition, you need to download the OpenSSL software that mod_ssl uses for security. Later in the chapter you'll see how to enable the mod_ssl module included with Mac OS X 10.2. Enabling the module, although faster than recompiling, is not as clean as using the certificate management tools in the full Apache distribution, and isn't likely to be as up to date. If you do decide to just enable the existing mod_ssl , feel free to skip ahead in the chapter to "Activating the Included mod_ssl."
First, download the latest Apache source from http://www.apache.org/, the most current version of mod_ssl from http://www.modssl.org, and the Darwin-patched OpenSSL distribution from http://www.openssl.org. Place them in a common build directory:
% mkdir apachebuild % cd apachebuild/ % curl -O ftp://www.modssl.org/source/mod_ssl-2.8.10-1.3.27.tar.gz % curl -O http://www.apache.org/dist/httpd/apache_1.3.27.tar.gz % curl -O ftp://ftp.openssl.org/source/openssl-0.9.6g.tar.gz
Now, decompress and untar ( tar zxf <filename> ) each of the archives:
% tar zxf apache_1.3.27.tar.gz % tar zxf mod_ssl-2.8.10-1.3.27.tar.gz % tar zxf openssl-0.9.6g.tar.gz
All done! Let's move on.
The next step is to prepare mod_ssl this can be skipped if you are simply upgrading Apache and have no desire to add SSL support. Use the command ./configure --with-apache=< path to apache source distribution> from within the mod_ssl distribution directory, substituting the appropriate name of your Apache distribution:
# ./configure with-apache=../apache_1.3.27 Configuring mod_ssl/2.8.10 for Apache/1.3.27 + Apache location: ../apache_1.3.27 (Version 1.3.27) + Auxiliary patch tool: ./etc/patch/patch (local) + Applying packages to Apache source tree: o Extended API (EAPI) o Distribution Documents o SSL Module Source o SSL Support o SSL Configuration Additions o SSL Module Documentation o Addons Done: source extension and patches successfully applied.
The mod_ssl configuration will include several additional instructions on how to finish the Apache installation. Do not follow them or your compiled Apache server will be missing some important functions.
Now it's time to set up the OpenSSL systemagain, skip this step if you have no intention of running an SSL-enabled server.
NOTEIf you already have a fresh install of OpenSSL on your system, there's no need to recompile. Just be sure to set the SSL_BASE to the appropriate location in the next step ("Building Apache"). |
Compiling might take quite a while, depending on your system speed. You might want to start this process, then walk away for a few minutes. To configure OpenSSL for compilation, enter the distribution directory and type ./Config :
% ./Config Operating system: ppc-apple-darwin Configuring for darwin-ppc-cc Configuring for darwin-ppc-cc IsWindows=0 ...
After the software has been configured, use make to compile OpenSSL:
% make + rm -f libcrypto.0.dylib + rm -f libcrypto.dylib + rm -f libcrypto.0.9.6.dylib + rm -f libssl.0.dylib + rm -f libssl.dylib + rm -f libssl.0.9.6.dylib making all in crypto...
Finally, it's time to compile and install Apache.
Building Apache is straightforward. Apple has worked with the Apache group to incorporate information about the Mac OS X (Darwin) operating system into the source code distribution. What this means to you is that Apache, when compiled and installed, will correctly integrate itself with the Mac OS X operating system.
To configure Apache for installation, first move into the source distribution directory. If you are compiling with SSL support, you must set the SSL_BASE environment variable to point to the directory containing the OpenSSL source distribution:
% setenv SSL_BASE=../openssl-0.9.6g
Next, use ./configure --enable-module=all --enable-shared=max to set up the distribution for the Mac OS X environment:
% ./configure --enable-module=all --enable-shared=max Configuring for Apache, Version 1.3.27 + using installation path layout: Darwin (config.layout) Creating Makefile Creating Configuration.apaci in src Creating Makefile in src + configured for Darwin platform + setting C compiler to gcc + setting C pre-processor to gcc -E -traditional-cpp + checking for system header files + adding selected modules o rewrite_module uses ConfigStart/End enabling DBM support for mod_rewrite o dbm_auth_module uses ConfigStart/End o db_auth_module uses ConfigStart/End using Berkeley-DB/1.x for mod_auth_db (-lc) o ssl_module uses ConfigStart/End + SSL interface: mod_ssl/2.8.10 + SSL interface build type: DSO + SSL interface compatibility: enabled + SSL interface experimental code: disabled + SSL interface conservative code: disabled + SSL interface vendor extensions: disabled + SSL interface plugin: Configured DBM (-ldbm) + SSL library path: /Users/jray/apachebuild/openssl-0.9.6g + SSL library version: OpenSSL 0.9.6b 9 Jul 2001 + SSL library type: source tree only (stand-alone)
If an error occurs, make sure that you have correctly set the SSL_BASE and typed the command-line options exactly as they appear here.
Now, one tiny correction needs to be made to the SSL module Makefile . From within the main Apache source distribution, go into src/modules/ssl/ . Open the file Makefile in your favorite text editor and look for the line that reads
SSL_LIBS= -ldbm -lssl -lcrypto -L/usr/lib -lgcc
Change it to
SSL_LIBS= -lssl -lcrypto -L/usr/lib -lgcc
If you fail to follow these steps, the compilation process will complain of a missing library.
Finally, compile your new version of Apache by typing make from within the root level of the Apache source directory:
% make ===> src ===> src/regex sh ./mkh -p regcomp.c >regcomp.ih ...
The compile should finish in roughly three minutes on a base 1GHz G4. When the compile finishes, Apache displays a success message with the following instructions:
+---------------------------------------------------------------------+ Before you install the package you now should prepare the SSL certificate system by running the 'make certificate' command. For different situations the following variants are provided: % make certificate TYPE=dummy (dummy self-signed Snake Oil cert) % make certificate TYPE=test (test cert signed by Snake Oil CA) % make certificate TYPE=custom (custom cert signed by own CA) % make certificate TYPE=existing (existing cert) CRT=/path/to/your.crt [KEY=/path/to/your.key] Use TYPE=dummy when you're a vendor package maintainer, the TYPE=test when you're an admin but want to do tests only, the TYPE=custom when you're an admin willing to run a real server and TYPE=existing when you're an admin who upgrades a server. (The default is TYPE=test) Additionally add ALGO=RSA (default) or ALGO=DSA to select the signature algorithm used for the generated certificate. Use 'make certificate VIEW=1' to display the generated data. Thanks for using Apache & mod_ssl. Ralf S. Engelschall rse@engelschall.com www.engelschall.com +---------------------------------------------------------------------+
You now have the most recent version of Apache, and it is ready to start handling secure Web traffic! All that remains is a few more minutes of setting up a basic certificate. If you are not using SSL, you can type sudo make install to start using the new version of Apache immediately.
Secure Web servers rely on a CA (Certificate Authority) signed certificate to prove their identity and open a secure connection with a client. Unfortunately, obtaining a certificate isn't as simple as going to a Web site and buying one. An official certificate can be issued only by a CA, and only after you generate and send a CSR (Certificate Signing Request) to it. Luckily, for the purposes of testing SSL-enabled Apache, you can sign your own certificate. This will create a secure server, but most Web browsers will display a dialog box when accessing a server that isn't signed by a known CA. For the purposes of this chapter, we'll assume that you want to get up and running quickly, and that you'll want to use a VeriSign or other CA signed certificate later on.
Assuming that you're in the top level of the Apache distribution directory, type make certificate TYPE=test . This will take you through the steps of setting up a certificate, allowing you to automatically sign it with a fictional CA so that it can be used immediately, and then creating a CSR file so that you can send in a request for a real certificate in the future. During the certification creation, you are asked a series of questions related to your business or organization. Of all the questions, it is most important to correctly answer the Common Name prompt. This is your Web server's hostname (for example, www.poisontooth.com ). Any questions you are unsure of can be left with their default values:
[View full width]% make certificate TYPE=test SSL Certificate Generation Utility (mkcert.sh) Copyright (c) 1998-2000 Ralf S. Engelschall, All Rights Reserved. Generating test certificate signed by Snake Oil CA [TEST] WARNING: Do not use this for real-life/production systems ______________________________________________________________________ STEP 0: Decide the signature algorithm used for certificate The generated X.509 CA certificate can contain either RSA or DSA based ingredients. Select the one you want to use. Signature Algorithm ((R)SA or (D)SA) [R]: ______________________________________________________________________ STEP 1: Generating RSA private key (1024 bit) [server.key] 2529186 semi-random bytes loaded Generating RSA private key, 1024 bit long modulus ...........................++++++ ......++++++ e is 65537 (0x10001) ______________________________________________________________________ STEP 2: Generating X.509 certificate signing request [server.csr] Using configuration from .mkcert.cfg 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. ----- 1. Country Name (2 letter code) [XY]: US 2. State or Province Name (full name) [Snake Desert]: Ohio 3. Locality Name (eg, city) [Snake Town]: Dublin 4. Organization Name (eg, company) [Snake Oil, Ltd]: PoisonTooth, Ent. 5. Organizational Unit Name (eg, section) [Webserver Team]: 6. Common Name (eg, FQDN) [www.snakeoil.dom]: www.poisontooth.com 7. Email Address (eg, name@FQDN) [www@snakeoil.dom]: jray@poisontooth.com 8. Certificate Validity (days) [365]: ______________________________________________________________________ STEP 3: Generating X.509 certificate signed by Snake Oil CA [server.crt] Certificate Version (1 or 3) [3]: Signature ok subject=/C=US/ST=Ohio/L=Dublin/O=PoisonTooth, Ent./OU=Webserver Team/ CN=www.poisontooth. com/Email=jray@poisontooth.com Getting CA Private Key Verify: matching certificate & key modulus read RSA key Verify: matching certificate signature ../conf/ssl.crt/server.crt: OK ______________________________________________________________________ STEP 4: Enrypting RSA private key with a pass phrase for security [server.key] The contents of the server.key file (the generated private key) has to be kept secret. So we strongly recommend you encrypt the server.key file with a Triple-DES cipher and a Pass Phrase. Encrypt the private key now? [Y/n]: n Warning, you're using an unencrypted RSA private key. Please notice this fact and proceed at your own risk. ______________________________________________________________________ RESULT: Server Certification Files o conf/ssl.key/server.key The PEM-encoded RSA private key file which you configure with the 'SSLCertificateKeyFile' directive (automatically done when you install via APACI). KEEP THIS FILE PRIVATE! o conf/ssl.crt/server.crt The PEM-encoded X.509 certificate file which you configure with the 'SSLCertificateFile' directive (automatically done when you install via APACI). o conf/ssl.csr/server.csr The PEM-encoded X.509 certificate signing request file which you can send to an official Certificate Authority (CA) to request a real server certificate (signed by this CA instead of our demonstration-only Snake Oil CA), which later can replace the conf/ssl.crt/server.crt file. WARNING: Do not use this for real-life/production systems
In this example, there is only one nonintuitive response: the use of encryption for the server key ( Encrypt the private key now? [Y/n]: n ). If the server key is encrypted, you have to manually enter a password to unlock the key each time the server is started, or write a script to supply the password to the server. When the key is left unencrypted, the assumption is made that your server protection is sufficient to keep the file safe from prying eyes. The Apache server and certificate are ready to install. Type sudo make install to prepare the software:
% sudo make install ===> [mktree: Creating Apache installation tree] ./src/helpers/mkdir.sh /usr/bin ./src/helpers/mkdir.sh /usr/sbin ... +--------------------------------------------------------+ You now have successfully built and installed the Apache 1.3 HTTP server. To verify that Apache actually works correctly you now should first check the (initially created or preserved) configuration files /etc/httpd/httpd.conf and then you should be able to immediately fire up Apache the first time by running: /usr/sbin/apachectl start Or when you want to run it with SSL enabled use: /usr/sbin/apachectl startssl Thanks for using Apache. The Apache Group http://www.apache.org/ +--------------------------------------------------------+
Unfortunately, the installation of the newly compiled Apache needs a modified version of the configuration file, so you still need to make two final changes before you're done. Open the file /etc/httpd/httpd.conf.default and add the following line to the bottom of the file:
Include /private/etc/httpd/users
Next, search for the directive
UserDir public_html
and change it to
UserDir Sites
Save the configuration file and copy it to take the place of /etc/httpd/httpd.conf . Now you're ready to go. Stop the existing Apache server ( apachectl stop ) and start the new SSL-enabled server with apachectl startssl .
% sudo /usr/sbin/apachectl stop /usr/sbin/apachectl stop: httpd stopped # /usr/sbin/apachectl startssl Processing config directory: /private/etc/httpd/users Processing config file: /private/etc/httpd/users/jray.conf Processing config file: /private/etc/httpd/users/robyn.conf Processing config file: /private/etc/httpd/users/test.conf Processing config file: /private/etc/httpd/users/test2.conf /usr/sbin/apachectl startssl: httpd started
To configure Mac OS X to automatically start Apache in SSL mode each time it boots, edit the file /System/Library/StartupItems/Apache/Apache and change the line
apachectl start
to read
apachectl startssl
That wasn't so bad, was it? Your Mac OS X machine is now a full- fledged secure Web server. To test it, open a Web browser and point to a URL on the machine, prefacing the URL with https:// rather than the usual http:// . Your browser might display a message about the certificate and signing authority not being recognized and ask you if you want to accept it, as shown in Figure 15.2.
You can expect to see these messages until you send in a certificate-signing request to a recognized CA. Upon loading the now-secure the page, you'll notice the small "lock" icon in the status bar of your browser window, indicating the traffic is secure.
USING CERTIFYING AUTHORITIESWhen you created your server certificate, you also created a CSR that can be sent to a CA to generate a real certificate. The certificate signing request file is stored in /etc/httpd/ssl.csr/server.csr . This file can be sent to a CA, such as VeriSign : http://digitalid.verisign.com/server/apacheNotice.htm Thawte : http://www.thawte.com/html/RETAIL/ssl/index.html After processing your request, the CA will return a new digitally signed certificate file. Replace the existing /etc/httpd/ssl.crt/server.crt certificate with the CA signed certificate, and your server will be official. |
Any time you recompile Apache manually, you should add mod_hfs_apple support back into the system; otherwise you put yourself at risk for the case-sensitivity exploit discussed earlier in the chapter. To reinstall mod_hfs_apple , download the source distribution from Apple's Darwin repository at http://www.opensource.apple.com/projects/darwin/6.0/projects.html or from http://www.opendarwin.org/cgi-bin/cvsweb.cgi/src/apache_mod_hfs_apple/.
The distribution consists of a Makefile and a source filewhich you install much the same way as you did the mod_auth_apple . Unarchive and enter the module distribution. As always, the installation needs to take place as root, or use sudo for the final step:
# tar zxf apache_mod_hfs_apple-3.tar.gz # cd apache_mod_hfs_apple-3
Next, edit the Makefile line. Look for the section reading
all build $(MODULE): $(MODULE_SRC) $(OTHER_SRC) ln -sf $(SRCROOT)$(SRCPATH)/Makefile $(OBJROOT)/Makefile ln -sf $(SRCROOT)$(SRCPATH)/mod_hfs_apple.c $(OBJROOT)/mod_hfs_apple.c
Comment out the two ln link lines:
all build $(MODULE): $(MODULE_SRC) $(OTHER_SRC) #ln -sf $(SRCROOT)$(SRCPATH)/Makefile $(OBJROOT)/Makefile #ln -sf $(SRCROOT)$(SRCPATH)/mod_hfs_apple.c $(OBJROOT)/mod_hfs_apple.c
While you're still in the file, look for the line commented-out that looks like
# /usr/sbin/apxs -i -a -n hfs_apple $(MODULE)
Uncomment it so that it reads:
/usr/sbin/apxs -i -a -n hfs_apple $(MODULE)
You're now ready to compile and install using make DSTROOT=. OBJROOT=. and make install DSTROOT=. OBJROOT=. , respectively:
# make DSTROOT=. OBJROOT=. #ln -sf /Makefile ./Makefile #ln -sf /mod_hfs_apple.c ./mod_hfs_apple.c cd . ; /usr/sbin/apxs -c -S LDFLAGS_SHLIB="-bundle -bundle_loader ... # make install DSTROOT=. OBJROOT=. Installing product... /bin/mkdir -p ./usr/libexec/httpd /bin/cp ./mod_hfs_apple.so ./usr/libexec/httpd /bin/chmod 755 ./usr/libexec/httpd/mod_hfs_apple.so /usr/bin/strip -x ./usr/libexec/httpd/mod_hfs_apple.so /usr/sbin/apxs -i -a -n hfs_apple mod_hfs_apple.so [activating module `hfs_apple' in /private/etc/httpd/httpd.conf] cp mod_hfs_apple.so /usr/libexec/httpd/mod_hfs_apple.so chmod 755 /usr/libexec/httpd/mod_hfs_apple.so cp /private/etc/httpd/httpd.conf /private/etc/httpd/httpd.conf.bak cp /private/etc/httpd/httpd.conf.new /private/etc/httpd/httpd.conf rm /private/etc/httpd/httpd.conf.new
The mod_hfs_apple module is now compiled and installed, and your server is again protected from case-sensitivity issues.
If you'd rather just use the Apple-supplied version of mod_ssl with Apache, you can avoid the entire compile process and simply activate the existing module by changing a few lines in /etc/httpd/httpd.conf . The benefit to this approach is time savings coupled with the ability to blame Apple if exploits are found for the version they've provided. (That's sarcasm, folks! It's your responsibility to keep track of security issues, especially for components such as mod_ssl , which Apple doesn't formally support on the Mac OS X client.)
There are three steps to this process:
Create a Certificate-Signing Request. This request is usually sent to a CA, where it is signed, and a server certificate is returned.
Create and use a CA to sign the request. You'll be signing the request yourself, rather than using a third party (which should be done on a production server).
Configure Apache for SSL. Because SSL support wasn't built into Apache, you need to do a bit of editing by hand to make the server work as expected.
You'll be using OpenSSL for most of the remainder of the chapter to create private keys, signing requests , and act as the CA. This will be similar to creating the OpenSSL-enabled mail server in Chapter 13, "Mail Server Security," but we'll go through the process, step-by-step, so you know what to expect.
First, create and enter a new directory that you'll use for the entire process:
% mkdir ssltmp % cd ssltmp
You'll need some random data to seed the encryption. There are a number of ways to generate pseudo-random data for this purpose. One of the easiest is to use /dev/random . Create a file with random data by typing head /dev/random > random.seed .
% head /dev/random > random.seed
Next, use openssl genrsa -des3 -rand random.seed -out server.key 1024 to generate a 1024-bit RSA key.
% openssl genrsa -des3 -rand random.seed -out server.key 1024 1890 semi-random bytes loaded Generating RSA private key, 1024 bit long modulus .++++++ .......++++++ e is 65537 (0x10001) Enter PEM pass phrase: ***** Verifying password - Enter PEM pass phrase: *****
During this process, you'll be asked for a passphrase. This phrase is used to protect the server.key, which is, itself, the private key for your server. If this is confusing, see Chapter 5, "Picking Locks: Password Attacks," for more information on encryption and public/private key systems.
Now, to create the certificate signing request, use the command openssl req -new -key server.key -out server.csr . When prompted, enter the passphrase you used when creating the server key. The other critical piece of information is the Common Name, which, in this case, refers to your server's fully qualified domain namein this example, www.poisontooth.com .
% openssl req -new -key server.key -out server.csr Using configuration from /System/Library/OpenSSL/openssl.cnf Enter PEM pass phrase: ***** 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) [AU]: US State or Province Name (full name) [Some-State]: Ohio Locality Name (eg, city) []: Columbus Organization Name (eg, company) [Internet Widgits Pty Ltd]: PoisonTooth Ent. Organizational Unit Name (eg, section) []: Development Common Name (eg, YOUR name) []: www.poisontooth.com Email Address []: jray@macosxunleashed.com Please enter the following 'extra' attributes to be sent with your certificate request A challenge password []: An optional company name []:
You've now created the file server.csr , which contains your certificate-signing request. In a production server environment, you'd send this file to a "real" Certificate Authority, then receive back a signed server certificate ( server.crt in the examples throughout this chapter), which you could install in Apache and go. If you are creating a production server, you'll want to proceed with getting the real .crt file and skip the next step, which allows you to sign your own certificate.
To sign the request that you just generated, you need to create a CA key (using the same process required to generate the server.key file) and then use that key to create a self-signed CA certificate. This certificate, when completed, will be used to sign your original request. You're becoming your own Certificate Authoritywhich, while inappropriate for production servers, is fine for a test environment.
First, create the CA keyfile using openssl genrsa -des3 -rand random.seed -out ca.key . As you did previously, choose a passphrase you can remember, and it shouldn't be the same one that you used earlier:
% openssl genrsa -des3 -rand random.seed -out ca.key 1890 semi-random bytes loaded Generating RSA private key, 512 bit long modulus ....++++++++++++ ........++++++++++++ e is 65537 (0x10001) Enter PEM pass phrase: Verifying password - Enter PEM pass phrase:
Next, create the CA certificate with openssl req -new -x509 -days 100 -key ca.key -out ca.crt . You may want to change the days attribute to increase the length of time the certificate will be valid if you plan to use it for signing requests in the future.
% openssl req -new -x509 -days 1000 -key ca.key -out ca.crt Using configuration from /System/Library/OpenSSL/openssl.cnf Enter PEM pass phrase: ****** 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) [AU]: US State or Province Name (full name) [Some-State]: Ohio Locality Name (eg, city) []: Columbus Organization Name (eg, company) [Internet Widgits Pty Ltd]: PoisonTooth Ent. Organizational Unit Name (eg, section) []: IT Department Common Name (eg, YOUR name) []: John Ray Email Address []:jray@macosxunleashed.com
Now it's time to sign the server.csr file by using the CA certificate and key. To do this, you need to download the utility sign.sh included in the mod_ssl package. The easiest way to do this is grab it from the Open Darwin CVS: http://www.opendarwin.org/cgi-bin/cvsweb.cgi/src/apache_mod_ssl/mod_ssl/pkg. contrib /sign.sh. After downloading, make sure to give execute permissions to the script ( chmod +x sign.sh ). Finally, use sign.sh server.csr to create your server.crt file:
% ./sign.sh server.csr CA signing: server.csr -> server.crt: Using configuration from ca.config Enter PEM pass phrase: ***** Check that the request matches the signature Signature ok The Subjects Distinguished Name is as follows countryName :PRINTABLE:'US' stateOrProvinceName :PRINTABLE:'Ohio' localityName :PRINTABLE:'Columbus' organizationName :PRINTABLE:'PoisonTooth Ent.' organizationalUnitName:PRINTABLE:'Development' commonName :PRINTABLE:'www.poisontooth.com' emailAddress :IA5STRING:'jray@macosxunleashed.com' Certificate is to be certified until Oct 31 03:42:41 2003 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 CA verifying: server.crt <-> CA cert server.crt: OK
NOTEBecause this certificate is being signed for a test server, you may want to bump the 365-day limit up by editing the sign.sh file and changing the default_days attribute to something else. |
The server certificate is now signed and ready for use. When using mod_ssl , Apache will require your initial passphrase to start and access the server.key file. There are two ways to solve this problem. On a production server, Apache's startup should be modified so that the password is supplied to it (via script or another mechanism); otherwise the server process will hang while it waits for the input. The alternative approach, which we'll use here, is to create an unencrypted version of server.key :
% cp server.key server.key.original % openssl rsa -in server.key.original -out server.key read RSA key Enter PEM pass phrase: ***** writing RSA key
Finally, create the directories /etc/httpd/ssl.crt , /etc/httpd/ssl.csr , /etc/httpd/ssl.key , into which you'll copy the files server.crt , server.csr , and server.key . You'll need to use sudo or be logged in as root to do this:
% sudo -s # mkdir /etc/httpd/ssl.crt # mkdir /etc/httpd/ssl.key # mkdir /etc/httpd/ssl.csr # cp server.crt /etc/httpd/ssl.crt # cp server.csr /etc/httpd/ssl.csr # cp server.key /etc/httpd/ssl.key
The directory structure isn't of importance. The names used in this example are based on those of the default Apache mod_ssl distribution. Of the files you've moved, only the .crt and .key files are actually used by Apache. The server.csr file, however, might be useful to keep around if you want to submit it to a real Certificate Authority later.
You can get rid of ca.crt and ca.key files, unless you want to use them for signing additional requests. The CA certificate and key could potentially be misused by a third party to impersonate you. They are your personal identifiers and should not be made publicly accessible or left unprotected on the server.
The final step in activating mod_ssl is to edit /etc/httpd/httpd.conf to include the appropriate directives to load mod_ssl and the server certificate you just created. Open /etc/httpd/httpd.conf now.
NOTEAdding SSL support is going to require adding quite a few new lines to your httpd.conf file. These lines are shown here with the official Apache comments preceding them. If you don't want to do as much typing, leave out the configuration lines that begin with # . |
First, uncomment the mod_ssl lines in the file, changing
#LoadModule ssl_module libexec/httpd/libssl.so #AddModule mod_ssl.c
to
LoadModule ssl_module libexec/httpd/libssl.so AddModule mod_ssl.c
Now, you're going to (more or less) rebuild the SSL-enabled config file that comes with Apache if you compile in SSL support by hand. Apache must be told to listen on port 443 ( https ) in addition to port 80. Locate the line Port 80 in your config file and add the following immediately after it:
## ## SSL Support ## ## When we also provide SSL we have to listen to the ## standard HTTP port (see above) and to the HTTPS port ## <IfDefine SSL> Listen 80 Listen 443 </IfDefine>
Next, move to the bottom of the configuration file and insert the following directives. The comments aren't critical, so you can feel free to skip them if you'd like:
## ## SSL Global Context ## ## All SSL configuration in this context applies to both ## the main server and all SSL-enabled virtual hosts. ## # # Some MIME-types for downloading Certificates and CRLs # <IfDefine SSL> AddType application/x-x509-ca-cert .crt AddType application/x-pkcs7-crl .crl </IfDefine> <IfModule mod_ssl.c> # Pass Phrase Dialog: # Configure the pass phrase gathering process. # The filtering dialog program ('builtin' is an internal # terminal dialog) has to provide the pass phrase on stdout. SSLPassPhraseDialog builtin # Inter-Process Session Cache: # Configure the SSL Session Cache: First the mechanism # to use and second the expiring timeout (in seconds). SSLSessionCache dbm:/var/log/httpd/ssl_scache SSLSessionCacheTimeout 300 # Semaphore: # Configure the path to the mutual exclusion semaphore the # SSL engine uses internally for inter-process synchronization. SSLMutex file:/var/log/httpd/ssl_mutex # Pseudo Random Number Generator (PRNG): # Configure one or more sources to seed the PRNG of the # SSL library. The seed data should be of good random quality. # WARNING! On some platforms /dev/random blocks if not enough entropy # is available. This means you then cannot use the /dev/random device # because it would lead to very long connection times (as long as # it requires to make more entropy available). But usually those # platforms additionally provide a /dev/urandom device that doesn't # block. So, if available, use this one instead. Read the mod_ssl User # Manual for more details. SSLRandomSeed startup builtin SSLRandomSeed connect builtin # Logging: # The home of the dedicated SSL protocol logfile. Errors are # additionally duplicated in the general error log file. Put # this somewhere where it cannot be used for symlink attacks on # a real server (that is, somewhere where only root can write). # Log levels are (ascending order: higher ones include lower ones): # none, error, warn, info, trace, debug. SSLLog /var/log/httpd/ssl_engine_log SSLLogLevel info </IfModule>
NOTEThe paths used for SSLSessionCache and SSLMutex are different from the Apache defaults. In this example, they're configured to the same values Apple uses for Mac OS X Server. You can change them to something more logical, such as /var/db or /var/run , if you'd like. |
As a final step, you need to " turn on" the SSL Engine for your Web server. You can do this either for a given virtual host or for the entire server. This example uses a virtual host entry for /Library/WebServer/Documents (which is the main server). The advantage of this approach is that the SSL-protected accesses can be logged and dealt with separately, rather than combined with the main site logs and rules. Add the following to the bottom of your /etc/httpd/httpd.conf file. Again, comments aren't necessary; they're provided to reflect the defaults in the Apache SSL installation. Be sure to change the ServerName and ServerAdmin directives to match your particular installation:
<IfDefine SSL> ## ## SSL Virtual Host Context ## <VirtualHost _default_:443> #General setup for the virtual host DocumentRoot "/Library/WebServer/Documents" ServerName www.poisontooth.com ServerAdmin jray@macosxunleashed.com ErrorLog /var/log/httpd/ssl_error_log TransferLog /var/log/httpd/ssl_access_log # SSL Engine Switch: # Enable/Disable SSL for this virtual host. SSLEngine on # SSL Cipher Suite: # List the ciphers that the client is permitted to negotiate. # See the mod_ssl documentation for a complete list. SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL # Server Certificate: # Point SSLCertificateFile at a PEM encoded certificate. If # the certificate is encrypted, then you will be prompted for a # pass phrase. Note that a kill -HUP will prompt again. A test # certificate can be generated with 'make certificate' under # built time. Keep in mind that if you've both a RSA and a DSA # certificate you can configure both in parallel (to also allow # the use of DSA ciphers, etc.) SSLCertificateFile /etc/httpd/ssl.crt/server.crt # Server Private Key: # If the key is not combined with the certificate, use this # directive to point at the key file. Keep in mind that if # you've both a RSA and a DSA private key you can configure # both in parallel (to also allow the use of DSA ciphers, etc.) SSLCertificateKeyFile /etc/httpd/ssl.key/server.key # SSL Engine Options: # Set various options for the SSL engine. # o FakeBasicAuth: # Translate the client X.509 into a Basic Authorization. This means that # the standard Auth/DBMAuth methods can be used for access control. The # user name is the 'one line' version of the client's X.509 certificate. # Note that no password is obtained from the user. Every entry in the user # file needs this password: 'xxj31ZMTZzkVA'. # o ExportCertData: # This exports two additional environment variables: SSL_CLIENT_CERT and # SSL_SERVER_CERT. These contain the PEM-encoded certificates of the # server (always existing) and the client (only existing when client # authentication is used). This can be used to import the certificates # into CGI scripts. # o StdEnvVars: # This exports the standard SSL/TLS related 'SSL_*' environment variables. # Per default this exportation is switched off for performance reasons, # because the extraction step is an expensive operation and is usually # useless for serving static content. So one usually enables the # exportation for CGI and SSI requests only. # o CompatEnvVars: # This exports obsolete environment variables for backward compatibility # to Apache-SSL 1.x, mod_ssl 2.0.x, Sioux 1.0 and Stronghold 2.x. Use this # to provide compatibility to existing CGI scripts. # o StrictRequire: # This denies access when "SSLRequireSSL" or "SSLRequire" applied even # under a "Satisfy any" situation, i.e. when it applies access is denied # and no other module can change it. # o OptRenegotiate: # This enables optimized SSL connection renegotiation handling when SSL # directives are used in per-directory context. #SSLOptions +FakeBasicAuth +ExportCertData +CompatEnvVars +StrictRequire <Files ~ "\.(cgishtmlphtmlphp3?)$"> SSLOptions +StdEnvVars </Files> <Directory "/Library/Webserver/CGI-Executables"> SSLOptions +StdEnvVars </Directory> # SSL Protocol Adjustments: # The safe and default but still SSL/TLS standard compliant shutdown # approach is that mod_ssl sends the close notify alert but doesn't wait for # the close notify alert from client. When you need a different shutdown # approach you can use one of the following variables: # o ssl-unclean-shutdown: # This forces an unclean shutdown when the connection is closed, i.e. no # SSL close notify alert is send or allowed to received. This violates # the SSL/TLS standard but is needed for some brain-dead browsers. Use # this when you receive I/O errors because of the standard approach where # mod_ssl sends the close notify alert. # o ssl-accurate-shutdown: # This forces an accurate shutdown when the connection is closed, i.e. a # SSL close notify alert is send and mod_ssl waits for the close notify # alert of the client. This is 100% SSL/TLS standard compliant, but in # practice often causes hanging connections with brain-dead browsers. Use # this only for browsers where you know that their SSL implementation # works correctly. # Notice: Most problems of broken clients are also related to the HTTP # keep-alive facility, so you usually additionally want to disable # keep-alive for those clients, too. Use variable "nokeepalive" for this. # Similarly, one has to force some clients to use HTTP/1.0 to work around # their broken HTTP/1.1 implementation. Use variables "downgrade-1.0" and # "force-response-1.0" for this. SetEnvIf User-Agent ".*MSIE.*" \ nokeepalive ssl-unclean-shutdown \ downgrade-1.0 force-response-1.0 # Per-Server Logging: # The home of a custom SSL log file. Use this when you want a # compact non-error SSL logfile on a virtual host basis. CustomLog /var/log/httpd/ssl_request_log \ "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b" </VirtualHost> </IfDefine>
If you'd rather just SSL-enable your entire server, you can leave out the <VirtualHost> tags and the DocumentRoot , ServerName , ServerAdmin , and ErrorLog directives. This uses the default setting for your Web server, but enables mod_ssl globally, rather than for a virtual host.
WHAT IS A VIRTUAL HOST?A virtual host is a unique container object, in that it can define an entirely separate Web space unrelated to the main Apache Web site or user sites. For example, the three domains poisontooth.com , vujevich.com , and shadesofinsanity.com are all being served from a single computer. To the end user, these appear to be different and unique hosts. To Apache, however, they're just different directories on the same hard drive. There are two types of virtual hosts: name-based and IP-based. Name-based virtual hosts rely on the HTTP/1.1 to work. A single IP address is used on the server, but there are multiple DNS entries for that single address. When connecting to the server, the client browser sends a request for a Web page, along with the name of the server from which it should come. Apache uses that information to serve the correct page. This works for all but the oldest 2.0 revision browsers. IP-based virtual hosts relyon Apache's capability to listen to multiple IP addresses simultaneously . Each domain name is assigned to a different IP address. Apache can differentiate between the different incoming addresses and serve the appropriate documents for each. This works on any browser, but is costly in terms of the IP addresses that it consumes. There are only two differences in the Apache configuration of name-based and IP-based virtual hosts. Name-based hosts must include the NameVirtualHost directive, whereas IP-based hosts need to use Listen to inform Apache of all the available addresses. Let's take a look at two different ways to configure the virtual hosts www.mycompany.com and www.yourcompany.com . First, using named-based hosting: Assume that both mycompany and yourcompany domain names point to the IP address 192.168.0.100 . To configure name-based virtual hosts, you could add the following directives to the end of the /etc/httpd/httpd.conf file: NameVirtualHost 192.168.0.100 <VirtualHost 192.168.0.100> ServerName www.mycompany.com DocumentRoot /Users/jray/mycompany ServerAdmin president@mycompany.com </VirtualHost> <VirtualHost 192.168.0.100> ServerName www.yourcompany.com DocumentRoot /Users/jray/yourcompany ServerAdmin president@yourcompany.com </VirtualHost> The NameVirtualHost sets up the IP address on which Apache expects multiple domain name requests to come in. The two VirtualHost directives define the basic properties of the two sites: what their real domain names are, where the HTML documents are loaded, and the email address for the person who runs the site. Creating this same setup using IP-based hosts doesn't require much additional effort. For this sample configuration, assume that www.mycompany.com has the address 192.168.0.100 and www.yourcompany.com uses 192.168.0.101 . The configuration becomes Listen 192.168.0.100 Listen 192.168.0.101 <VirtualHost 192.168.0.100> ServerName www.mycompany.com DocumentRoot /Users/jray/mycompany ServerAdmin president@mycompany.com </VirtualHost> <VirtualHost 192.168.0.101> ServerName www.yourcompany.com DocumentRoot /Users/jray/yourcompany ServerAdmin president@yourcompany.com </VirtualHost> This time, the Listen directive is used to tell Apache to watch for incoming Web connections on both the available IP addresses. The VirtualHost containers remain the same, except they now use different IP addresses for the two different sites. |
To start your SSL-enabled Apache, you should use the command sudo http -DSSL . This defines the runtime SSL variable, which, in turn, enables the SSL configuration we've created in /etc/httpd/httpd.conf . If you use the standard /usr/sbin/apachectl start command, SSL support will be turned off.
If you've read through this entire section, you may have noticed that when you install an SSL-enabled Apache by hand, you can use /usr/sbin/apachectl startssl to start Apache with SSL support. Unfortunately, the version of apachectl that Apple is currently distributing with Mac OS X does not support this feature.
To be sure that Apache starts with SSL support, you can open the /usr/sbin/apachectl script and change the line that reads
HTTPD=/usr/sbin/httpd
to
HTTPD="/usr/sbin/httpd -DSSL"
Your system can now start and stop your mod_ssl Apache as it normally does.
No matter how you choose to enable mod_ssl on your system, you're going to end up seeing some unfamiliar SSL-related directives in your Apache configuration file. The best reference for what these do is the source: http://www.modssl.org/docs/. For your convenience, a summary of the directives used in the configuration we just created is provided in Table 15.5.
Directive | Purpose |
---|---|
SSLPassPhraseDialog builtin exec : <path to executable> | Choose how the server's private key will be decrypted. The builtin method prompts the user when Apache is starting. Because we removed the password from our key, no password is required. Alternatively exec can be used to provide a program that is executed to provide the passphrase. |
SSLMutex nonefile: <file path> sem | Determines how the SSL engine will create mutually exclusive locks for operations in the Apache server processes. Mac OS X users should use the file method. |
SSLRandomSeed server connect builtinfile: <file path> exec: <path to executable> | Determines how random numbers are seeded at server startup (server) or when a connection (connect) is created. Mac OS X users can use the builtin method or file:/dev/random . |
SSLSessionCache none dbm: <file path> | Creates an optional SSL session cache file. Mac OS X users can use a dbm database file to store the cache. |
SSLSessionCacheTimeout <seconds> | The length of time in seconds before an SSL session expires in the cache. |
SSLEngine onoff | Turns SSL on for the server or a configured virtual host. |
SSLProtocol +/- <protocol>.. | Chooses the SSL protocols the server is to use. Valid options are All , SSLv2 , TLSv1 . Protocols can be prefixed with + or - to add or subtract them from the list. |
SSLCipherSuite <Cipher list> | Chooses the ciphers that the client computer is allowed to use during the SSL handshake. See http://www.modssl.org for a full list of the available options. |
SSLCertificateFile <filename> | Specifies the path to the site certificate file /etc/httpd/ssl.crt/server.crt for our examples. |
SSLCertificateKeyFile <filename> | Sets the path of the private key file /etc/httpd/ssl.key/server.key . |
SSLLog <log file pathname> | Logfile dedicated to logging SSL protocol errors and exceptions. |
SSLLogLevel noneerrorwarninfotracedebug | Determines the amount of information that will be logged to the SSLLog filelisted in order of increasing verbosity . |
SSLOptions +/ <option>SSL | Sets SSL runtime options. Please set the comments in the Apache options earlier in the chapter or visit http://www.modssl.org for a full list and description of options. |
SSLRequireSSL | When applied to a directory or virtual host, non SSL access will be prohibited to that resource. |
Top |