Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I have the following 2 domain records

website.com 10.0.0.1
www.website.com 10.0.0.1

I have(had) the following 2 Virtualhosts

#note how the IP address is wrong
<VirtualHost 10.0.0.2:80>

    ServerName website.com
    Redirect / http://www.website.com

</VirtualHost>

<VirtualHost 10.0.0.1:80>

    ServerName www.website.com
  #note how there is no alias here
    DocumentRoot /var/www/www.website.com

    <IfModule mpm_itk_module>
            AssignUserId www-website www-website
    </IfModule>

    CustomLog /var/log/apache2/www.website.com-access.log combined
    ErrorLog /var/log/apache2/www.website.com-error.log

</VirtualHost>

<VirtualHost 10.0.0.1:443>
    ServerName www.website.com

    DocumentRoot /var/www/www.website.com

    <IfModule mpm_itk_module>
            AssignUserId www-website www-website
    </IfModule>

    SSLEngine On
    SSLCertificateFile /etc/apache2/ssl/www.website.com

    CustomLog /var/log/apache2/www.website.com-ssl-access.log combined
    ErrorLog /var/log/apache2/www.website.com-ssl-error.log

</VirtualHost>

I expected that a request to http://website.com would be returned with a 404. However it was served as if it was delivered from http://www.website.com. Why?

share|improve this question
3  
The very first declared virtual host will act as catch-all if domain name is unknown. "it was served as if it was delivered from website.com"; -- did you saw redirect .. or it was served without redirect. If there was no redirect then your 2nd virtual host was "the very first" for that IP. That is my understanding of the situation (but who knows -- maybe I am wrong here). –  LazyOne Aug 18 '11 at 1:30
    
You are right, but we have many more virtual hosts on that server including that "first one", which is completely different –  jdog Aug 18 '11 at 1:35
    
In my experience, Apache will pick one at random to act as the catch-all. I know various places say you can specify it, or the first one will be it, but that doesn't seem as reliable as I'd like. –  TessellatingHeckler Aug 18 '11 at 2:56
    
@TessellatingHeckler First to load - I've depended heavily on this behavior ;) See here; "If no matching virtual host is found, then the first listed virtual host that matches the IP address will be used." –  Shane Madden Aug 18 '11 at 3:59
add comment

1 Answer

up vote 7 down vote accepted

LazyOne is exactly right. As long as you have your NameVirtualHost directives sorted out, then the first VirtualHost defined for the ip address requested is used, if no other ServerName or ServerAlias matches exist.

Therefore, if you want to serve a 404 for each ip address that doesn't hit a host header match, create a VirtualHost (per ip) without a ServerName or ServerAlias directive, and position it in the config so that it is loaded first. Something like:

<VirtualHost 10.0.0.1:80>
    Redirect 404 /   
</VirtualHost>

<VirtualHost 10.0.0.2:80>
    Redirect 404 /   
</VirtualHost>

<VirtualHost 10.0.0.2:80>
    ServerName website.com
    Redirect / http://www.website.com
</VirtualHost>

<VirtualHost 10.0.0.1:80>
    ServerName www.website.com
    #note how there is no alias here
    DocumentRoot /var/www/www.website.com
...
</VirtualHost>

Update: Most of the following is cribbed from the apache2 docs, here and here.

The main config file, generally named httpd.conf, is loaded first. But if you're using a binary package on a debian-based system, there's a good chance it'll be called apache2.conf. Other config files are added using the Include directive in the main config. Multiple uses of the Include directive are allowed. Include directives may use fnmatch-style wildcards to load several config files at once, in alphabetical order.

To clarify further (hopefully), your main config is loaded first. As Include directives are encountered, they are loaded in the order they appear in the main config. If an individual Include uses a wildcard, each config file that matches is loaded in alphabetical order.

On a debian server, apache2.conf may look something like this:

# Include module configuration:
# ...
Include mods-enabled/*.conf

# Include all the user configurations:
Include httpd.conf

# Include ports listing
Include ports.conf

# ...

# Include generic snippets of statements
Include conf.d/

# Include the virtual host configurations:
Include sites-enabled/

In other words, any file ending in .conf in mods-enabled/ is loaded before httpd.conf, which is loaded before ports.conf, which is loaded before any file in conf.d/, etc.

share|improve this answer
    
Dead on. To add to this; @jdog, your second VirtualHost is catching the request because the host file points that domain name to 10.0.0.1, while the VirtualHost handling the redirect is on 10.0.0.2; therefore, the first vhost to load on 10.0.0.1:80 handles the request. –  Shane Madden Aug 18 '11 at 3:57
    
Upvote for stealing an answer from the comments section! You win one half of an internet. meta.serverfault.com/questions/1886/… –  Wesley Aug 18 '11 at 4:18
    
ok, so if they are all in separate files, what order is taken? –  jdog Aug 18 '11 at 4:46
1  
@jdog Still first to load. Say, for instance, if your main apache config is including a directory full of files that each contain a VirtualHost, they're loaded alphabetically, so the first one alphabetically will be the default for that IP:port combination. –  Shane Madden Aug 18 '11 at 5:27
    
@shane you put me to shame with your succinctness :) –  Marty Aug 18 '11 at 5:41
show 3 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.