Mobile app version of vmapp.org
Login or Join
Yeniel560

: Require valid ServerName in httpd.conf I have two virtual hosts, and have sites1.com and sites2.com pointing to my server. All works fine. <VirtualHost *:80> ServerName site1.com

@Yeniel560

Posted in: #Apache #Dns #Domains #Url

I have two virtual hosts, and have sites1.com and sites2.com pointing to my server. All works fine.

<VirtualHost *:80>
ServerName site1.com
DocumentRoot /var/www/site1/html
<Directory "/var/www/site1/html">
allow from all
Options +Indexes
</Directory>
</VirtualHost>
<VirtualHost *:80>
ServerName site2.com
DocumentRoot /var/www/site2/html
<Directory "/var/www/site2/html">
allow from all
Options +Indexes
</Directory>
</VirtualHost>


I also have sites3.com pointing to my server, but haven't set up a virtual server for sites3.com.

I have found that sites3.com will resolve to sites1.com (my first VPS). After reviewing httpd.apache.org/docs/current/vhosts/name-based.html, it appears that this is by design:


If no matching ServerName or ServerAlias is found in the set of
virtual hosts containing the most specific matching IP address and
port combination, then the first listed virtual host that matches that
will be used.


It it possible to prevent this behavior, and require a valid ServerName?

10.01% popularity Vote Up Vote Down


Login to follow query

More posts by @Yeniel560

1 Comments

Sorted by latest first Latest Oldest Best

 

@Eichhorn148

The first virtual host directive is the default "catch all." Any unrecognized host names get handled by whichever virtual host directive comes first. The solution to your problem is to create a default virtual host directive that prints out an error. I have one that I use. I've previously posted it in this answer


404 Not Found -- Hostname Not Recognized

This server is not configured to serve documents for foo.example.com


Then I create specific virtual hosts for each of my sites that serve the correct content when the host name is correct.

Here is my default virtual host configuration that uses 404.pl to handle all requests:

<VirtualHost *:80>
Servername localhost.localdomain
DocumentRoot /var/www/default
<Directory /var/www/default/>
Require all granted
Options +ExecCGI
AddHandler cgi-script .pl
RewriteEngine on
RewriteCond !-f
RewriteRule ^(.*)$ 404.pl
AllowOverride None
</Directory>
</VirtualHost>


And here is the 404.pl script that prints out the "hostname not recognized" message as well as does redirects for domain names that are almost correct but not canonical:

#!/usr/bin/perl

use strict;

# Put the host names you actually use in here to enable redirects
# The left side should be the "main" domain name and the right should include the TLD
# This enables redirects for alternate TLDs.
my $hostnameredirects = {
'example' => 'example.com',
'foo' => 'foo.example.com',
};
my $hostname = `hostname --fqdn`;
chomp $hostname;

my $server = $ENV{'SERVER_NAME'};
$server = "" if (!$server);
$server =~ s/[^-_.A-Za-z0-9]//g;
$server = lc($server);
my $uri = $ENV{'REQUEST_URI'};
$uri = "" if (!$uri);
$uri =~ s/[ rn]+//g;
$uri = "/$uri" if ($uri !~ /^//);

&serverNameRedirect();
&noVirtualHostError();
&show404();

sub serverNameRedirect(){
my $domain = &removeTld($server);
while ($domain){
if ($hostnameredirects->{$domain}){
&redirect('http://'.$hostnameredirects->{$domain}.$uri);
}
$domain =~ s/^[^.]*[.]?//g;
}
}

sub removeTld(){
my ($domain) = @_ ;
$domain =~ s/.(([^.]+)|((([A-Za-z]{2})|com|org|net).[A-Za-z]{2}))$//g;
return $domain;
}

sub redirect(){
my ($redirect) = @_ ;
my $eRedirect = &escapeHTML($redirect);
print "Status: 301 Moved Permanentlyn";
print "Location: $redirectn";
print "Content-type: text/htmln";
print "n";
print "<html><body><p>Moved permanently: <a href="$eRedirect">$eRedirect</a></p></body></html>n";
exit;
}

sub show404(){
my $eServer = &escapeHTML($server);
&errorPage(
'404 Not Found',
'404 Not Found -- Hostname Not Recognized',
"This server is not configured to serve documents for '$eServer'"
);
}

sub noVirtualHostError(){
if ($server !~ /^d+.d+.d+.d+$/){
return;
}
&errorPage(
'400 Bad request',
'400 Bad Request -- No Hostname Sent',
"This server only accepts requests with a domain name, not requests for an ip address such as $server"
);
}

sub errorPage(){
my ($status, $title, $message) = @_ ;
print STDERR "$titlen";
print STDERR "$messagen";
print "Status: $statusn";
print "Content-type: text/htmln";
print "n";
print "<html>n";
print "<head>n";
print "<title>$title</title>n";
print "</head>n";
print "<body>n";
print "<h1>$title</h1>n";
print "ERROR: $messagen";
print "</body>n";
print "</html>n";
exit;
}

# Convert <, >, & and " to their HTML equivalents.
sub escapeHTML {
my $value = $_[0];
$value =~ s/&/&amp;/g;
$value =~ s/</&lt;/g;
$value =~ s/>/&gt;/g;
$value =~ s/"/&quot;/g;
return $value;
}

10% popularity Vote Up Vote Down


Back to top | Use Dark Theme