DekGenius.com
[ Team LiB ] Previous Section Next Section

Recipe 7.4 Serving a Portion of Your Site via SSL

Problem

You want to have a certain portion of your site available via SSL exclusively.

Solution

This is done by making changes to your httpd.conf file.

For Apache 1.3, add a line such as the following:

Redirect /secure/ https://secure.domain.com/secure/

For Apache 2.0:

<Directory /www/secure>
    SSLRequireSSL
</Directory>

Or, with mod_rewrite:

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

Discussion

It is perhaps best to think of your site's normal pages and its SSL-protected pages as being handled by two separate servers, rather than one. While they may point to the same content, they run on different ports, are configured differently, and, most importantly, the browser considers them to be completely separate servers. So you should too.

Don't think of enabling SSL for a particular directory; rather, you should think of it as redirecting requests for one directory to another.

Note that the Redirect directive preserves path information, which means that if a request is made for /secure/something.html, then the redirect will be to https://secure.domain.com/secure/something.html.

Be careful where you put this directive. Make sure that you only put it in the HTTP (non-SSL) virtual host declaration. Putting it in the global section of the config file may cause looping, as the new URL will match the Redirect requirement and get redirected itself.

Finally, note that if you want the entire site to be available only via SSL, you can accomplish this by simply redirecting all URLs, rather than a particular directory:

Redirect / https://secure.domain.com/

Again, be sure to put that inside the non-SSL virtual host declaration.

You will see various solutions proposed for this situation using RedirectMatch or various RewriteRule directives. There are special cases where this is necessary, but in most cases, the simple solution offered here works just fine.

It it important to understand that this Redirect must appear only in the non-SSL virtual host, otherwise it will create a condition where the Redirect will loop. This implies that you do in fact have the HTTP (non-SSL) site set up as a virtual host. If you do not, you may need to set it up as one in order to make this recipe successful.

Thus, the entire setup might look something like this:

NameVirtualHost *

<VirtualHost *>
    ServerName regular.example.com
    DocumentRoot /www/docs

    Redirect /secure/ https://secure.example.com/secure/
</VirtualHost>

<VirtualHost _default_:443>
    SSLEngine On
    SSLCertificateFile /www/conf/ssl/ssl.crt
    SSLCertificateKeyFile /www/conf/ssl/ssl.key

    ServerName secure.example.com
    DocumentRoot /www/docs
</VirtualHost>

This is, of course, an oversimplified example and is meant only to illustrate the fact that the Redirect must appear only in the non-SSL virtualhost to avoid a redirection loop.

The other two solutions are perhaps more straightforward, although they each have a small additional requirement for use.

The second recipe listed, using SSLRequireSSL, will work only if you are using Apache 2.0. It is a directive added specifically to address this need. Placing the SSLRequireSSL directive in a particular <Directory> section will ensure that non-SSL accesses to that directory are not permitted.

The third recipe, using RewriteCond and RewriteRule directives, requires that you have mod_rewrite installed and enabled. Using the RewriteCond directive to check if the client is already using SSL, the RewriteRule is invoked only if they are not; in which case, the request is redirected to a request for the same content but using HTTPS instead of HTTP.

See Also

    [ Team LiB ] Previous Section Next Section