Forum Moderators: phranque

Message Too Old, No Replies

Redirecting non-www to www and http to https

Redirecting non-www to www and http to https with Lets Encrypt

         

elvang

4:32 am on Apr 25, 2022 (gmt 0)

Top Contributors Of The Month



Hi,
I have already installed Lets Encrypt. And i want to be sure that i redirected non-www traffic to www domain. Now my virtual host conf file looks like below. My question is:

1-Do i need to do any change or should i add some codes to virtual host config file like:

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


OR

RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [L,NE,R=301]


OR


<VirtualHost *:80>
ServerName www.example.com
Document Root /var/www/html/example.com/public_html
</VirtualHost>

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



My virtual host:

RewriteCond %{SERVER_NAME} =www.example.com_html>
Require all granted
</Directory>
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
ServerName www.example.com
ServerAlias example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html/example.com/public_html

# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn

ErrorLog /var/www/html/example.com/log/error.log
CustomLog /var/www/html/example.com/log/access.log combined
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
RewriteEngine on
RewriteCond %{SERVER_NAME} =example.com [OR]
RewriteCond %{SERVER_NAME} =www.example.com
RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [END,NE,R=permanent]
</VirtualHost>

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet

phranque

6:35 am on Apr 25, 2022 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



Redirect permanent / http://www.example.com/

you should not use any mod_alias redirection directive since these will conflict with the mod_rewrite directives that you must also necessarily have.
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)$ [NC]
RewriteRule ^ https://www.%1%{REQUEST_URI} [L,NE,R=301]

i would use this instead:
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^(www\.example\.com)? [NC]
RewriteRule ^(.*)$ https://www.example.com$1 [L,R=301]

note that if this is contained within the virtual host configuration for a specific port, you don't need to test the %{HTTPS} value since it is already known at that point.

note that you will have to configure virtual hosts and redirects for all combinations of www/non-www and http/https.
in other words, you will also need to configure those hostnames so they are listening on the secure port as well.

elvang

8:51 am on Apr 25, 2022 (gmt 0)

Top Contributors Of The Month



Hi pranque,

My server is open to 80,443,53 and 22 ports as far as i remember. I will host a website in this virtual host. In this case, to redirect all traffic to htpps://www domain, the last code you added is enough? If it is not enough what else should i add?

Thank you.

w3dk

10:58 am on Apr 25, 2022 (gmt 0)

10+ Year Member Top Contributors Of The Month



you should not use any mod_alias redirection directive since these will conflict ....


Except in the vHost for port 80, as @elvang would seem to be suggesting.


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


The mod_rewrite directives would then only be needed in the vHost for port 443 (assuming both www and non-www are served from the same vHost. Otherwise, if you have a separate vHost for the canonical hostname only then a simpler mod_alias "Redirect" would be preferred for these canonical redirects).

elvang

11:44 am on Apr 25, 2022 (gmt 0)

Top Contributors Of The Month



Thank you @phranque and @w3dk but i couldnt get what should i write to direct all domain variants' (non www, http) traffic to https://www .



[edited by: not2easy at 1:16 pm (utc) on Apr 25, 2022]
[edit reason] unlinked for readability [/edit]

not2easy

1:21 pm on Apr 25, 2022 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



what should i write to direct all domain variants' (non www, http) traffic to https://www .

That is the part handled by the line:
 RewriteRule ^(.*)$ https://www.example.com$1 [L,R=301]

elvang

1:54 pm on Apr 25, 2022 (gmt 0)

Top Contributors Of The Month



thank u @not2easy

phranque

10:23 pm on Apr 25, 2022 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



My server is open to 80,443,53 and 22 ports as far as i remember.

in your case, only ports 80 and 443 are relevant to the web server.
I will host a website in this virtual host. In this case, to redirect all traffic to htpps://www domain, the last code you added is enough? If it is not enough what else should i add?

normally you would prefer to do the non-https/non-www request redirect in one step, but if you are planning to implement hstspreload [hstspreload.org] you must do this in two separate redirects:
Redirect from HTTP to HTTPS on the same host, if you are listening on port 80.

this means redirecting in a 301 chain like this:
http://example.com > https://example.com > https://www.example.com

phranque

10:33 pm on Apr 25, 2022 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



The mod_rewrite directives would then only be needed in the vHost for port 443 (assuming both www and non-www are served from the same vHost. Otherwise, if you have a separate vHost for the canonical hostname only then a simpler mod_alias "Redirect" would be preferred for these canonical redirects).

if you are using mod_rewrite anywhere (such as a WP site or pretty much any CMS) you should avoid mod_alias (Redirect[Match]) everywhere.
see this for why:
https://httpd.apache.org/docs/current/rewrite/avoid.html#redirect
The use of RewriteRule to perform this task may be appropriate if there are other RewriteRule directives in the same scope. This is because, when there are Redirect and RewriteRule directives in the same scope, the RewriteRule directives will run first, regardless of the order of appearance in the configuration file.


in other words, your internal CMS urls would get exposed by the canonical hostname redirect.

Redirect / https://www.example.com/

in any case this type of redirect should be Permanent (i.e., a 301 status code response)

(also, see the HSTS advisory mentioned above, which may prevent this implementation since it would redirect a non-secure/non-www request to a different hostname)

Sgt_Kickaxe

4:56 pm on Apr 26, 2022 (gmt 0)



One other thing to keep in mind when redirecting for both HTTPS and WWW is to make sure the first redirect goes to the secure version. If it's not HTTPS make sure it gets HTTPS before anything else is modified. If you take someone from http:example.com to http:www.example.com and then to HTTPS you may start seeing security warnings on some browsers.

You may be unable to validate Strict Transport Security protocol if you take them from http://example.com to https://www.example.com (2 changes at once) - order matters.

read: [https.cio.gov...]

elvang

11:46 am on Apr 27, 2022 (gmt 0)

Top Contributors Of The Month



Hello, @Sgt_Kickaxe and @phranque i am not planning to implement hstspreload.org. And i am planning to take Phranque's advice about mod_allias redirection and Sgt_Kickaxe's advice about Strict Transport Security rules. By taking all those things into consideration, to redirect all domain variant's to https://www, my apache.conf file will look like this (i think this is the right one according to your advices):


RewriteCond %{SERVER_NAME} =www.example.com_html>
Require all granted
</Directory>
<VirtualHost *:80>
# The ServerName directive sets the request scheme, hostname and port that
# the server uses to identify itself. This is used when creating
# redirection URLs. In the context of virtual hosts, the ServerName
# specifies what hostname must appear in the request's Host: header to
# match this virtual host. For the default virtual host (this file) this
# value is not decisive as it is used as a last resort host regardless.
# However, you must set it for any further virtual host explicitly.
ServerName www.example.com
ServerAlias example.com
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html/example.com/public_html

# Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
# error, crit, alert, emerg.
# It is also possible to configure the loglevel for particular
# modules, e.g.
#LogLevel info ssl:warn

ErrorLog /var/www/html/example.com/log/error.log
CustomLog /var/www/html/example.com/log/access.log combined
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
# For most configuration files from conf-available/, which are
# enabled or disabled at a global level, it is possible to
# include a line for only one particular virtual host. For example the
# following line enables the CGI configuration for this host only
# after it has been globally disabled with "a2disconf".
#Include conf-available/serve-cgi-bin.conf
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^(www\.example\.com)? [NC]
RewriteRule ^(.*)$ https://www.example.com$1 [L,R=301]

# vim: syntax=apache ts=4 sw=4 sts=4 sr noet




[edited by: not2easy at 12:25 pm (utc) on Apr 27, 2022]
[edit reason] delinked for readability [/edit]

phranque

9:02 pm on Apr 27, 2022 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



i am not planning to implement hstspreload.org. And i am planning to take ... Sgt_Kickaxe's advice about Strict Transport Security rules

if you are not implementing hstspreload, you don't need STS rules.
RewriteCond %{SERVER_NAME} =www.example.com_html>
...
</Directory>

not sure if this was a typo, but this directive in this location does nothing.
<VirtualHost *:80>
...
RewriteCond %{HTTPS} off [OR]
...

in a virtual host container that specifies port 80, it may be assumed that %{HTTPS} is "off", so this directive is superfluous.

i don't see anything that will redirect https://example.com/ (i.e. a canonical hostname redirect for port 443)

phranque

9:12 pm on Apr 27, 2022 (gmt 0)

WebmasterWorld Administrator 10+ Year Member Top Contributors Of The Month



 Document Root /var/www/html/example.com/public_html

i just noticed this typo:
Document Root
should be:
DocumentRoot