I have an Apache2 web server (v. 2.2.16) running on Debian hosting three virtual hosts. The first two hosts are HTTP only (server1 and server2). The last host is HTTPS only (server3). My virtual host configuration files can be found at pastebin. I would like to use mod rewrite to get the following behavior:

  • Any request for http://server3 is re-directed to https://server3
  • Any request for either https://server1 or https://server2 is re-directed to http://server1 or http://server2 as appropriate.

Currently, requesting http://server3 gives you a 403 because indexing is disabled for that host and a request for https://server1 or https://server2 will resolve as https://server3 (as its the only virtual host running SSL). This behavior is not desirable.

So far I have added a rewrite rule to the central configuration file (myServerWideConfs.conf), with unfortunately no effect. I was under the impression that this rule (or something similar) should rewrite all https:// requests for server1 and server2 to the proper http:// request.

RewriteEngine On
RewriteCond %{HTTP_HOST} !^server3 [NC]
RewriteRule (.*) http://%{HTTP_HOST}

My question is two-fold:

  • What mod rewrite rules should I use to accomplish this? And where should they go? Debian's packaging of Apache has a pretty granular (i.e., fractured) configuration file layout; should my rewrite rules go in /etc/apache2/apache2.conf, /etc/apache2/conf.d/myServerWideConfs.conf, or the individual virtual host files?
  • Is mod rewrite the right tool to accomplish this or am I missing something in my greater apache configuration?

2 Answers 2


What I do: use vhosts for each site, including a vhost for the variant I want to suppress. This keeps all the configuration for a named site in one place. The duplication of content is minimal thanks to mod_macro.

You want to issue a redirect, not rewrite internally, since the idea is to get the client to retry using the correct protocol. Make sure to only rewrite for GET, since a redirect after POST means data is accepted and you only want to really deal with people using the wrong scheme in their web-browser -- API users should be using the correct interface.


<IfModule mod_rewrite.c>
  <VirtualHost [2001:db8::1234:1]:80>
    ServerName www.example.org
    DocumentRoot /www/sites/empty-stub
    RewriteEngine       on
    RewriteCond %{REQUEST_METHOD} =GET
    RewriteRule ^(.*) https://www.example.org$1 [R,L]

and if you do this a lot, wrap it in a mod_macro <Macro>..</Macro> block so that it becomes:

Use RedirToHTTPS www.example.org
  • That worked perfectly for addressing my issue with redirecting all requests for the HTTPS server that come in as http://server3 to the correct https://server3. Thanks!
    – user5596
    Feb 22, 2011 at 19:15

This is tricky. Historically this wasn't possible since SSL didn't permit indicating which virtual host it was attempting to access as it sets up the connection to the designated IP address. This has changed somewhat with Server Name Indication (RFC 4366), a feature of TLS.

Apache has taken a long time to get support for it, but it now does. Your version is new enough it should support it, but you'll need a browser that also does. Before working on the rewrite stuff, I'd start working on making sure that https://server1.example.com/ returns the right VHost. Once it does that, the Mod-rewrite stuff should just work.

  • Sorry, my ignorance here is greater than my ambition. How exactly do I go about ensuring that all the server1 request return the correct VHosts? If I place another block in the configuration file for *:443, I get an error (default VirtualHost overlap on port 443) and HTTPS requests are still redirected to the wrong vhost. Can you give me some hints on where to start?
    – user5596
    Feb 22, 2011 at 18:51

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.