1

I wonder what is the relationship of ServerName & ServerAlias with host.file. As I know ServerName sets the hostname and port that the server uses to identify itself and ServerAlias is the alternate names for a host. But does the ServerName and ServerAlias need to be identified in host.file? Do we need to put the exact domain name or it can be an alternate name in ServerName or ServerAlias? Let's say my actual domain is www.example.com and I have set up SSL and my website are now run as https+www.example.com, now I'm trying to redirect my website from http+example.com when I type it in the browser and I expect my browser will redirect me to https+www.example.com, what ServerName or ServerAlias should I put in httpd-vhost.conf? Below are my host.file:

127.0.0.1 example.com www.example.com
::1 example.com www.example.com
127.0.0.1 localhost
::1 localhost

Below are my httpd-vhosts.conf:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot "d:/wamp64/www/example"
    <Directory  "d:/wamp64/www/example/">
        Options +Indexes +Includes +FollowSymLinks +MultiViews
        AllowOverride All
        Order allow,deny
        Allow from all
        Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
    </Directory>
</VirtualHost>

Does my definition of ServerName and ServerAlias correct in httpd-vhosts.conf? This is what I put in .htacess to redirect my website from http+example.com to https+ww.example.com but it does not work and I believe it related with my definition of ServerName and ServerAlias:

RewriteCond %{HTTPS} !on 
RewriteCond %{HTTP_HOST} ^example\.com$
RewriteRule .* https://www.example.com%{REQUEST_URI} [R=301,L]

Below is the outcome of my redirection logs:

[perdir D:/wamp64/www/example/] RewriteCond: input='off' pattern='!on' => matched 
[perdir D:/wamp64/www/example/] RewriteCond: input='' pattern='^example\\.com$' => not-matched

This is what I get from Firefox debugger:

Firefox debugger

Update

I've update my .htaccess to below:

RewriteCond %{HTTP_HOST} example.com [NC]
RewriteRule .* https://www.example.com%{REQUEST_URI} [R=301,L]

I update my ServerName in vhost to www.example.com Here's the logs that I got:

example per-dir prefix: D:/wamp64/www/example/index.php/news-and-events/news-and-events/news -> index.php/news-and-events/news-and-events/news
applying pattern '.*' to uri 'index.php/news-and-events/news-and-events/news'
RewriteCond: input='off' pattern='!on' => matched
RewriteCond: input='www.example.com' pattern='example.com' [NC] => matched
rewrite 'index.php/news-and-events/news-and-events/news' -> 'https://www.example.com/index.php/news-and-events/news-and-events/news'
explicitly forcing redirect with https://www.example.com/index.php/news-and-events/news-and-events/news
trying to replace prefix D:/wamp64/www/example/ with /
escaping https://www.example.com/index.php/news-and-events/news-and-events/news for redirect
redirect to https://www.example.com/index.php/news-and-events/news-and-events/news [REDIRECT/301]

Here is what I got from firefox debugger raw header:

GEThttp://example.com/

Request URL:http://example.com/
Request Method:GET

Request Headers (328 B) 
Raw Headers
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 6.1; rv:74.0) Gecko/20100101 Firefox/74.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
DNT: 1
Connection: keep-alive
Upgrade-Insecure-Requests: 1

This is what I get from Microsoft Edge:

General
Request URL: http://example.com/
Referrer Policy: no-referrer-when-downgrade
Request Headers
Provisional headers are shown
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36 Edg/80.0.361.111

Please help and do point me out if I've done anything wrong and thanks in advance!

10
  • Your config looks "OK". Your rule in .htaccess isn't strictly correct - but that isn't the problem here. However, your log entry seems to imply the Host header is missing from the request?! How exactly are you making this request and what URL are you requesting? Please edit your question to include the HTTP request headers being sent (from the browser)?
    – MrWhite
    Commented Apr 7, 2020 at 0:47
  • Hi Mr White, item added! I actually want my website to redirect when I type http+example.com in the browser and it will redirect to https+www.example.com
    – Petri
    Commented Apr 7, 2020 at 0:56
  • The easier and less confusing approach is to split this into multiple VirtualHosts - one for example.com, and one for www.example.com. Then one can always redirect (no need for rewritecond), and the other one can always deliver the actual site. Btw, you can have rewrite-rules directly in your virtualhost, I do not see any reason to put it in an .htaccess file in your example (though it should still work) Commented Apr 7, 2020 at 4:42
  • Related to your question: HTTP_HOST contains the content of the Host header sent by the client when making the request. Neither ServerName nor ServerALias play any role at this. The redirection logs imply said Header was empty when you made that request. Oddly enough this would also imply, that you did not hit your VirtualHost, as it is selected based on the Host header (that was empty). So your redirect only triggered because it was specified in .htaccess. Commented Apr 7, 2020 at 4:48
  • 1
    You've exemplified the output in your screenshot by overtyping the value of the Host header. This is fair enough, however, this is also the value we are trying to debug! Is the value of the Host header in the same format as example.com - all lowercase letters, with a single dot and com tld? In the "Firefox Debugger" you can switch to "Raw header" and copy as text - that would be more useful here.
    – MrWhite
    Commented Apr 7, 2020 at 10:06

1 Answer 1

1

The host file (& how it's not related)

First, you don't need anything in your hosts file if the authoritative DNS for example.com is pointing to the public IP address of your server.

127.0.0.1 example.com www.example.com

This simply overrides the DNS when example.com is used from the same machine. It makes the server to use local loopback instead of the public IP, but in fact you seldom use a website from the server, anyway.

Relationship of ServerName & ServerAlias

It doesn't really matter whether the hostname matched against the Host header is in ServerName or ServerAlias; they are treated the same. It's just that you MUST have a single hostname as the ServerName and list of the other hostnames in the ServerAlias.


This is one of the conditions When not to use mod_rewrite

Your HTTP virtual host doesn't need to have any document root and it doesn't have to read the RewriteRule from the .htaccess, but you can redirect directly from the <VirtualHost> block, preferably using mod_alias instead of mod_rewrite.

Your configuration can be as short as:

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

Then, you can replace the second rewrite condition by adding a separate virtual host (in your httpd-ssl.conf) for non-www HTTPS:

<VirtualHost *:443> 
    ServerName example.com 

    # SSL cert/key headers here

    # This is the correct place for HSTS.
    Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"

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

Now you have eliminated the need for any rewrite rules at all and using .htaccess files in the first place, which makes your configuration both simple and efficient.

5
  • While tihs solution should work, so should the solution the OP has in place (I agree thought that it is not the most elegant one). Care to explain why OPs solution doesn't work? Commented Apr 7, 2020 at 5:20
  • Yes, is another solution but I already did my SSL configuration in httpd-ssl.conf. So if I want to configure everything in vhost, I need to revert everything that I configure earlier and reconfigure it again in vhost. This is why I need help on my .htaccess file or anything that would fix my current problem.
    – Petri
    Commented Apr 7, 2020 at 5:47
  • 2
    You SHOULD revert everything and use the best practice solution suggested in When not to use mod_rewrite and Canonical Hostnames for good reasons, instead of struggling with these mod_rewrite rules. However, I've added a hint on what might be wrong, as requested by @JohannesH. Commented Apr 7, 2020 at 6:31
  • 1
    "I've added a hint on what might be wrong" - The double backslash in the error log is just the way Apache escapes the string before outputting the message in the log file - this is "normal" and not the problem here. However, what is of concern is that according to the log entry RewriteCond: input='' pattern='^example\\.com$, the input string (ie. %{HTTP_HOST}) is empty! That's why it doesn't match and the condition fails. But why is HTTP_HOST seemingly empy?! According to the OPs "screenshot", the Host header appears to be present. (?)
    – MrWhite
    Commented Apr 7, 2020 at 9:57
  • Thanks, @MrWhite. I removed the chapter that was guessing this wrongly. Wouldn't want to spread misinformation, and the mod_alias solution is really THE solution for this. Commented Apr 7, 2020 at 10:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .