RewriteRule for mapping x.domain.com to y.domain.com - apache

Is it possible to redirect all requests to x.domain.com/.* to y.domain.com/.* WITHOUT letting this redirection be visible in the url?
I have unsuccessfully tried several things in .htaccess. Just specifying the [L] flag still shows this redirection in the url (as it does when I use the [R] flag additionally).
EDIT: as somebody claimed there being no reason for this, let me give some more information :)
I have one nice url: x.domain.com , which is well known.
Then there are a number of other domains: spring.domain.com , summer.domain.com , autumn.domain.com, winter.domain.com .
Depending on the time of the year, a specific y.domain.com becomes the current one. The x.domain.com should always map to the current one.
EDIT2:
I'll write here, as the code isn't nicely rendered in the comments...
I tried what Arjan suggested:
RewriteCond %{HTTP_HOST} ^x.domain.com$
RewriteRule ^(.*)$ /path/to/y.domain.folder/$1
Unfortunatly though this keeps redirecting forever. :(
Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.
Putting the [R] flag behind, I see in the url something like:
http://x.domain.com/path/to/y.domain.folder/path/to/y.domain.folder/path/to/y.domain.folder/ ...
Any suggestions?
Now that I can read the errorlogs, I can give a direct response, as what a possible 500 error refers to.

Assuming you have access to the Apache configuration, create the following virtual host for domain x.domain.com. Then simply update y to whatever you need each season.
<VirtualHost ...:80>
ServerName x.domain.com
UseCanonicalName Off
ProxyRequests Off
<Proxy *>
Order Allow,Deny
Allow from all
</Proxy>
ProxyPreserveHost Off
RewriteEngine On
RewriteRule ^$ http://y.domain.com/ [P,NC]
RewriteRule ^/(.*)$ http://y.domain.com/$1 [P,NC]
ProxyPassReverse / http://y.domain.com/
</VirtualHost>
Also to pick up the Alias suggestions, if you have multiple virtual hosts (one for each season) then you could put a server alias into the current domain. E.g.
<VirtualHost ...:80>
ServerName summer.domain.com
ServerAlias x.domain.com
...
</VirtualHost>
<VirtualHost ...:80>
ServerName spring.domain.com
...
</VirtualHost>
...
This would make Apache deliver the summer.domain.com pages if you go to x.domain.com. If your seasonal subdomains depend on the HOST header line to be set correctly (i.e. to season.domain.com) you would need to use the first suggestion above, though.

If these are not hosted on the same server, then you'd need the Proxy flag. This also requires the proxy module to be running. Not tested:
RewriteCond %{HTTP_HOST} ^x.domain.com$
RewriteRule ^(.*)$ http://y.domain.com/$1 [P]
EDIT: Given the edits to your question they're probably just on the same server. So then indeed, as jetru suggested an Alias might do. Or:
# No RewriteCond required; serve all content from other folder:
RewriteRule ^(.*)$ /path/to/y.domain.folder/$1
EDIT: The above would not change the HTTP_HOST header that was sent by the browser (maybe that can be done as well). This implies that it would only work if the subdomains are represented on the file system as separate directories. So, as the .htaccess would then be placed in the directory holding the website for x.domain.com, the RewriteCond wouldn't even be required. Also, the directory for this x.domain.com subdomain would in fact not need any HTML content then; in the end all content would be served from the directory of another subdomain.
EDIT: As the above does not seem to work either, and yields endless rewrite loops even when adding [NS], maybe simply adding [L] helps here:
RewriteRule ^(.*)$ /path/to/y.domain.folder/$1 [NS,L]
Or maybe one can set an environment variable to stop the loop:
RewriteCond %{ENV:MY_VAR} !=1
RewriteRule ^(.*)$ /path/to/y.domain.folder/$1 [E=MY_VAR:1]
But, for both [L] and [E]: I'm just guessing; I've never made mod_rewrite jump into the directory of another virtual host. I am not sure it can be done to start with.
Unfortunately, it's unclear how one would add a new subdomain. If one would just need to create a new directory with the name of the subdomain (without any use of some administrative tool) then the provider might be be using system wide rewriting as well. In fact, even without subdomains the provider might be doing some Mass Virtual Hosting as described in the URL Rewrite Guide.
I guess the best solution would be to change the value of HTTP_HOST on the fly, to solve issues with any system wide rewriting. Maybe the following is allowed to achieve that:
RewriteCond %{HTTP_HOST} ^x.domain.com$
RewriteRule ^(.*)$ /path/to/y.domain.folder/$1 [E=HTTP_HOST:y.domain.com]
Again, as the above would only be present in the .htaccess in the x.domain.folder, the RewriteCond is probably not needed at all.

Have you tried
Alias /dir/file.html /full/path/to/other/file.html
??

To my knowledge and testing with firebug a redirect via .htaccess is always announced to the client and it's up to him how to proceed. It is therefore not an alternative to some sort of SSI functionality. To prevent a "fake" address modern browser should always make the REAL address visible to the user, however I think I have seen some misbehavior in programs like "feeddemon" where IE is embedded. If you - for whatever reason - really want to show content from one subdomain on another you can try using Javascript or (i)frames on the user side or some include functionality on the server site (eg. file_get_contents with php). However, I don't recommend this.

Related

apache mod_rewrite user URLs to index.php

I've always had a fairly standard apache configuration. Right now we're introducing a new concept, user session specific URLs that's going to change things. Basically we have a DocumentRoot and anything such as:
http://example.com/ would hit index.html in the DocumentRoot directive.
But now I'd like to be able to do something like
http://example.com/uid/5/
http://example.com/uid/2
Those should still hit index.html in the DocumentRoot that has been set. The URL is mostly for server-side and client-side scripts to be able to carry out their own tasks.
What's the best way to handle this in Apache? Is mod_rewrite even necessary here?
I also need to be able to support existing paths such as say the following:
http://example.com/foo/bar/something.php will be rewritten to http://example.com/uid/3/foo/bar/something.php but will still hit the same place on the filesystem as before.
You could use mod_rewrite by putting this code in your htaccess
RewriteEngine On
RewriteRule ^uid/([1-9][0-9]*)/(.+)$ /$2?uid=$1 [L]
Example:
http://example.com/foo/bar/something.php -> unchanged
http://example.com/uid/3/foo/bar/something.php -> rewritten to /foo/bar/something.php?uid=3
EDIT: without uid appended
RewriteEngine On
RewriteRule ^uid/[1-9][0-9]*/(.+)$ /$1 [L]

.htaccess Mask Domain and hide url

I am trying to get a subdomain to show to contents of another domain, with the ability to go to any area of the other domain i.e. all directories
So for example I would like my client to go to "sub.domain-one.com" or more specifically "sub.exampledomain.com/client_name". I would like this to then show the content of "domain-two.com", my development server, without the client knowing.
I would also if possible like to keep the base domain of "sub.domain-one.com" to stay on my live server so that I can keep a index.php on that server. But this is only an extra wish :)
My current code is
Options +FollowSymLinks
RewriteEngine On
RewriteCond %{REQUEST_URI} !^(sub.)?domain-one.com/$1
RewriteCond %{HTTP_HOST} ^(sub.)?domain-one.com
RewriteRule ^(.*) http://domain-two.com/$1 [P,NC]
This code seems to work to an extent (it will let me go to sub.domain-one.com but if I go to sub.domain-one.com/client_name it will redirect my browser url to domain-two.com/client_name
But I need it hidden :(
Thanks heaps in advanced
James
You need to use a ProxyPassReverse in order to rewrite redirects from the proxied site to the site that you are proxying from. Unfortunately, you can't do this in an htaccess file. In the server/vhost config, you'll need to create a virtual host for "sub.domtain-one.com"/"domain-one.com", then use ProxyPass:
ProxyPass / http://domain-two.com/
ProxyPassReverse / http://domain-two.com/

Apache mod_rewrite ANY subdomain(s) to root domain, unless existent as virtualdocumentroot

Say you've got an Apache2 virtual host setup, something like this:
/htdocs/parent1.com
/htdocs/sub1.parent1.com
/htdocs/sub2.parent1.com
/htdocs/parent2.net
/htdocs/parentn.org
Say you'd like to do this with VirtualDocumentRoot /htdocs/%0, so that you can add and remove virtual hosts without tinkering with your Apache configuration. That's important: please please no messing with htaccess files or httpd.conf every time a virtual host comes or goes - whether that host is a parent domain or not. In fact, say you're using AllowOverride None.
Anyway, the question is, how might you 301 redirect non-existent sub-domains to their corresponding parent domains without redirecting existent sub-domains?
I may have solved my own problem. However I would appreciate any feedback if somebody finds a problem with what I'm doing.
The following leaves alone any request to an arbitrary subdomain, as long as there exists a corresponding document root; but redirects any request to a subdomain which does not exist in the filesystem.
<IfModule rewrite_module>
RewriteEngine On
RewriteMap lowercase int:tolower
RewriteCond "/htdocs/${lowercase:%{HTTP_HOST}}" !-d
RewriteCond %{HTTP_HOST} "\.([^\.]+\.[^\.]+)$"
RewriteRule ^/(.*)$ "http://%1/$1" [R=301]
</IfModule>
Allows me to setup wildcard DNS and use name-based virtual hosting, without touching any configuration settings. Also, there's no htaccess involved. Just make your folder with any name like "/htdocs/[host.]domain.tld" and you're up and running. As far as I can tell, this doesn't really work with SSL/TLS (presumably something to do with %{HTTP_HOST}?), but secure sites are comparably few and better resolved by IP address than by hostname.

Problems redirecting old domain to new with Apache and htaccess

My homepage is located at www.nazgulled.net and I bought a new domain which is www.ricardoamaral.net. Both these domains point to the same exact server.
I'm having two problems with the redirection, my current code is this:
RewriteCond %{HTTP_HOST} ^(www\.)?nazgulled\.net [NC]
RewriteRule ^(.*)$ http://www.ricardoamaral.net/$1 [L]
For now I'm just testing but the idea is to replace [L] with [L,R=301] when I'm ready to move the whole thing, just so you know.
Anyway...
1) This is not working, when I try it, I can't access "nazgulled.net", it gives me a "server internal error" and I don't understand why... I don't understand why because if replace "ricardoamaral.net" by "google.com", the redirect works just fine :/
2) I have a few subdomains and I would like to redirect everything in those too. My first choice is to add different rewrite conditions/rules for each of the subdomains but that takes a lot of manual code and if the user types some subdomain that doesn't exist, they don't be redirect it and I also want that.
I think for your situation creating separate vhosts would be the ideal fit. What I do often is place domains that are being redirected on the same server but in a different folder to keep the www folder clean, for instance. My main site would be here:
/var/www/example.com/public
For all my redirects I would place them like so:
/var/www/redirects/example-2.com/public
Within each public folder of the redirected sites you would add this line to your .htaccess file
RedirectMatch permanent /.* http://example.com/
For 1, you can use something like this instead:
<VirtualHost *:80>
ServerAdmin webmaster#nazgulled.net
ServerName nazgulled.net
ServerAlias www.nazgulled.net
Redirect permanent / http://www.ricardoamaral.net/
</VirtualHost>
I use a similar configuration and it works perfectly, keeping query parameters, paths, etc.
Regarding your own rewrite rule, I want to note that you may lose your query params if you don't include QSA.
To diagnose internal server errors, just have a look at the log file provided by your ErrorLog directive within your vhost, or a global one, depending on your configuration. It should give you the exact reason for the error.
This is best solutions. Create a notepad file and save it as .htaccess if you do not already have an existing one.
Update the .htaccess file with the following code and save
Options +FollowSymLinks
RewriteEngine on
RewriteRule (.*) http://new-domain.com/$1 [R=301,L]

How can I implement a global RewriteCond / RewriteRule in Apache that applies to all virtual hosts?

The title pretty much says it all. :-) I have lots of virtual hosts and I want to put a single rewriting block at the top of the httpd.conf file that rewrites URLs no matter which virtual host the request might be directed to. How the heck do I do this?
I found this but my question is the same: how can I do this without resorting to .htaccess files and performing some other action for each virtual host?
OMGTIA!
Specify RewriteOptions InheritDown in the parent scope (such as httpd.conf) to get your rules applied in child Virtual Hosts without modifing them.
This will only work on Virtual Hosts where the RewriteEngine directive is set to on:
Note that rewrite configurations are not inherited by virtual hosts. This means that you need to have a RewriteEngine on directive for each virtual host in which you wish to use rewrite rules.
(source)
Apache supports this since 2.4.8 (not available at the time of the original question).
From documentation for RewriteOptions:
InheritDown
If this option is enabled, all child configurations will inherit the configuration of the current configuration. It is equivalent to specifying RewriteOptions Inherit in all child configurations. See the Inherit option for more details on how the parent-child relationships are handled.
Available in Apache HTTP Server 2.4.8 and later.
InheritDownBefore
Like InheritDown above, but the rules from the current scope are applied before rules specified in any child's scope.
Available in Apache HTTP Server 2.4.8 and later.
IgnoreInherit
This option forces the current and child configurations to ignore all rules that would be inherited from a parent specifying InheritDown or InheritDownBefore.
Available in Apache HTTP Server 2.4.8 and later.
(http://httpd.apache.org/docs/current/mod/mod_rewrite.html#rewriteoptions)
By default, mod_rewrite configuration settings from the main server context are not inherited by virtual hosts. To make the main server settings apply to virtual hosts, you must place the following directives in each <VirtualHost> section:
RewriteEngine On
RewriteOptions Inherit
click http://httpd.apache.org/docs/2.2/mod/mod_rewrite.html to find more information
Looks like the simplest possible solution is to add
RewriteOptions inherit
to each VirtualHost directive. This is at least a lot simpler than messing with .htaccess files. Apache is pretty clear on the fact that
by default, rewrite configurations are
not inherited. This means that you
need to have a RewriteEngine on
directive for each virtual host in
which you wish to use it.
(http://httpd.apache.org/docs/1.3/mod/mod_rewrite.html)
and apparently the way to change the default is via RewriteOptions in the child (vhost or director), so you have to do something in each child.
I've never tested it, so it might not work, but I would try adding an include directive in all of the virtual host blocks to a single file. You would have to change each virtual host configuration block once, but after that, you should have a central place from which to make changes. YMMV.
If you're only trying to rewrite something in the domain part of the name, e.g. to fix a common misspelling, you don't even need the 'inherit' option. I setup a no-name virtual host to catch all invalid host names and respell them correctly before redirecting them.
Since this uses redirects, the appropriate virtual host will be found after the rewrites have been applied.
Options +Indexes +FollowSymLinks
RewriteEngine on
# If it begins with only domain.com, prepend www and send to www.domain.com
RewriteCond %{HTTP_HOST} ^domain [NC]
RewriteRule ^(.*) http://www.domain.com$1 [L,R=301]
# Correct misspelling in the domain name, applies to any VirtualHost in the domain
# Requires a subdomain, i.e. (serviceXXX.)domain.com, or the prepended www. from above
RewriteCond %{HTTP_HOST} ^([^.]+\.)dommmmmain\.com\.?(:[0-9]*)?$ [NC]
RewriteRule ^(.*) %{HTTP_HOST}$1 [C]
RewriteRule ^([^.]+\.)?domain.com(.*) http://$1domain.com$2 [L,R=301]
# No-name virtual host to catch all invalid hostnames and mod_rewrite and redirect them
<VirtualHost *>
RewriteEngine on
RewriteOptions inherit
</VirtualHost>
You may want to use InheritDownBefore to avoid having to add more junk to your vhosts.
An example of a global letsencrypt alias:
# letsencrypt
<IfModule alias_module>
Alias /.well-known/ /var/www/html/.well-known/
</IfModule>
<IfModule mod_rewrite.c>
# prevent vhost rewrites from killing the alias
RewriteEngine On
RewriteOptions InheritDownBefore
RewriteCond %{REQUEST_URI} ^/\.well\-known
RewriteRule . - [L,PT]
</IfModule>
Then you can do this in each of your vhosts, with no other directives:
<VirtualHost *:80>
....
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^/.* /index.php [L,PT]
</IfModule>
</VirtualHost>
Thanks to everyone to answered above. It helped me find my answer.
Question has been answered already, I just wanted to add an example in case you are using Google Compute Engine. It says it requires Apache HTTP Server 2.4.8 BUT it works with Apache/2.4.25 (Debian). Even when I try to upgrade, I cannot go past Apache/2.4.25. It says this version is the latest version.
Here's an example of how to implement.
RewriteOptions InheritDown
RewriteCond %{HTTP_HOST} ^www\. [NC,OR]
RewriteCond %{HTTP_HOST} !\.co$ [NC]
RewriteCond %{HTTP_HOST} ^(?:www\.)?(.+)\.[^.]+$ [NC]
RewriteRule ^ https://%1.co%{REQUEST_URI} [L,NE,R=301]
<VirtualHost *:80>
RewriteEngine On
ServerAlias *.*
</VirtualHost>
ALSO OF NOTE (For Testing):
When you are testing your rewrite engine. It is really easy to get confused about if it is working or not because of cache and cookies. If you got it to work once on a browser, it will continue to work even if you delete the rewrite code. Testing rewrite is really annoying sometimes. You might think it works but then it stops or starts.
Best way to test rewrite code is to open an incognito tab in your browser, clear or cookies and cache. Open developer mode just in case. DO NOT JUST REFRESH. You need to click into the URL and refresh. Or open new tab. Or copy/paste URL into new window. If you use same window with refresh, it might be just redoing results from the past instead of renewing the new code.
I've always used a "catch-all" VHost for directives I wanted across the board, like......
Listen 80
NameVirtualHost *:80
<VirtualHost *:80>
ErrorLog "/var/log/apache2/error_log"
</VirtualHost>
<VirtualHost *:80>
ServerName alloftherestoftheVHosts.com
DocumentRoot "/ServiceData/.........
............
And it's always seemed to work... error logs were getting combined properly, etc...... but it IS possible that this was the result of an earlier / conflicting / like-minded directive.
Personal note.. Whoever dreamed up the Apache configuration schema and syntax was a dingbat, or a group of dingbats, who spent too much time in their cave.... The whole thing should be exorcised and XMLized, or something! Although they are both wildly different... the Hello-Kitty setup process of Cherokee.. to the viciously succinct NGinx config.... are both so much more logical..