skip to Main Content

I make following post on redirection of https://www.website.com to https://website.com :

Issue with Let's Encrypt certificate : https://www.website.com not working with redirection to https://website.com

I can’t get to achieve this redirection and I don’t understand what is the reason.

If I type https://www.website.com, it remains on https://www.website.com and doesn’t perform the redirection to https://website.com.

My config is a little special with a Zope server working with Apache2.

For the moment, here below are my rewrite rules (http://www.website.com and http//website.com are both redirected fine to https://website.com) :

<VirtualHost *:443>

    # REWRITE to get https://www.website.com to https://website.com except for cgi-bin scripts
    RewriteEngine On
    RewriteCond %{REQUEST_URI} !^/cgi-bin/search [NC]
    RewriteCond %{REQUEST_URI} !^/cgi-bin/awstats [NC]
    RewriteRule ^/(.*)  https://localhost:8443/++vh++https:%{SERVER_NAME}:443/++/$1 [P,L]

</VirtualHost>

<VirtualHost *:80>

<IfModule mod_rewrite.c>

# www to non www for HTTP and HTTPS
RewriteCond %{REQUEST_URI} ^/www. [NC,OR]
RewriteCond %{REQUEST_URI} !^/podcast [NC]
# Rewrite below works : redirect 80 => https
RewriteRule ^/(.*) https://website.com/$1 [R=301,L]

RewriteRule ^/(.*)  http://localhost:9674/++vh++http:%{SERVER_NAME}:80/++/$1 [P,L]

</IfModule>

</VirtualHost>

What could be wrong here?

2

Answers


  1. I believe there are few things of note:

    1. One or more RewriteCond can precede a RewriteRule directive. The following rule is then only used if both the current state of the URI matches its pattern, and if these conditions are met.

    2. The RewriteRule directive……can occur more than once, with each instance defining a single rewrite rule. The order in which these rules are defined is important – this is the order in which they will be applied at run-time.

    3. In VirtualHost context, The Pattern will initially be matched against the part of the URL after the hostname and port, and before the query string (e.g. "/app1/index.html"). This is the (%-decoded) URL-path.

    4. If you wish to match against the hostname, port, or query string, use a RewriteCond with the %{HTTP_HOST}, %{SERVER_PORT}, or %{QUERY_STRING} variables respectively.

    You also make use of L|last flags, which makes the engine stop processing further rules after RewriteRule is run.

    The above sorta gives you an idea how the engine runs your rewrites:

    1. RewriteRules are processed sequentially (unless you specify L flag, which you do for all rules)
    2. Each RewriteRule can have many RewriteCond which all must match before RewriteRule is considered. It also means that RewriteCond must be repeated for each RewriteRule individually (there’s however an interesting technique to group RewriteRules into if-then-else blocks)
    3. In your case (VirtualHost context), only the URL-paths are matched by default unless you manually match HTTP_HOST variable.

    With this in mind, I see a few issues with your rewrite rules (I swapped http and https vhosts around for readability but it does not matter):

    <VirtualHost *:80> <!-- your http:// requests will end up with this block, because 80 is the port for http -->
    <IfModule mod_rewrite.c>
        # www to non www for HTTP and HTTPS <!-- I believe HTTPS traffic is NOT handled by this vhost at all, it arrives straight to *:443 queue -->
        RewriteCond %{REQUEST_URI} ^/www. [NC,OR] <!-- you evaluate path component of your request uri to begin with "www." (i.e. /www.index.html) - this will obviously never match, you however have OR flag, which proceeds to the second condition -->
        RewriteCond %{REQUEST_URI} !^/podcast [NC] <!-- you check if the path does not start with "/podcast" - this is easy to test - try http://www.website.com/podcast and see if you get redirected to HTTPS - I suspect you will not -->
        # Rewrite below works : redirect 80 => https <!-- I suspect it works by accident, please test it out with http://www.website.com/podcast to confirm my theory -->
        RewriteRule ^/(.*) https://website.com/$1 [R=301,L] <!-- we end up here, and regardless of the requested path we issue a 301 redirect to https version of the website. This is marked as Last rule, so the engine should stop processing here -->
        RewriteRule ^/(.*)  http://localhost:9674/++vh++http:%{SERVER_NAME}:80/++/$1 [P,L] <!-- this I believe kicks in when you request a "/podcast" path - this will proxy the request to your http://localhost:9674/ -->
    </IfModule>
    </VirtualHost>
    
    <VirtualHost *:443><!-- this is where your 301 redirect will com after bouncing through first set of rules above -->
        # REWRITE to get https://www.website.com to https://website.com except for cgi-bin scripts
        RewriteEngine On <!-- this is important, keep it on -->
        RewriteCond %{REQUEST_URI} !^/cgi-bin/search [NC] <!-- you check whether url path does not contain /cgi-bin/search -->
        RewriteCond %{REQUEST_URI} !^/cgi-bin/awstats [NC]<!-- AND does not contain /cgi-bin/awstats-->
        RewriteRule ^/(.*)  https://localhost:8443/++vh++https:%{SERVER_NAME}:443/++/$1 [P,L]<!-- if both conditions above are met - proxy the request to backend and stop further processing. -->
    </VirtualHost>
    

    As far as I see – there’s no rule to rewrite https://www.website.com -> https://website.com, the only bit your https rewrite is checking is /cgi-bin

    My suggestion would be along the following lines (it’s probably not a copy and paste solution, but hopefully you will have gotten the gist):

    <VirtualHost *:443>    
        RewriteEngine On
        # www to non www for HTTPS
        <!-- checking for the same thing again -->
        RewriteCond %{HTTP_HOST} ^www.(.+) [NC]
        RewriteRule ^/(.*) https://website.com/$1 [R=301,L] <!-- some people might argue second redirect here is excessive since you already arrived at correct host, but I'd leave this for you to sort out -->
        <!-- your /cgi-bin checks can be merged into one regex --> 
        RewriteCond %{REQUEST_URI} !^/cgi-bin/(search|awstats) [NC]
        RewriteRule ^/(.*)  https://localhost:8443/++vh++https:%{SERVER_NAME}:443/++/$1 [P,L]
    </VirtualHost>
    
    <VirtualHost *:80>
    <IfModule mod_rewrite.c>
        # www to non www for HTTP
        <!-- if you want to keep your `/podcast` on http check it first -->
        RewriteCond %{REQUEST_URI} !^/podcast [NC]
        RewriteRule ^/(.*)  http://localhost:9674/++vh++http:%{SERVER_NAME}:80/++/$1 [P,L]
        <!-- everything else will get redirected to https -->
        RewriteCond %{HTTP_HOST} ^www.(.+) [NC]
        RewriteRule ^/(.*) https://website.com/$1 [R=301,L]
    </IfModule>
    </VirtualHost>
    
    Login or Signup to reply.
  2. I had the same problem, for only one website of many that were virtually hosted on a amazon lightsail bitnami implementation.

    After commenting out the line

    ServerName mywebsite.com:80
    

    In the /opt/bitnami/apache2/conf/httpd.conf file the problem was sovled.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search