Fallback - redirect to a new domain using apache vhost configuration - apache

This is a followup question on https://stackoverflow.com/posts/47547418
I wanted my requests from
somedomain.com/loadproduct?product=dell-inspiron-15
to be selectively redirected to
someotherdomain.com/dell-inspiron-15
but at the same time I want to make sure if something goes wrong with the new domain, users are still able to use old domain by adding /old in the url.
For example if users uses
somedomain.com/old/loadproduct?product=dell-inspiron-15
then they should not be redirected to someotherdomain but should be served through a valid url somedomain.com/loadproduct?product=dell-inspiron-15
but if they use
somedomain.com/loadproduct?product=dell-inspiron-15
they should be redirected.
Currently my vhost configuration looks like below. It redirects to someotherdomain for selected products but there is no fallback configuration.
Listen 12567
NameVirtualHost *:12567
<VirtualHost *:12567>
ServerName somedomain.com
ProxyPreserveHost On
RewriteEngine On
RewriteCond %{QUERY_STRING} (?:^|&)product=(Dell-Inspiron-15) [NC,OR]
RewriteCond %{QUERY_STRING} (?:^|&)product=(Dell-Inspiron-16) [NC,OR]
RewriteCond %{QUERY_STRING} (?:^|&)product=(Dell-Inspiron-17) [NC]
RewriteRule ^/?loadproduct$ http://someotherdomain.com/%1? [R=301,L,NC]
</VirtualHost>
Any leads here is really appreciated.

Modify your RewriteCond conditions and add one where it says not to accept /old/ in the path (URI). So:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^.*/old/.*$ [NC]
RewriteCond %{QUERY_STRING} (?:^|&)product=(Dell-Inspiron-15) [NC,OR]
RewriteCond %{QUERY_STRING} (?:^|&)product=(Dell-Inspiron-16) [NC,OR]
RewriteCond %{QUERY_STRING} (?:^|&)product=(Dell-Inspiron-17) [NC]
RewriteRule ^/?loadproduct$ http://someotherdomain.com/%1? [R=301,L,NC]
In the first line, no need to specify [AND], as it is implicit. The ! character negates the match.
Disclaimer: I have not tested this on a real Apache, but I am pretty sure it is ok.

Related

How can I direct all folders on my website to use HTTPS in .htaccess?

Please be kind, this is my first question on here :)
My Setup
Apache served on my Raspberry Pi 4
My .htaccess file
# Force HTTPS on all pages
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI} [R=301,L]
</IfModule>
The Problem
Typing in "tyler.cloud" successfully redirects to https://www.tyler.cloud, but typing in "tyler.cloud/react" stays at http://tyler.cloud/react (not HTTPS).
What I've tried in addition to above with the same results
RewriteEngine on
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://%{SERVER_NAME}%{REQUEST_URI} [R=301,L]
and
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
and a few other variations.
It turns out "AllowOverride" in /var/www has to be "All" in /etc/apache2/apache2.conf.
It was set to "None", and that means it ignored all of my .htaccess files.
I used this:
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
and it seems to work!
Consider using apache2.conf instead of .htaccess. Because using .htaccess in a server where you have root access is a bad idea. It can slow your website down unnecessarily.
Try using this instead of .htaccess:
<Directory "/path/to/web/directory">
RewriteEngine On
RewriteCond %{HTTPS} !on
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</Directory>
And if you are using VirtualHosts, add:
RewriteEngine On
RewriteOptions Inherit
inside the virtualhost.
And also, if someone points their domain to your IP address, then they will be able to show your website through their IP address (unless you are using Name based virtual hosting i.e. https://httpd.apache.org/docs/2.4/vhosts/name-based.html, but still they will be able to access your main Apache host with the IP address of course). Although because you are using HTTPS, their domain probably will fail HTTPS. But, because you do not have HSTS (https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security) set up, users can still access the website.
So, I would also suggest you to redirect to your domain if the domain doesn't match https://www.tyler.cloud, using the following: (add the following to inside <Directory> directive)
(If you are planning to add HSTS preload see the next solution please)
#Do not use RewriteEngine On more than once. see the next solution if you are planning to use HSTS preload
RewriteCond %{HTTP_HOST} !^www\.tyler\.cloud [OR]
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://www\.tyler\.cloud%{REQUEST_URI} [R=301,L]
Use the next solution if planning to use HSTS preload:
RewriteCond %{HTTP_HOST} ^tyler\.cloud
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://tyler\.c%{REQUEST_URI} [R=301,L]
RewriteCond %{HTTP_HOST} !^www\.tyler\.cloud [OR]
RewriteCond %{HTTPS} !=on
RewriteRule ^ https://www\.tyler\.cloud%{REQUEST_URI} [R=301,L]
And you are good to go!

Double conditions redirection

I'd like to permanently redirect my pages to https + www.
I'm using the code below but it doesn't work when I enter https://example.com. It does nothing and displays the page without adding the www.
RewriteEngine On
RewriteCond %{HTTPS} off [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^ https://www.example.com%{REQUEST_URI} [R=301,L,NE]
There is no problem with the given redirect rule. It seems problem is that OP is executing shown rule from <VirtualHost *:80> section. Those rules will obviously won't fire if request is https://. OP can do one of the two thing to fix the problem:
Keep same redirect rule in <VirtualHost *:443> section as well - OR
Keep rule in a common place like .htaccess
Try it like this:
RewriteEngine on
RewriteCond %{HTTPS} !=on [OR]
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ https://www.example.com%{REQUEST_URI} [R=301,L,NE]
Make sure to clear your cache before testing this.

Apache rewrite all incoming to same address

Hi I want to direct all traffic on port 443 to teh same adress but I want to kepp the parameters.
I have tried to read how to do it and right now I have something like this
<Virtualhost x.x.x.x:443>
RewriteEngine on
RewriteCond %{REQUEST_URL} !^(.*)example2.com/test/(.*) [NC]
RewriteRule ^(.*)$ https://example1.example2.com/test/$1 [R,L]
So basically I want to rewrite everything that doesn't have example2.com/test/ in the URI
Example if I get www.example.com?parameter=5
I want it to be https://example1.example2.com/test?parameter=5
The %{REQUEST_URI} is only the URI and not the hostname. So there will never be example.com in the variable, and thus the condition will always be true (unless you're actually going to http://example1.example2.com/example2.com/test/).
Try:
RewriteEngine on
RewriteCond %{HTTP_HOST} !^(.*)example2.com$ [NC]
RewriteCond %{REQUEST_URI} !^/test/(.*) [NC]
RewriteRule ^(.*)$ https://example1.example2.com/test%{REQUEST_URI} [R,L]

Subdomain to subfolder in Apache

I am looking for Apache configuration that would allow for the following:
Serve sub.domain.com as /%docRoot%/domain.com/sub, and
Would be able to do this for every hosted domain and any subdomain (ie. no per-domain vhost configuration)
I would be grateful for any solution, especially if there was no mod_rewrite involved (using mod_vhost_alias).
Note: There are some obvious solutions using mod_vhost_alias, but they either work for domain.com or sub.domain.com, none of them seems to cover both cases.
Have a nice day!
Point *.domain.com to your document root (/%docRoot%/). You'll need to do this in a vhost config. In that same vhost, add this:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/domain.com/
RewriteCond %{HTTP_HOST} ^([^\.]+)\.domain\.com$ [NC]
RewriteRule ^/(.*)$ /domain.com/%1/$1 [L]
If you want to avoid pointing www.domain.com to /%docRoot%/domain.com/www, then add a condition to exclude it:
RewriteEngine On
RewriteCond %{REQUEST_URI} !^/domain.com/
RewriteCond %{HTTP_HOST} !^www\.domain\.com$ [NC]
RewriteCond %{HTTP_HOST} ^([^\.]+)\.domain\.com$ [NC]
RewriteRule ^/(.*)$ /domain.com/%1/$1 [L]
EDIT:
I assume I will still have to do this for every hosted domain (as the examples you've posted all refer to "domain.com"). Am I right?
Yes, the above will only do the routing for domain.com, if you want to do this for all arbitrary domain.com, you'll need to do something a bit more tricky:
RewriteEngine On
# here, %1 = subdomain name, and %2 = domain name
RewriteCond %{HTTP_HOST} ^([^\.]+)\.(.+)$ [NC]
# make sure the request doesn't already start with the domain name/subdomain name
RewriteCond %{REQUEST_URI}:%2/%1 !^/([^/]+/[^/]+)[^:]*:\1
# rewrite
RewriteRule ^/(.*)$ /%2/%1/$1 [L]
The tricky thing here is the %{REQUEST_URI}:%2/%1 !^/([^/]+/[^/]+)[^:]*:\1 match. It posits the condition: %{REQUEST_URI}:domain.com/sub and makes sure the %{REQUEST_URI} doesn't start with the domain.com/sub (back refrenced from previous match using %2/%1) using the \1 back reference.
With this, you setup your vhost to accept every domain (default vhost) and any subdomain/domain will get routed. Examples:
http://blah.bleh.org/file.txt goes to /%docRoot%/bleh.org/blah/file.txt
http://foo.bar.com/some/path/ goes to /%docRoot%/bar.com/foo/some/path/
http://sub2.sub1.d.com/index.html goes to /%docRoot%/sub1.d.com/sub2/index.html
EDIT2:
Yes, I would very much like to get domain.com routed to /%docRoot%/domain.com/
Try these:
RewriteCond %{HTTP_HOST} ^(.+?)\.([^\.]+\.[^\.]+)$ [NC]
RewriteCond %{REQUEST_URI}:%2/%1 !^/([^/]+/[^/]+)[^:]*:\1
RewriteRule ^/?(.*)$ /%2/%1/$1 [L]
RewriteCond %{HTTP_HOST} ^([^\.]+\.[^\.]+)$ [NC]
RewriteCond %{REQUEST_URI}:%1 !^/([^/]+)[^:]*:\1
RewriteRule ^/?(.*)$ /%1/$1 [L]
Basically the same thing, except a few of the regex needs to be tweaked to separate what a domain.com is like vs sub.domain.com. If you want to redirect www.domain.com to domain.com, that needs to happen before these rules.

How to ensure that Apache always serves a single page via HTTPS?

I would like to redirect all connections from htt_p://www.example.com/abc.html to HTTP_S://www.example.com/abc.html . What mod_alias or mod_rewrite commands would work for this? I've tried:
RewriteEngine on
RewriteCond %{HTTPS} =off
RewriteRule $abc\.html^ https://www.example.com/abc.html [R]
in both .htaccess and httpd.conf but that doesn't work. It works if the first string in the RewriteRule is anything else (like abz.html) but not if it is abc.html. abc.html is a real file on the server (not another redirect). Options FollowSymlinks is present in the appropriate Directory directive.
Many thanks.
Something along the lines of the following will allow you to redirect non-SSL pages to SSL versions (assuming that you are running SSL on port 443):
RewriteEngine on
# Limited redirects
RewriteCond %{SERVER_PORT} !^443$
RewriteCond %{REQUEST_URI} ^/abc\.html$ [OR,NC]
RewriteCond %{REQUEST_URI} ^/def\.html$ [OR,NC]
RewriteCond %{REQUEST_URI} ^/ghi\.html$ [NC]
RewriteRule ^/(.*)$ https://%{HTTP_HOST}/$1 [R=301,L]
The [OR] flag after the RewriteCond is literally that, "or", which is why the last condition doesn't have it