In previous posts we setup ColdFusion on Apache, created multiple ColdFusion instances, and created Virtual Directories to remote, UNC pathed resources. What's left? Well, what if you need to test SSL secure pages? Perhaps you have areas of your sites that need to have secure encryption, where you're harvesting personal information from your users. No one feels comfortable submitting personal information online if they don't see that little lock in the bottom of their browser. You, as a developer, want to be able to code this functionality, without the need to test it in your production environment.

With a little work, setting up a secure site within Apache is relatively simple. You already completed your first step when you installed ColdFusion and Apache, because the Apache version you installed was precompiled for SSL. With a few more steps you'll be on your way.

Download the openssl.cnf.txt file from the Download link below, and place the file in your Apache bin directory (C:\Program Files\Apache Group\Apache2\bin). Then, rename the file, removing the .txt extension. After you've done this, you may not see the remaining .cnf extension in your file browser, and it may say that it's a SpeedDial file type. That's OK, it's supposed to look that way. The next thing you need to do is copy the ssleay32.dll and lebeay32.dll files from your bin folder into your Windows\System32 folder. Make sure you copy the .dll files and not the .lib files. Now you're ready to create your personal security certificates.

Open a command prompt and navigate to your bin folder. Once there you can begin to use the openssl executable to create your certs. You will need one for each secure site you configure. Here we'll create one for secure.companyname.loc, by executing the following commands in your console.

view plain print about
1openssl req -config openssl.cnf -new -out secure.csr

The .csr file can have any name, but I've named it like this so I know that it's associated with my 'secure' domain. Note that you must create a certificate for each fully qualified domain name that you wish to be secure. The web browser will scream if the domain names don't match exactly. Here is a step by step of what you should see, with my responses bracketed by percentage signs.

view plain print about
1Loading 'screen' into random state - done
2Generating a 1024 bit RSA private key
3........++++++
4.......++++++
5writing new private key to 'privkey.pem'
6Enter PEM pass phrase: %my-made-up-pass%
7Verifying - Enter PEM pass phrase: %my-made-up-pass%
8-----
9You are about to be asked to enter information that will be incorporated into your certificate request.
10What you are about to enter is what is called a Distinguished Name or a DN.
11There are quite a few fields but you can leave some blank
12For some fields there will be a default value,
13If you enter '.', the field will be left blank.
14-----
15Country Name (2 letter code) []:%US%
16State or Province Name (full name) []:%mystate%
17Locality Name (eg, city) []:%mycity%
18Organization Name (eg, company) []:%companyname%
19Organizational Unit Name (eg, section) []:%mydept%
20Common Name (eg, your websites domain name) []:%secure.companyname.loc%
21Email Address []:%username@companyname.com%
22
23Please enter the following 'extra' attributes
24to be sent with your certificate request
25A challenge password []:%my-made-up-pass%

This will create the .csr file. Now, on to the next step, the private key file.

view plain print about
1openssl rsa -in privkey.pem -out secure.key
2Enter pass phrase for privkey.pem:%my-made-up-pass%
3writing RSA key

Ok, now that we have a private key all that's left is to get a certificate.

view plain print about
1openssl x509 -in secure.csr -out secure.cert -req -signkey secure.key -days 365
2Loading 'screen' into random state - done
3Signature OK
4subject=/C=US/ST=mystate/L=mycity/O=companyname/OU=mydept/CN=secure.companyname.loc/emailAddress=username@companyname.com
5Getting Private key

Alright, now you have your certificate for your 'secure' domain. Create, within your Apache conf folder, two new folders ssl.cert and ssl.key, and move your secure.cert and secure.key files into their respective folders. You may also delete the .rnd file from your Apache bin folder. This file contains entropy information for creating the key and could be used for cryptographic attacks against your private key. Although this isn't likely within your local development environment, it is still good practice.

As this is for your local environment, this is a simple way of creating a self-signed certificate for development use. All you have to do is install the certificate in your browser the first time you come to a secure page. Also note that this certificate expires after a year, and you can increase the -days 365 if you want.

Now we start getting into actually configuring your server for your SSL connection. First you will want to remove the comment hash (#) from the LoadModule line for ssl_module modules/mod_ssl.so. This is generally the last line of the LoadModule descriptors in your httpd.conf file.

view plain print about
1# SGB: [072408]: Enabling SSL
2LoadModule ssl_module modules/mod_ssl.so

Next you'll find the IfModule block below:

view plain print about
1<IfModule mod_ssl.c>
2    Include conf/ssl.conf
3</IfModule>

And add a few necessary lines:

view plain print about
1<IfModule mod_ssl.c>
2    Include conf/ssl.conf
3</IfModule>
4# SGB [072408]: Some added config for our SSL
5SSLMutex default
6SSLRandomSeed startup builtin
7SSLSessionCache none
8ErrorLog logs/ssl.log
9LogLevel info

It is very important that you move this descriptor block below the JRun Settings descriptor block. When you define which instance serves your secure pages you want it to know the JRun is needed.

The next step took a great deal of trial and error to get straight. First, make a backup copy of the ssl.conf file. Then, within the original file, we're going to make several changes. First, comment (with a hash sign [#]) the opening and closing IfDefine tags near the top and very bottom of the file.

view plain print about
1# SGB [072408]: Removed for proper load
2#<IfDefine SSL>
3    ....
4# SGB [072408]: Removed for proper load
5#</IfDefine>

And, set it up for NameVirtualHost, just as you did within your httpd.conf, but with the correct port for SSL.

view plain print about
1# SGB [072408]: Enable NameVirtualHost configurations on SSL
2NameVirtualHost 127.0.0.1:443

Next, remove the entire VirtualHost block from the file. This is loaded with lines and lines of comments, is already in your backup file for later reference, and only confuses what is needed (and caused me errors somewhere anyway). We'll setup a 'secure' VirtualHost entry for your secure domain, using the certificate and key you created before.

view plain print about
1# SGB [072408]: 'secure' SSL domain setup directive
2<VirtualHost 127.0.0.1:443>
3    DocumentRoot "C:\Documents and Settings\username\My Documents\wwwroot\siteroot"
4    ServerName secure.companyname.loc
5    ServerAdmin username@companyname.com
6    ErrorLog logs/secure-ssl-error.log
7    TransferLog logs/secure-ssl-access.log
8    SSLEngine On
9    SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
10    SSLCertificateFile conf/ssl.cert/secure.cert
11    SSLCertificateKeyFile conf/ssl.key/secure.key
12    <FilesMatch "\.(cgi|shtml|phtml|cfm|cfc|php3?)$">
13        SSLOptions +StdEnvVars
14    </FilesMatch>
15    <Directory "C:\Documents and Settings\username\My Documents\wwwroot\siteroot">
16        SSLOptions +StdEnvVars
17    </Directory>
18    SetEnvIf User-Agent ".*MSIE.*" \
19             nokeepalive ssl-unclean-shutdown \
20             downgrade-1.0 force-response-1.0
21    CustomLog logs/ssl_request_log \
22             "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
23</VirtualHost>

OK, what's left? Oh yeah! We need a ColdFusion instance to associate it with (in this case the 'sites' instance). And, we'll probably need those Aliases too. Easy enough. Just add your Include statements.

view plain print about
1# SGB [072408]: 'secure' SSL domain setup directive
2<VirtualHost 127.0.0.1:443>
3    DocumentRoot "C:\Documents and Settings\username\My Documents\wwwroot\siteroot"
4    ServerName secure.companyname.loc
5    ServerAdmin username@companyname.com
6    ErrorLog logs/secure-ssl-error.log
7    TransferLog logs/secure-ssl-access.log
8    SSLEngine On
9    SSLCipherSuite ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP:+eNULL
10    SSLCertificateFile conf/ssl.cert/secure.cert
11    SSLCertificateKeyFile conf/ssl.key/secure.key
12    <FilesMatch "\.(cgi|shtml|phtml|cfm|cfc|php3?)$">
13        SSLOptions +StdEnvVars
14    </FilesMatch>
15    <Directory "C:\Documents and Settings\username\My Documents\wwwroot\siteroot">
16        SSLOptions +StdEnvVars
17    </Directory>
18    SetEnvIf User-Agent ".*MSIE.*" \
19             nokeepalive ssl-unclean-shutdown \
20             downgrade-1.0 force-response-1.0
21    CustomLog logs/ssl_request_log \
22             "%t %h %{SSL_PROTOCOL}x %{SSL_CIPHER}x \"%r\" %b"
23    Include conf/cf_sitesinstance.conf
24    Include conf/site_aliases.conf
25</VirtualHost>

That's it! Restart your Apache server and go to https://secure.companyname.loc (make sure your put a test 'index.cfm' in there). First you will be asked to accept the development certificate that you created, and then you should see your test message display, with the little lock down in the corner.

And that is how to configure ColdFusion (7 or 8) on top of Apache, in a multi-instance configuration, with virtual, UNC pathed directories, SSL support, and access to your instance administrators. Verify your instance settings, setup your Data Sources, fire-up CFEclipse, checkout from the Subversion repository, and get to writin' some code!


Resources: And a hellavalotta trial and error. No one, single post answered every issue (some didn't even answer one issue by itself), and so...here it is.