-1

I need to redirect all for example.com to https://www.example.com with HSTS turned on. How to do it? I got configuration in vhost80 and vhost443. What to fix in this code:

in vhost 80

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

in vhost 443

RewriteCond %{HTTP_HOST} ^example.com$ [NC]
RewriteRule (.*) https://www.example.com$1 [R=301,L]
MrWhite
  • 12,647
  • 4
  • 29
  • 41
Kamil Bu
  • 9
  • 4

2 Answers2

0

Assuming you have just two vHost containers. One for port 80 and handles requests to both example.com and www.example.com only and the other for port 443 that again handles both example.com and www.example.com only. Then...

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

You simply need to remove all the conditions, only the RewriteRule directive is required. For example:

RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [END,NE,R=permanent]

You also need to ensure you redirect to the same hostname, hence the use of HTTP_HOST, not SERVER_NAME. (Although, by default, SERVER_NAME is the same as HTTP_HOST - but this depends on the UseCanonicalName directive in your server config.)

The rule in the vHost 443 container looks "OK".

However, best practise would avoid the use of mod_rewrite altogether... create a separate vHost for each hostname and use the simpler mod_alias Redirect directive instead.

MrWhite
  • 12,647
  • 4
  • 29
  • 41
  • So, does not HTTP_HOST redirect AliasName also? You mentioned to use separated hostname files for example and www.example domains? In last example ```RewriteRule ^ https://%{HTTP_HOST}%{REQUEST_URI} [END,NE,R=permanent]``` how to add here also servername.example.com ? – Kamil Bu Apr 13 '20 at 12:38
0

For completeness, here's the simpler mod_alias alternative suggested by MrWhite. This also has the HSTS headers in the correct place and, as recommendable, subdomains included & with preloading. First the three redirecting virtual hosts and then the actual virtual host serving content.

<VirtualHost *:80>
    ServerName example.com
    Redirect permanent / https://example.com/
</VirtualHost>

<VirtualHost *:80>
    ServerName www.example.com
    Redirect permanent / https://www.example.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName example.com
    Redirect permanent / https://www.example.com/

    # The mandatory SSL* directives.

    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</VirtualHost>

<VirtualHost *:443>
    ServerName www.example.com
    DocumentRoot /var/www/html

    # The mandatory SSL* directives.
    # . . . whatever else you may have here

    Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains; preload"
</VirtualHost>

Naturally, this requires both mod_alias and mod_headers loaded. Wrapping the Header directives inside <IfModule> sections would avoid errors on missing mod_headers module, but then you would not have HSTS enabled, and this was titled as redirection with HSTS.


The two <VirtualHost *:80> blocks are there because:

  • there's a limitation: you can't use the variable %{SERVER_NAME} with Redirect.
  • with HSTS it's recommended to redirect first to the HTTPS and then to the canonical name.

For the wildcard *.example.com redirection I'd add a ServerAlias to the VirtualHosts *:80 redirecting first to the domain apex and then again there on the HTTPS. As the www is included in the *.example.com, you won't even need the additional <VirtualHost *:80> for it:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias *.example.com
    Redirect permanent / https://example.com/
</VirtualHost>

<VirtualHost *:443>
    ServerName example.com
    ServerAlias *.example.com
    Redirect permanent / https://www.example.com/
    . . .

This way the user...

  1. Enters URL http://anysub.example.com/.
  2. Gets redirected to https://example.com/ (or is already on the same configuration, if entered https://anysub.example.com/, or if the HSTS policy is already in the cache).
  3. Sees the HSTS header, protecting all (*.)*.example.com including anysub.example.com.
  4. Gets finally redirect to the canonical https://www.example.com/.
Esa Jokinen
  • 46,944
  • 3
  • 83
  • 129
  • SO as i understand, its better to use 2 times VH direction not AliasName? – Kamil Bu Apr 13 '20 at 12:41
  • And what about ```*.example.com``` wildcard redirection ? – Kamil Bu Apr 13 '20 at 12:42
  • As this would have been too complex to answer in the comments, I've answered both these questions on my edit. – Esa Jokinen Apr 13 '20 at 13:01
  • Another question, how can i test it from my server or web? I use this page: ```https://httpstatus.io/ ``` and it shows http to https redirect first and than to httpswww. As i understand, with HSTS it seems ok. How can i also test it if HSTS is working propably and redirections too. At this moment i do not use mod_alias just redirect rule without conditions. But i want to test it and learn how to do it and how it works. curl ? – Kamil Bu Apr 13 '20 at 13:31
  • The `Redirect` is a directive from mod_alias, so by using it you are using mod_alias. You could test the responses with `curl`, and the browser behavior regarding HSTS with the developer tools in the browser. – Esa Jokinen Apr 13 '20 at 14:14