35

I have an Apache 2.2 server with an SSL certificate hosting several services that should be only access using SSL.

ie: https://myserver.com/topsecret/ should be allowed while http://myserver.com/topsecret/ should be either denied or, ideally, redirected to https. http://myserver.com/public should not have this restriction, and should work using either http or https.
The decision to allow/deny http is made at the top level directory, and affects all content underneath it.

Is there a directive that can be placed in the Apache config to retrict access in this manner?

DrStalker
  • 6,946
  • 24
  • 79
  • 107

6 Answers6

42

The SSLRequireSSL directive is what you're looking for.

Inside your <VirtualHost>, or at the top level if you're not using virtual hosts:

<Directory /topsecret>
  SSLRequireSSL
</Directory>

Or in .htaccess:

SSLRequireSSL
Thomas
  • 811
  • 1
  • 9
  • 18
  • 1
    Welcome to Server Fault! We really do prefer that answers have content, not pointers to content. This may theoretically answer the question however, [it would be preferable](http://meta.stackexchange.com/q/8259) to include the essential parts of the answer here, and provide the link for reference. Thank you! – Chris S Apr 11 '13 at 18:41
  • 10
    Ok, I've updated my five-year-old post with an example :) – Thomas Jul 01 '13 at 17:55
  • 1
    To be fair, 5 years old or not, the reasoning is that the link you point to might disappear, making your answer mostly or completely useless to somebody coming along looking for the information later. So I actually voted your snarky comment up (honest), but I also totally agree that the answer should have some context so that it remains useful. Especially since it's marked as the correct answer. – Craig Tullis May 22 '15 at 20:52
  • I don't think the SO/SF community was as strict about just-a-link and "lmgtfy" answers back then. But I agree; a retroactive edit makes sense at any time. – Thomas May 26 '15 at 18:11
  • To what configuration file would I add that directive statement? – dan carter Aug 01 '16 at 11:33
  • Good question. Updated. – Thomas Aug 01 '16 at 11:50
8

In the global configuration you could use:

<IfModule mod_rewrite.c>
   RewriteEngine On
   RewriteCond %{HTTPS} !on
   RewriteRule .* https://%{HTTP_HOST}/%{REQUEST_URI} [R=301,L,QSA]
</IfModule>

Similarly you could use a .htaccess file in the first directory of the secure directory tree:

<IfModule mod_rewrite.c>
   RewriteEngine On
   RewriteCond %{HTTPS} !on
   RewriteRule .* https://%{HTTP_HOST}/%{REQUEST_URI} [R=301,L,QSA]
</IfModule>

That last one could also be placed inside a directory directive in the global or virtual host configuration.

Chris S
  • 77,945
  • 11
  • 124
  • 216
2

Someone mentioned SSLRequireSSL but I don't think it works by itself and I haven't found a successful example with it. The recommended way is https://wiki.apache.org/httpd/RedirectSSL I've applied that and it works well!

Robert
  • 261
  • 3
  • 8
1

Alternatively, you could use the server-side language to do the processing for you, rather than using Apache's configuration options (if, perhaps, you don't have access to the server's configuration).

For example, with PHP:

if (!isset($_SERVER['HTTPS'])) {
  // put your redirect here
  header('Location: http://myserver.com/public');
}

(though just be aware - if you're using ISAPI on Microsoft IIS, if the request is not being routed through HTTPS, then the value of the $_SERVER['HTTPS'] variable will be "off")

Magsol
  • 93
  • 1
  • 1
  • 9
0

Assuming you are using VirtualHost directives,

Place a Directory directive in the non-ssl virtualhost denying access.

Then, place a Directory directive in the ssl virtualhost granting access.

0

I've always done this mod_rewrite in an .htaccess file, though you should be able to do it within your main config file as well.

Here's a guide with a few ways of making this happen: Smart HTTP and HTTPS RewriteRule Redirects