Apache settings, multi vhost multi servername same directory - apache

I would like to know if it s possible to use the same block to set up different servername for one vhost. I have an application that is reachable by www.extranet.com i would like to access it through any sub domain like www.exemple.extranet.com without having to declare them all.
I could use server alias but i need to keep the original URI on the browser.
Any Thoughts ?

Probably the best method would to be to use the rewrite rules. For example:
RewriteEngine on
RewriteCond %{HTTP_HOST}^mydomain\.com [NC]
RewriteRule ^/(.*)$ http://www.mydomain.com [r=301,L]

This is the main use-case for ServerAlias. The vhost responds to not only the Servername, but also all ServerAliases. The only thing you need to "declare" is the list of hosts that this vhosts answers to.
ServerName example.net
ServerAlias www.example.net www.subdomain.example.net anothersubdomain.example.net
The hostname in the browser will stay the same.
Unless you do something about it with RewriteRules and such, but your goal was to not alter it. So the default behaviour should work for you.

Related

Apache Configuration: redirecting to www in .htaccess

I have read a number of formulas for redirecting example.com to www.example.com and this appears to apply to .htaccess. However, I am confused about how this might work.
I want to assume that I have no access to the Apache vhosts configuration, and that I need to do it with .htaccess.
Suppose the configuration contains something like this:
<VirtualHost *:80>
ServerName www.example.com:80
ServerAlias www.example.com
VirtualDocumentRoot /whatever/example.com/www
</VirtualHost>
One such formula is something like this"
RewriteCond %{HTTP_HOST} !^www\. [NC]
RewriteRule ^(.*)$ www\.%{HTTP_HOST}/$1 [R=301,L]
However, I don’t see how one root directory can respond to both requests.
The question is: Is it even possible to redirect example.com to www.example.com using .htaccess only, without tweaking the Virtual Host file?
The way I see it, the original request
I run my own server, and I can do anything I like. However, I am asking this because many of my clients and students have no access to tehe configuration, and can only fiddle with .htaccess.

Rewrite spare domains to main domains with .htaccess

We have a site with an English and Spanish version, each on a different domain. We also have a few spare domains for each language which we'd like to redirect to the language's main domain.
Specifically:
estadiosfutbol.net/..., estadiosfutbol.org/... and estadiosfutbol.info/... should all redirect to https://estadiosfutbol.com/...
worldfootballstadiums.com/..., worldfootballstadiums.info/..., worldfootballstadiums.org/... and worldfootballstadiums.net/... should all redirect to https://worldstadiums.football/...
I'm struggling with the rewrite rules so any help would be greatly appreciated.
There are two ways this can be done. The first is the simpliest, but is not always practical.
First Method
This method does not require HTACCESS files. In your Apache server configuration you just need to add ServerAliases for each of the domains that you want it to handle. (You must make sure all the domains are pointing at the same machine)
The Code
NameVirtualHost *:443
<VirtualHost *:443>
ServerName estadiosfutbol.com
ServerAlias estadiosfutbol.info estadiosfutbol.net estadiosfutbol.org
DocumentRoot /www/domain
</VirtualHost>
<VirtualHost *:443>
ServerName worldstadiums.football
ServerAlias worldfootballstadiums.com worldfootballstadiums.net worldfootballstadiums.info worldfootballstadiums.org
DocumentRoot /www/otherdomain
</VirtualHost>
Note: This will only redirect if the user tries to access the website using SSL. (eg ) If you want it to redirect all traffic from both port 80 and port 443 you would need to make separate virtual hosts and use the second method to achieve the redirection.
Second Method
The second way is a little more complicated, but works in almost all situations. There a two main steps that need to be carried out in order for this to work properly:
Make sure that whatever server software you are using is setup to be looking for all the domains. The server has to have a VirtualHost(Apache) that is listening for each domain in order for the next step to do anything.
Create a .HTACCESS file under each domains' root that looks similar to this:
The Code
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} !estadiosfutbol.net$ [NC]
RewriteRule ^(.*)$ https://estadiosfutbol.com/$1 [L,R=301]
Note: You will need to change the third line on each domain to be the domain to rewrite from (eg estadiosfutbol.net/, estadiosfutbol.org/ and estadiosfutbol.info)
Note: Changing the forth line is all that is required for the separate domain.

How to retrieve server alias in Apache config?

I have a single named virtual host that handles traffic for a bunch of different hostnames.
In the Apache config, I need to create RewriteRules according to the hostname requested by the user. Unfortunately the contents of the %{SERVER_NAME} variable always matches the primary hostname defined as ServerName in the config, instead of the alias requested by user.
e.g.: I need to serve site.company.com, site2.company.com and site3.company.com
NameVirtualHost *:80
<VirtualHost *:80>
ServerName site.company.com
ServerAlias site?.company.com
RewriteCond %{SERVER_NAME} pattern
RewriteRule blah_depending_on_hostname_requested_by_user
</VirtualHost>
Problem: %{SERVER_NAME} is always site.company.com, even if user requests one of the aliases such as site2.company.com.
How do I solve this? There doesn't seem to be a %{SERVER_ALIAS} variable available.
You probably mean %{HTTP_HOST}. That's the exact site name provided by the browser. From the manual:
If you wish to match against the hostname, port, or query string, use
a RewriteCond with the %{HTTP_HOST}, %{SERVER_PORT}, or
%{QUERY_STRING} variables respectively.

redirecting www.subdomain.example.com to subdomain.example.com

I've had some users trying to access a site that is registered as subdomain.example.com with www.subdomain.example.com.
is there some sort of .htaccess rule I can add to redirect people that arrive using www.subdomain.example.com to subdomain.example.com?
Also, do I have to change DNS stuff?
Sure, use a directive like:
<VirtualHost *:80>
ServerName www.subdomain.example.com
Redirect permanent / http://subdomain.example.com/
</VirtualHost>
Apache automatically preserves anything after the / when using the Redirect directive, which is a common misconception about why this method won't work (when in fact it does).
Also, yes you will need to change DNS records, because www.subdomain.example.com is a distinct hostname that needs its own A (or CNAME) record to point the browser to an appropriate server in the first place.
RewriteCond %{HTTP_HOST} ^www.subdomain.domain.com
RewriteRule (.*) http://subdomain.domain.com/$1 [R=301,L]
You need to add a virtual host directive in httpd.conf and Redirect Permament to the correct subdomain and add the additional DNS entry (CNAME is fine)

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..