72

If I have 3 domains, domain1.com, domain2.com, and domain3.com, is it possible to set up a default virtual host to domains not listed? For example, if I would have:

<VirtualHost 192.168.1.2 204.255.176.199>
DocumentRoot /www/docs/domain1
ServerName domain1
ServerAlias host
</VirtualHost>

<VirtualHost 192.168.1.2 204.255.176.199>
DocumentRoot /www/docs/domain2
ServerName domain2
ServerAlias host
</VirtualHost>

<VirtualHost 192.168.1.2 204.255.176.199>
DocumentRoot /www/docs/everythingelse
ServerName *
ServerAlias host
</VirtualHost>

If you register a domain and point it to my server, it would default to everythingelse showing the same as domain3. Is that possible?

0

10 Answers 10

45

Yes, that should work, except ServerAlias should be "*", with ServerName set to an actual hostname. You might need to make sure that VirtualHost is the very last loaded...

5
  • It should work, but doesn't. If a domain is not specifically listed, I get "Firefox can't find the server."
    – SJaguar13
    Nov 6, 2009 at 22:22
  • 2
    Did you set it as "ServerName host" and "ServerAlias *"? I didn't emphasize this enough originally, but ServerName does not take wildcards, only ServerAlias does. ServerName needs to be an actual hostname.
    – freiheit
    Nov 6, 2009 at 22:44
  • Also, do the other virtualhosts work? What version of apache?
    – freiheit
    Nov 6, 2009 at 22:46
  • "Firefox can't find the server." is not an apache problem. You need more detail (what server if any is contacted, what is the error code...)
    – Law29
    Nov 30, 2015 at 22:11
  • 1
    Weird that does not work for me, it always picks the first virtualhost regardless of host header
    – jjxtra
    Jun 1, 2019 at 18:59
96
+50

When using name-based virtual hosts, the first virtual host configuration loaded will be the default (Source: Apache Wiki). For example, with the configuration below, otherwise unmatched domains will match with domain-one.com:

NameVirtualHost *:80

<VirtualHost *:80>
  ServerName domain-one.com
  # Other options and directives ..
</VirtualHost>

<VirtualHost *:80>
  ServerName domain-two.com
  # Other options and directives ..
</VirtualHost>

Many servers do not have a monolithic configuration file, but have several host-specific configuration files organized as follows:

/etc/apache2
|-- sites_available  (actual configuration files)
`-- sites_enabled    (symlinks to files in sites_available)

In this case, to make a particular virtual host configuration load first, rename the symlink to something which will be first when sorted, such as 00-default.


Some of the other answers are not quite correct. According to the Apache Wiki, not setting a ServerName in a virtual host is incorrect. If the host without a ServerName is not loaded first, Apache may never even use it, since the first host loaded would be the default.

Furthermore, while ServerAlias * will indeed match anything, it may also override other virtual hosts defined later. Maybe this approach would work if it's always the last virtual host to be defined (as in the configuration given in the question), but this means adding a new directive and changing the sort order instead of just changing the order as above.

6
  • 3
    + 1 million internets to you Sir! It has to be first to be default.
    – Ryan
    Jun 11, 2012 at 15:14
  • Do you know which one comes first, httpd.conf or conf.d/xyz.conf?
    – Esa Varemo
    Sep 16, 2012 at 21:59
  • 2
    "the first virtual host configuration loaded will be the default" solved my problem with local SSL domains on XAMPP (Windows). It looks like Apache uses first vhost as defaults for each port, so in order to properly handle non-matched domains for both unsecured/secured requests, there should be 2 explicit "default" configs for 80/443 ports defined at the beginning of httpd-vhosts.conf
    – Wirone
    Apr 17, 2015 at 7:17
  • 1
    @EsaVaremo - httpd.conf will be loaded first, and it will have an Include line that sources conf.d/xyz.conf (or likely, conf.d/*). any config (including vhosts) before the Include line will be processed first; anything after the include line is processed after the included files.
    – Dan Pritts
    May 1, 2015 at 15:48
  • Thank you so much for mentioning ServerAlias *. Jun 14, 2021 at 13:18
7

Don't specify a servername, and that becomes your default vhost..

<VirtualHost *:80>
ServerAdmin webmaster@localhost

DocumentRoot /var/www
<Directory />
    Options FollowSymLinks
    AllowOverride None
</Directory>
<Directory /var/www/>
    Options Indexes FollowSymLinks MultiViews
    AllowOverride None
    Order allow,deny
    allow from all
</Directory>
</VirtualHost> 

Also be sure that you haven't specified a DocumentRoot in the main httpd.conf file, as that will take precedence over the vhosts.

2
  • I have that as the first virtual host listed, and I still get "Firefox can't find the server."
    – SJaguar13
    Nov 8, 2009 at 6:18
  • 2
    I disagree. I had my first virtual host set without a ServerName, however, it seems to conflict with some virtual hosts, but not others. I solved the issue by adding a ServerName, but setting it to some random domain that's not on my server. Since it's the first virtual host, it's used as the default, but only matches when a domain not matched to any other ServerName is used.
    – joshaidan
    Jul 9, 2013 at 16:20
2

Order is important - move your vhost definition for everything else to the head of the list.

2

Use the _default_ virtual host and place it first in httpd-vhosts.conf as specified in http://httpd.apache.org/docs/2.2/vhosts/examples.html

"Catching every request to any unspecified IP address and port, i.e., an address/port combination that is not used for any other virtual host [...] A default vhost never serves a request that was sent to an address/port that is used for name-based vhosts. If the request contained an unknown or no Host: header it is always served from the primary name-based vhost (the vhost for that address/port appearing first in the configuration file)."

Snippet from a live but obfuscated httpd-vhosts.conf which happens to lock all vhosts to port 80:

# Listen for virtual host requests on all IP addresses.
# This directive cannot be removed:
NameVirtualHost *:80

<VirtualHost _default_:80>
# This vhost catches client requests with host headers which have
# not been matched by ServerName or ServerAlias directives in other vhosts.
#
# We redirect all such requests to a particular named vhost:
    RewriteCond %{HTTP_HOST}    ^(.*)$
    RewriteRule ^(.*)$  http://my.site.of.choice [R=permanent,L]
</VirtualHost>

# Name based vhosts here:
<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    ServerName  my.other.site
    ServerAlias my.other.site2 my.other.site3
</VirtualHost>

# more vhosts etc...

An in-depth explanation of the vhost matching process can be found here: http://httpd.apache.org/docs/2.2/vhosts/details.html

1
  • 3
    _default_ is used only for non-matched IPs, so when you have wildcarded vhost (*:80) it will never be used.
    – Wirone
    Apr 17, 2015 at 7:38
2

Wildcard include your site configuration files:

Include path/to/site/confs/*httpd.conf

Organize your site conf files so they are loaded in an expected order. Example...

01-httpd.conf

02-site1-httpd.conf

03-site2-httpd.conf

etc...

Apache will read these in order. Then create one that will always load last to catch any unmatched virtual hosts and return a 404 instead of loading a default site.

99-catchall-httpd.conf

<VirtualHost *:8080>
 ServerName null
 ServerAlias *
 Redirect 404 /
</VirtualHost>

<VirtualHost *:8443>
 ServerName null
 ServerAlias *
 Redirect 404 /
</VirtualHost>

Be sure to replace the ports with whatever ports your httpd listens on. Or if you have httpd listening on specific interfaces, you'll need to add a catchall for each interface instead, like so:

<VirtualHost 192.168.1.101:8080>
 ServerName null
 ServerAlias *
 Redirect 404 /
</VirtualHost>
<VirtualHost 192.168.1.101:8443>
 ServerName null
 ServerAlias *
 Redirect 404 /
</VirtualHost>

<VirtualHost 192.168.1.102:8080>
 ServerName null
 ServerAlias *
 Redirect 404 /
</VirtualHost>

<VirtualHost 192.168.1.102:8443>
 ServerName null
 ServerAlias *
 Redirect 404 /
</VirtualHost>

Hope this helps. I use this method to load sites in the order I specify and prevent unmatched virtual hosts from loading an unexpected site unintentionally.

0

The best solution is to rename the site configuration file starting with a "1" so it will load first and that will be your default site.

Apache2 makes the first loaded vhost file as the default page.

1
  • default apache installation also has 000-default virtual host for this reason.
    – vp_arth
    Nov 5, 2015 at 9:23
0

when using <VirtualHost *:port> and specifying ServerName/ServerAlias for the hosts you care about, which is what I needed to do.

A bit of background in my situation:

I have a dynamic IP address from my ISP so my IP address is registered at a dynamic IP address registering company (noip.org in my case). One of my "hosts" needed to be registered at my DNS registration as myabc.example.com as a CNAME which points to host1.ddns.net. But host2.ddns.net was left as is. I wanted myabc.example.com and host1.ddns.net to go to site1 and host2.ddns.net to go to site 2 and anything else including my IP address to go to default.

The first conf file read will be the default, i.e. 000_def.conf, 001_site1.conf, 002_site2.conf will be read in that order with 000_def.conf as the default site. (note: in my case, I have these "files" in /etc/apache2/sites-enabled which are actually dynamic links to the actual conf file in /etc/apache2/sites-available)

Because ServerName is being used in 001_site1.conf and 002_site2.conf, it must also be set to something in 000_def.conf.

# 000_def.conf:
<VirtualHost *:80>  
ServerName null
# NOTE: DO NOT USE "ServerAlias *" this seems to override the other conf files.
</VirtualHost>


# 001_site1.conf
<VirtualHost *:80>  
ServerName myabc.example.com
ServerAlias mylocalhostname host1.ddns.net
</VirtualHost>


# 002_site2.conf:
<VirtualHost *:80>  
ServerName host2.ddns.net
</VirtualHost>
0

In addition to the answers given here (especially the one from @Jason Blevins), there is a potential pitfall here. It took me some time to figure this out.

As stated, Apache will use the first VirtualHost entry if no other entry matches einther the HostName or HostAlias directive.

However, be careful when you mix virtual hosts that are tied to a specific IP address and some that are not (<VirtualHost 192.168.1.1:80> vs. <VirtualHost *:80>).

If a request is made to an IP address that has one or more IP-bound virtual hosts, it will use the first VirtualHost entry tied to that address, even if it is not the first one. In other words, more specific matches are preferred to the unspecific ones on the IP address match, too.

Example

<VirtualHost *>
DocumentRoot /www/docs/domain1
ServerName host1.exmple.com
ServerAlias host
</VirtualHost>

<VirtualHost 192.168.1.1>
DocumentRoot /www/docs/domain2
ServerName host2.exmple.com
ServerAlias host
</VirtualHost>

If a request is made to host foobar.example.com, and that resolves to 192.168.1.1, Apache will serve from /www/docs/domain2, which may be unexpected.

To solve this, either...

  • make all virtual hosts IP-independent (<VirtualHost *>), or
  • add a separate default VirtualHost entry for each IP address served.

If in doubt, run apachectl -S (or whatever command is appropriate on your system) to get a list of VirtualHosts. It will tell you which one is used as default.

0

Aardvark technique

On Apache 2.4.x, Ubuntu 20.04, there is no httpd.conf file.

Virtually hosted sites are configured using /etc/apache2/sites-available/, and enabled using a symbolic link in /etc/apache2/sites-enabled, I use the following technique to address the default host glitch.

Set up a fake site called aardvark.aaa and map it to a default page. It works because in Apache2, virtual hosts are loaded alphabetically, and aardvark.aaa will be the first. (If you have a site named aaa.com, you're out of luck :^)

  1. Copy /etc/apache2/sites-available/000-default.conf to /etc/apache2/sites-available/aardvark.aaa.conf.

sudo cp 000-default.conf aardvark.aaa.conf

Configure like so

    ServerAdmin [email protected]
    ServerName aardvark.aaa
    ServerAlias www.aardvark.aaa
    DocumentRoot /var/www/aardvark
  1. Create a symbolic link in /etc/apache2/sites-enabled/ to your config file in ~/sites-available. This will cause the site to be enabled, loaded, and visible in browser:

ln -s ../sites-available/aardvark.aaa.conf

  1. Create an /var/www/aardvark/index.html file in /var/www/ like so

    $ cat > index.html

    hello, world

[CTRL-D]

  1. Bounce your server

    $ sudo systemctl restart apache2

  2. Confirm that aardvark.aaa is loaded first with this command

    $ sudo apache2ctl -S

    root@ip-172-26-2-167:/etc/apache2/sites-enabled# sudo apache2ctl -S VirtualHost configuration: *:80 is a NameVirtualHost default server aardvark.aaa (/etc/apache2/sites-enabled/aardvark.aaa.conf:1) port 80 namevhost aardvark.aaa (/etc/apache2/sites-enabled/aardvark.aaa.conf:1) alias www.aardvark.aaa

  3. Browse to your host/ip address. You should see:

    hello, world

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .