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
|