I deal with this type of situation using my virtual host configuration. Under Apache, the first virtual host is the "default" virtual host. I configure it to serve a 404 error with the message
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 $1 !-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/[ \r\n]+//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 Permanently\n";
print "Location: $redirect\n";
print "Content-type: text/html\n";
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 "$title\n";
print STDERR "$message\n";
print "Status: $status\n";
print "Content-type: text/html\n";
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: $message\n";
print "</body>\n";
print "</html>\n";
exit;
}
# Convert <, >, & and " to their HTML equivalents.
sub escapeHTML {
my $value = $_[0];
$value =~ s/\&/\&/g;
$value =~ s/</\</g;
$value =~ s/>/\>/g;
$value =~ s/"/\"/g;
return $value;
}