45

How can I set a default VirtualHost in Apache?

Preferably, I want the default host not to be the same as the IP address host. Now I have something like this:

NameVirtualHost *

<VirtualHost *>
    ServerAdmin admin@example.com
    DocumentRoot /someOtherDir/
    ServerAlias ip.of.the.server
</VirtualHost>

<VirtualHost *>
    ServerAdmin admin@example.com
    DocumentRoot /someroot/
    ServerAlias example.com *.example.com
</VirtualHost *>

If a domain is forwarded to my server, but isn't in this vhost.conf file, the files from /someOtherDir/ are loaded, as expected. But I want to be able to use a different root for the IP address itself and domains which aren't added to the vhost.conf file (yet). Is this possible?

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Tiddo
  • 6,331
  • 6
  • 52
  • 85

10 Answers10

63

I found the answer: I remembered that Apache uses the first block if no other matching block is found, so I've added a block without a serveralias at the top of the blocks:

NameVirtualHost *

<VirtualHost *>
    DocumentRoot /defaultdir/
</VirtualHost>

<VirtualHost *>
    ServerAdmin admin@example.com
    DocumentRoot /someOtherDir/
    ServerAlias ip.of.the.server
</VirtualHost>

<VirtualHost *>
    ServerAdmin admin@example.com
    DocumentRoot /someroot/
    ServerAlias example.com *.example.com
</VirtualHost>
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Tiddo
  • 6,331
  • 6
  • 52
  • 85
  • 2
    Actually - I had to add `ServerName fake.example.com` to the "default" vhost. – Kris Nov 13 '13 at 14:57
  • 15
    The order of the files changed (alphabetically sorted) so my default suddenly stopped working. I'd suggest to put the config in the ```000-default.conf``` file. – Birla Jul 07 '14 at 06:33
  • 7
    Didnt work for me until I place the port number 80. ie. instead of just . I'm using Apache 2.4 on CentOS 7. – Basil Musa Dec 31 '15 at 11:18
12

If you are using Debian style virtual host configuration (sites-available/sites-enabled), one way to set a Default VirtualHost is to include the specific configuration file first in httpd.conf or apache.conf (or what ever is your main configuration file).

# To set default VirtualHost, include it before anything else.
IncludeOptional sites-enabled/my.example.com.conf

# Load config files in the "/etc/httpd/conf.d" directory, if any.
IncludeOptional conf.d/*.conf

# Load virtual host config files from "/etc/httpd/sites-enabled/".
IncludeOptional sites-enabled/*.conf
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
harmaahylje
  • 150
  • 1
  • 6
9

The other answers here didn't work for me, but I found a pretty simple solution that did work.

I made the default one the last one listed, and I gave it ServerAlias *.

For example:

NameVirtualHost *:80

<VirtualHost *:80>
    ServerName www.secondwebsite.example
    ServerAlias secondwebsite.example *.secondwebsite.example
    DocumentRoot /home/secondwebsite/web
</VirtualHost>

<VirtualHost *:80>
    ServerName www.defaultwebsite.example
    ServerAlias *
    DocumentRoot /home/defaultwebsite/web
</VirtualHost>

If the visitor didn't explicitly choose to go to something ending in secondwebsite.example, they get the default website.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
ArtOfWarfare
  • 20,617
  • 19
  • 137
  • 193
  • 1
    Note that a wildcard alias does not make the host the default. The default is still the first host defined, which has side effects. Eg, if the first host uses SSLStrictSNIVHostCheck, then that will apply to all hosts, which is surprising. It's best to define a fake host, ensure it is first so it will be the default, then use a wildcard alias, which must be defined last, for the host you want to handle anything not otherwise matched. – NateS Jan 24 '20 at 11:25
5

Actually, I'm using Virtual host configuration (sites-available / sites-enabled) on EC2 Linux AMI with Apache/2.4.39 (Amazon). So, I have 1 EC2 instance to serve many sites (domains).

Considering that you already have Virtual Host installed and working. In my folder /etc/httpd/sites-available, I have some files with domain names (suffix .conf), for example: example.com.conf. Create a new file like that.

sudo nano /etc/httpd/sites-available/example.com.conf

<VirtualHost *:80>
    ServerName www.example.com
    ServerAlias example.com
    DocumentRoot /var/www/html/domain
</VirtualHost>

For each file.conf in sites-available, I create a symbolic link:

sudo ln -s /etc/httpd/sites-available/example.com.conf /etc/httpd/sites-enabled/example.com.conf

This is the default configuration, so, if access directly by IP of Server, you will be redirect to DocumentRoot of the first file (.conf) in sites-available folder, sorted by filename.

To have a default DocumentRoot folder when access by IP, you have to create a file named 0a.conf, then Apache will serve this site because this new file will be the first in sites-available folder.

You must create a symbolic link:

sudo ln -s /etc/httpd/sites-available/0a.conf /etc/httpd/sites-enabled/0a.conf

To check serving order, use it:

sudo apachectl -S

Now, restart Apache, and check out it.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
LuizEduardoMPF
  • 876
  • 9
  • 14
  • 2
    creating/removing symbolic links between sites-enabled and sites-available are taken care of by the utilities that are installed alongside apache when you install from package. `sudo a2ensite your_domain.conf` will create the symbolic link in sites-enabled (thus enabling the vhost), and `sudo a2dissite your_domain.conf` will remove the symbolic link (thus disabling the vhost) – Rayanth Jul 14 '20 at 23:16
3

Obligatory - none of the previous answers worked for me. I inherited a strange combination of IP address-based virtual hosts and * vhosts (not assigned/catch all IP addresses) based virtual hosts in this Apache configuration messed up by ISPConfig.

I wanted Apache to serve not configured hosts with the same page.

I had: not configured hosts went to the first vhost after 000-default.conf. No matter I had *:80 catch all defined as the first vhost, instead of default Apache would load first defined site:

<VirtualHost *:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html
</VirtualHost>

Although it's not completely valid configuration, what finally worked was adding an IP address-based virtualhost without ServerName/ServerAlias defined:

<VirtualHost 192.168.10.10:80>
    ServerAdmin webmaster@localhost
    DocumentRoot /var/www/html
</VirtualHost>

<VirtualHost 192.168.10.10:443>
  ServerAdmin webmaster@localhost
  DocumentRoot /var/www/html
  SSLEngine On
  ...
</VirtualHost>

$ apachectl -S outputs IP address-based vhosts first, and * based vhosts later, and finally my default site is loaded before real site:

AH00548: NameVirtualHost has no effect and will be removed in the next release /etc/apache2/sites-enabled/000-default.conf:50
192.168.10.10:80        is a NameVirtualHost
         default server server.tld (/etc/apache2/sites-enabled/000-default.conf:34)
         port 80 namevhost server.tld (/etc/apache2/sites-enabled/000-default.conf:34)
         port 80 namevhost some-site.tld (/etc/apache2/sites-enabled/100-some-site.tld.vhost:7)

...

46.23.86.103:443       is a NameVirtualHost
         default server server.tld (/etc/apache2/sites-enabled/000-default.conf:38)
         port 443 namevhost server.tld (/etc/apache2/sites-enabled/000-default.conf:38)
         port 443 namevhost some-site.tld (/etc/apache2/sites-enabled/100-some-site.tld.vhost:182)

...

*:80                   is a NameVirtualHost
         default server server.tld (/etc/apache2/sites-enabled/000-default.conf:1)
         port 80 namevhost server.tld (/etc/apache2/sites-enabled/000-default.conf:1)

Word of notice - in a configuration like this, * vhosts won't work, so you need to apply IP addresses to all vhosts.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
seven
  • 2,388
  • 26
  • 28
1

An alternative setting is to have the default virtual host at the end of the config file rather than the beginning. This way, all alternative virtual hosts will be checked before being matched by the default virtual host.

Example:

NameVirtualHost *:80
Listen 80

...

<VirtualHost *:80>
        ServerName host1
        DocumentRoot /someDir
</VirtualHost>

<VirtualHost *:80>
        ServerName host2
        DocumentRoot /someOtherDir
</VirtualHost>

<VirtualHost *:80>
        DocumentRoot /defaultDir
</VirtualHost>
eaykin
  • 3,713
  • 1
  • 37
  • 33
  • 2
    According to https://wiki.apache.org/httpd/CommonMisconfigurations#Not_setting_a_ServerName_in_a_virtual_host. this is a common misconfiguration and wouldn't work. – jlh Jul 03 '17 at 09:16
1

I had the same issue. I could fix it by adding the following in httpd.conf itself before the IncludeOptional directives for virtual hosts. Now localhost and the IP 192.168.x.x both points to the default test page of Apache. All other virtual hosts are working as expected.

<VirtualHost *:80>
    DocumentRoot /var/www/html
</VirtualHost>

Reference: https://httpd.apache.org/docs/2.4/vhosts/name-based.html#defaultvhost

-1

The NameVirtualHost option would be a good option.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Rasika
  • 1,980
  • 13
  • 19
  • 7
    can you provide an example? I already have the line NameVirtualHost * at the top of this document. How do I need to change that if I want to have a default page? – Tiddo Mar 25 '11 at 01:04
  • Can you extend your answer? By [editing your answer](https://stackoverflow.com/posts/5427411/edit) (***without*** "Edit:", "Update:", or similar - the answer should appear as if it was written today). – Peter Mortensen Feb 12 '21 at 13:44
-1

Only supported and correct answer is:

<VirtualHost _default_:*>
    DocumentRoot "/www/default"
</VirtualHost>

or my own version to return 403:

<VirtualHost _default_:*>
    <Location />
        Require all denied
    </Location>
</VirtualHost>
CrazyRabbit
  • 251
  • 3
  • 10
-2

The solution is:

# apache2.conf

# @warning this is specific to apache 2.2
NameVirtualHost *:80
Listen 80

# ...
# aaaa.example.conf

<VirtualHost *:80>
    ServerName aaaa.example
    DocumentRoot /defaultDir
</VirtualHost>
# host1.example.conf

<VirtualHost *:80>
    ServerName host1.example
    DocumentRoot /someDir
</VirtualHost>
# host2.example.conf

<VirtualHost *:80>
    ServerName host2.example
    DocumentRoot /someOtherDir
</VirtualHost>

In my case, to work, I created a VirtualHost (n.e. VirtualHost per CNAME) called aaaa.example since I have different files for different VirtualHosts and knowing that Apache reads them in alphabetical order.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Cocfay
  • 1