RewriteCond -- cannot get http or https to add "www" to url

I'm new to Linode and have ran into a few issues setting up my new server as it has been a while since I have done any server work. I believe I finally got https to work with Let's Encrypt, but am having some issues with my RewriteCond.

When I type mydomain.com, it successfully goes to www.mydomain.com (and is https with my new certificate).

When I type http://mydomain.com, it moves to https://mydomain.com, but doesn't add the "www." to the url.

I have the following in both my mydomain.conf and mydomain-le-ssl.conf files

# Enable RewriteEngine
RewriteEngine on
RewriteOptions inherit

# Block .svn, .git
RewriteRule \.(svn|git)(/)?$ - [F]

# Catchall redirect to www.mydomain.com
RewriteCond %{HTTP_HOST}   !^www\.mydomain\.com [NC]
RewriteCond %{HTTP_HOST}   !^$
RewriteRule ^/(.*)         https://www.mydomain.com/$1 [L,R]

Thanks!

14 Replies

I tried your redirect rules in my mydomain-le-ssl file and this worked for me. (I did omit the 'Rewrite Options' line however, as I am not familiar with it.)

This may be working and you just don't realize it. Most browsers will hide the 'www' portion in the URL bar automatically.

Try doing curl -IL http://mydomain.com to follow redirects and see what is happening.

Thank you for the response @hphillips. I have tried again and it seems to be working now (perhaps it took a second to update or was cached?).

I found the instructions for the Rewrite in this guide:
https://www.linode.com/docs/guides/configure-apache-to-run-multiple-wordpress-sites-on-one-linode/

Sometimes I feel like it takes a second before resolving the webpage.
Could you help me understand what these rewrite options are doing? I'm having a hard time finding an explanation for this code. Perhaps there is an error in it?

I'm having a hard time finding an explanation for this code.

RewriteCond %{HTTP_HOST}   !^www\.mydomain\.com [NC]

This specifies that the next rewrite rule applies where the HTTP hostname (the bit in the URL after https:// and before the first /) does not equal www.mydomain.com.

[NC] is a flag that is applied to the rule. In this case, it ignores the case, so WWW.MYDOMAIN.COM will still match the rule.

RewriteCond %{HTTP_HOST}   !^$

This specifies that the next rewrite rule applies where the HTTP hostname is not empty. ^$ is a regular expression - ^ is the start of the string, and $ is the end of the string. So this regular expression will match an empty string.

RewriteRule ^/(.*)         https://www.mydomain.com/$1 [L,R]

Finally, this rewrites any URL (that matches the above 2 conditions) and maintains the path in the original URL.

For example: https://mydomain.com/my-test-path will become https://www.mydomain.com/my-test-path.

[L,R] are 2 more flags that tell Apache to issue a 302 redirect so the browser sees the new URL (R), and to stop processing any more rewrites for this request (L).

Thank you, @andysh! This is helpful.

In the original example that I based my code after, they only had "!^www.example1.com [NC]" with one \ and without the \ after "www"

I added the other slash based on another example, could you help me understand the difference?

I still don't have a great understanding of this, but your explanation is helping! Does my rewrite make sense? I have this code in both the mydomain.conf and mydomain-le-ssl.conf files.

I also wasn't sure about the inherit line and svn|git rule.

I added the other slash based on another example, could you help me understand the difference?

Sure!

In a regular expression, a "." matches any character. A backslash quotes the "." so it matches just a dot.

For example:

!^www.mydomain.com

would match www.mydomain.com, but it would also match wwwamydomainbcom.

However:

!^www\.mydomain\.com

would match www.mydomain.com and only that.

I also wasn't sure about the inherit line and svn|git rule.

I've never seen the inherit line before.

RewriteRule .(svn|git)(/)?$ - [F]

This rule, however, is another regular expression. Because there is no ^ (start of string) character, it will match anywhere in the string.

It is saying to match any request where the URL contains a string starting with a ".", followed by either svn or git - common folders used by the SVN and Git source control systems - followed by a "/" character (the ? makes it optional) that appears at the end of the string.

This would match:

The [F] is another flag that tells Apache to forbid the request - i.e. prevent someone from accessing the .git or .svn folder anywhere in your website's directory structure.

Personally, I would probably drop the $ character, as (I think) the above rule as it is would allow access to files within .git, such as the repository config file, for example:

www.example.com/.git/config

This is very helpful @andysh

I just checked the .git|.svn with the $ and you are correct, I was able to enter directories after the .git or .svn folder and got a 404. After removing the $, I got a 403 Forbidden for directories after the .git or .svn directory.

The inherit line seems to be something about inheriting settings from the parent .htaccess. Would I want that?

Between the following:

 !^www.mydomain.com

and

 !^www\.mydomain\.com 

what would you recommend?

The inherit line seems to be something about inheriting settings from the parent .htaccess. Would I want that?

That would make sense. Maybe so you could have rewrite rules for mydomain.com/folder, but then also include the rewrite rules from the main server.

what would you recommend?

Personally I would always include the backslash so it would only include the “.”. That way it closes a theoretically loophole where someone could register wwwamydomain.com, point it to your IP and cause your own Linode to unintentionally serve an insecure version of your website.

Thanks @andysh

And interesting! (I also just realized the way I had my question formatted in my last post, one couldn't see the two backslashes. Sorry about that. I have edited it above to show them).

So you are saying the following is more secure as it only matches "www.mydomain.com" and no other combination:

 !^www\.mydomain\.com       

Do I need both backslashes?

So you are saying the following is more secure as it only matches "www.mydomain.com" and no other combination:

Yes, exactly. The only hostname that will not be redirected to HTTPS is www.mydomain.com, so any other traffic that hits your IP that is not www.mydomain.com will be redirected to HTTPS.

Do I need both backslashes?

Yes, the backslash escapes the character immediately after it, and you want both of the "." to behave like "." instead of "any character".

Ah, that is helpful about the backslash and why I would want both.

I'm sorry, but I'm still struggling with the statement you said about www.mydomain.com not redirecting to HTTPS whereas any other traffic that isn't www.mydomain.com being redirected to HTTPS. Would I want my www.mydomain.com to be HTTPS? (I feel like I'm missing some obvious detail here and thank you so much for your patience!).

Would I want my www.mydomain.com to be HTTPS?

Sorry, my bad, I’ve got confused. I thought these rules were redirecting HTTP traffic to HTTPS as the RewriteRule sends traffic to https://…

I’ve just realised they’re not, they’re redirecting non-www traffic to www.

However my original comment still stands; you’d still want the backslashes in. The idea being that anything that hits your IP that is not www.mydomain.com, would get redirected to https://www.mydomain.com…

Apologies for confusing you.

No worries and you have been very helpful @andysh !

I have a certificate via Let's Encrypt for my domain. Are these rewrite rules doing both the add www to non-www traffic and adding https:// ? or is the https:// happening some other way? (new to getting my own certificate). If I didn't have any of these rewrite rules, how would my domain know to push traffic to the https:// ?

Are these rewrite rules doing both the add www to non-www traffic and adding https:// ?

Yes and no.

If a request hit http://www.example.com, it wouldn't hit the rewrite rule as the host does match www.example.com, and your RewriteCond excludes it from being rewritten (the "!" character at the beginning.)

If a request hit http://example.com, it would hit the rewrite rule, which redirects it to https://www.example.com, according to your RewriteRule line.

However I do believe Let's Encrypt adds a rewrite rule into the -le-ssl.conf file that rewrites HTTP to HTTPS.

If I didn't have any of these rewrite rules, how would my domain know to push traffic to the https:// ?

It wouldn't unless it had previously accessed your site and received a 301 redirect from HTTP to HTTPS, or you had configured HSTS and your browser had connected to your site previously.

Thank you @andysh

When I go to http://mydomain.com, it adds the https://www. to the URL. Perhaps that is something that Let's Encrypt adds in the ssl.conf that you mentioned? Is there a way to check that?

Based on our conversation, it sounds like the changes I've made are working and these changes are doing the following three things:

  • making sure people cannot access .git or .svn areas
  • pushes all non-www traffic to www
  • pushes all http:// traffic to https://

Am I missing something else? or is there something else to check/configure? Where can I confirm the Let's Encrypt HTTP to HTTPs part? Or does that matter since it appears to be working? (I like learning and knowing what causes things instead of it just working).

Reply

Please enter an answer
Tips:

You can mention users to notify them: @username

You can use Markdown to format your question. For more examples see the Markdown Cheatsheet.

> I’m a blockquote.

I’m a blockquote.

[I'm a link] (https://www.google.com)

I'm a link

**I am bold** I am bold

*I am italicized* I am italicized

Community Code of Conduct