Home > Blockchain >  How to redirect all server aliases and www to SSL non www in .htaccess
How to redirect all server aliases and www to SSL non www in .htaccess

Time:05-25

Looking for a way to redirect several server aliases (both www and non-www) to one non-www domain with forced SSL using Apache VirtualHosts and .htaccess. I've been searching for a while now and have found several solutions but they all work partially.

The situation is as follows, in my .conf file I have a virtual host specified as follows:

<VirtualHost *:443>

        ServerName example.domain
        ServerAlias *.example.domain *.exampledomain.com exampledomain.com

        ...

</VirtualHost>
<VirtualHost *:80>

        ServerName example.domain
        ServerAlias *. example.domain *.exampledomain.com exampledomain.com

        RewriteEngine on

        RewriteCond %{SERVER_NAME} =www.example.domain [OR]
        RewriteCond %{SERVER_NAME} =example.domain
        RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]

</VirtualHost>

Next, I have the following in my .htaccess:

        RewriteEngine On
        Options  FollowSymlinks

        RewriteBase /

        RewriteCond %{HTTPS} off
        RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

        RewriteCond %{HTTP_HOST} ^www.exampledomain.com$ [OR]
        RewriteCond %{HTTP_HOST} ^exampledomain.com$ [OR]
        RewriteCond %{HTTP_HOST} ^www\.example\.domain$
        RewriteRule ^(.*)$ https://example.domain/$1 [L,R=301]

Result is as follows:

http://example.domain/          -> https://example.domain/ - (correct)
http://www.example.domain/      -> https://example.domain/ - (correct)

http://exampledomain.com/       -> http://exampledomain.com/ - Forbidden, you dont have access...
http://www.exampledomain.com/   -> http://www.exampledomain.com/ - Forbidden, you dont have access...

https://exampledomain.com/      -> https://example.domain/ - (correct)
https://www.exampledomain.com/  -> https://www.exampledomain.com/ - Connection not secure

I really can't figure out where this goes wrong and why some redirects work and others don't. Any hints would be much appreciated.

CodePudding user response:

If you have access to the <VirtualHost> then you don't need to (should not) use .htaccess at all for this.

If the goal is to redirect to the canonical domain ( HTTPS) in a single redirect using just the two vHosts as defined then all you need is:

<VirtualHost *:443>
    ServerName example.domain
    ServerAlias *.example.domain *.exampledomain.com exampledomain.com

    RewriteEngine On

    # Redirect everything other than the canonical host to the canonical host
    RewriteCond %{HTTP_HOST} !=example\.domain
    RewriteRule ^ https://example.domain%{REQUEST_URI} [R=301,L]
</VirtualHost>

<VirtualHost *:80>
    ServerName example.domain
    ServerAlias *.example.domain *.exampledomain.com exampledomain.com

    # Unconditionally redirect everything to HTTPS   canonical host
    Redirect 301 / https://example.domain/
</VirtualHost>

The mod_alias Redirect directive is prefix matching and everything after the match is appended to the end of the target URL. So, the Redirect directive above redirects every URL to the same URL at the target.

You should test first with 302 (temporary) redirects and only change to a 301 (permanent) once you have confirmed it works as intended. You will likely need to clear your browser cache since 301s are cached persistently by the browser.


A look at your "results":

http://exampledomain.com/       -> http://exampledomain.com/ - Forbidden, you dont have access...
http://www.exampledomain.com/   -> http://www.exampledomain.com/ - Forbidden, you dont have access...

The current HTTP to HTTPS redirect in the vHost:80 container is only redirecting www.example.domain and example.domain and you probably aren't accepting requests in the vHost:80 container, so any HTTP request (that is not redirected to HTTPS) is probably blocked.

https://www.exampledomain.com/  -> https://www.exampledomain.com/ - Connection not secure

Your SSL cert needs to cover all domains and all aliases, otherwise, you will (at best) get a browser SSL cert warning and the browser will refuse to connect to your server (so does not see the redirect).

  • Related