12

I'm trying to redirect multiple hostnames to only one, for example, if you enter any of:

foo.example.com
www.example.com
bar.example.com
eample.com

you must be redirected to www.example.com

I have installed a virtual host with www.example.com as ServerName and the others as ServerAlias, and use mod_rewrite to check if the hostname was right, and if not do a redirection.

The problem is that everything seems to be served with the ServerName directive hostname, so mod_rewrite always gets www.example.com, which is consistent with the apache2 documentation:

For example, suppose that you are serving the domain www.domain.tld and you wish to add the virtual host www.otherdomain.tld, which points at the same IP address. Then you simply add the following to httpd.conf:

NameVirtualHost *:80

<VirtualHost *:80>
ServerName www.domain.tld
ServerAlias domain.tld *.domain.tld
DocumentRoot /www/domain

<VirtualHost *:80>
ServerName www.otherdomain.tld
DocumentRoot /www/otherdomain

You can alternatively specify an explicit IP address in place of the * in both the NameVirtualHost and directives. For example, you might want to do this in order to run some name-based virtual hosts on one IP address, and either IP-based, or another set of name-based virtual hosts on another address.

Many servers want to be accessible by more than one name. This is possible with the ServerAlias directive, placed inside the section. For example in the first block above, the ServerAlias directive indicates that the listed names are other names which people can use to see that same web site:

ServerAlias domain.tld *.domain.tld then requests for all hosts in the domain.tld domain will be served by the www.domain.tld virtual host.

Is there any apache2 directive to avoid this feature and get request server by with the hostname of the ServerAlias they match?

Or must I create another virtualhost just for redirection?

Thanks

sysadmin1138
  • 131,083
  • 18
  • 173
  • 296
alcuadrado
  • 223
  • 1
  • 3
  • 6

2 Answers2

17

To be fairly honest with you, the best approch i can see for this would be if you setup your main domain normally like this:

<VirtualHost *:80>
    ServerName www.example.com
    DocumentRoot /www/domain 
</virtualhost>

Then you create a new virtualhost that will hold all domains you want to redirect like this:

<VirtualHost *:80>
    ServerName example.com
    ServerAlias foo.example.com bar.example.com others.example.com
    DocumentRoot /www/redirect_folder 
</virtualhost>

Inside that folder make a simple index.php page that summons the 301 so any domains hold in there will be redirect to your main domain with the 301 code.

<?
Header( "HTTP/1.1 301 Moved Permanently" );
Header( "Location: http://www.example.com" );
?> 

Why do you think it is better this way ?

This way you won't have to keep updating a bunch of places everytime you have a new domain to hold and redirct to your main domain and it won't be serving your users with the current name but will actually redirect them to your main domain in question.

If you are the server owner you can make it even better, you can put the 2nd virtualhost as the first virtualhost in your httpd.conf of vhost.conf file and whenever you hit the IP of your server it will lead you to the redirection page which will lead your users to the main domain in this case instead of having to set a bunch of ServerAlias you can just create the DNS A record for that given subdomain or domain leading to your IP and the server will take care of the rest.

In this last case all you would need for your virtual host would be:

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /www/redirect_folder 
</virtualhost>

as you dont need the ServerAlias since every and each request that hits your server IP will go to your first vhost.

In addition if you wanted to do this using .htaccess, it would be something like this i belive:

RewriteEngine on
rewritecond %{http_host} ^foo.example.com [nc]
rewriterule ^(.*)$ http://www.example.com/$1 [r=301,nc] 
Prix
  • 4,703
  • 3
  • 23
  • 25
  • the option of index php header would only work for new domains pointing to a site however if you want to change oldDomain to a new domain and want everything redirected if think redirect in the vhost file would work best otherwise oldDomain.com/oldfolder/hiall.php wouldn't redirect – YesItsMe Apr 23 '18 at 23:57
  • @yesitsme It works regardless, you're either cached or doing something wrong, or have extra .htaccess in play or something worst going on... However, this answer was specifically to the OP case, and yours may differ, even the small details would affect the outcome, for example your browser being cached while you're forcing a 301 redirect thus not seeing the true results. – Prix Apr 24 '18 at 06:30
  • My point was for index.php wouldn't help if old links are out there pointing to a sub-folder, you're right with what you pointed out. – YesItsMe Apr 24 '18 at 19:28
  • @yesitsme Like I said every case is its own case, this reply does not take that into account as it was not a requirement. What you're pointing can be easily solved with the use of a .htaccess over the index.php. Redirecting from the vhost is always better as its much faster in most cases, but you don't always have access to modify the vhost unless you have root access to it or they allow you to do so from the control panel they may have at the hosting service. – Prix Apr 25 '18 at 05:33
  • 1
    The `DocumentRoot /www/redirect_folder` is a nice idea. But why not replace that with `RedirectMatch 301 (.*) http://www.example.com/$1`? Same thing without the bother of `/www/redirect_folder/index.php`. – DFriend Nov 04 '18 at 00:44
  • I love the `RedirectMatch` instruction but that makes a simple call to `http://example.org` redirect to `http://example.com//` with an extra slash. – Adam Mar 27 '20 at 15:58
2

It all depends on the configuration order in this case.

If you have a setup like this:

<VirtualHost>ServerAlias *.domain.tld</VirtualHost>
<VirtualHost>ServerName subdomain.domain.tld</VirtualHost>

Than people will always end up at the first vhost. However, if you define them like this, it works:

<VirtualHost>ServerName subdomain.domain.tld</VirtualHost>
<VirtualHost>ServerAlias *.domain.tld</VirtualHost>

Just remember that wildcards should always be at the bottom.

Wolph
  • 865
  • 1
  • 7
  • 12