0

I have this default 000-default.conf:

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

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined
</VirtualHost>

And this one I created, my.conf:

<VirtualHost *:80>
    ServerName example.com
    DocumentRoot /var/www/html
    Redirect permanent / https://example.com/
</VirtualHost>

<IfModule mod_ssl.c>
    <VirtualHost *:443>
        ServerName example.com
        DocumentRoot /var/www/html
        SSLEngine on
        ...
    </VirtualHost>
</IfModule>

If I try example.com on the browser, I get redirected to https://example.com/, which is fine.

But if I try 123.45.67.89 I also get redirected to https://example.com/.

Since both virtual servers (*:80) are a match for 123.45.67.89, and no ServerName is a match for 123.45.67.89, I expected Apache 2.4 to select the one in 000-default.conf. But it is not. Why?

My reference is this:

If multiple virtual hosts contain the best matching IP address and port, the server selects from these virtual hosts the best match based on the requested hostname. If no matching name-based virtual host is found, then the first listed virtual host that matched the IP address will be used

2 Answers 2

0

Your default Name-Based Virtual Host is missing the ServerName.

If you omit the ServerName directive from any name-based virtual host, the server will default to a fully qualified domain name (FQDN) derived from the system hostname. This implicitly set server name can lead to counter-intuitive virtual host matching and is discouraged.

It might be that the derived FQDN is matching the hostname in the second virtual host, causing unintuitive problems in Virtual Host Matching.

The same is also suggested and explained in Issues Regarding DNS and Apache HTTP Server:

In order for the server to function properly, it absolutely needs to have two pieces of information about each virtual host: the ServerName and at least one IP address that the server will bind and respond to.

# This is a misconfiguration example, do not use on your server
<VirtualHost 192.0.2.1>
  ServerAdmin webgirl@example.dom
  DocumentRoot "/www/example"
</VirtualHost>

This time httpd needs to use reverse DNS to find the ServerName for this virtualhost. If that reverse lookup fails then it will partially disable the virtualhost. If the virtual host is name-based then it will effectively be totally disabled.

Add something to the ServerName. Anything. Your first <VirtualHost> will still be the default unless there's another match. It can even be the IP address. Just don't leave it unspecified. Use e.g.

  • ServerName 198.51.100.10 (with your server's IP) or
  • ServerName default-catch-all.example.org
3
  • I will try. But before that, let's imagine this derived FQDN is matching the hostname in the second virtual host. Now we have two *:80 with ServerName example.com. I'm accessing it by IP on port 80, so both are initially matches, but then none of them are ServerName matches. In this case it should choose the first listed, which is 000-default. But no, it is choosing the one in my.conf.
    – Gustavo
    May 31, 2017 at 11:34
  • Here, I found this: This time (without ServerName) httpd needs to use reverse DNS to find the ServerName for this virtualhost. If that reverse lookup fails then it will partially disable the virtualhost. If the virtual host is name-based then it will effectively be totally disabled. Maybe the default virtual host is being ignored.
    – Gustavo
    May 31, 2017 at 12:08
  • Yes, that was the other condition. I just couldn't find the reverse DNS fallback explained anywhere at the moment. The suggestion is still exactly the same, I just modified my answer to cover this. May 31, 2017 at 13:11
0

The first listed host depends on the order the configuration is loaded. Different distributions have different mechanisms for loading the files.

On Ubuntu, sites should be defined in /etc/apache2/sites-available. These are enabled by creating a link in /etc/apache2/sites-enabled. The enabled sites are loaded in canonical order from that directory. Files in sites-available that are not linked to sites-enabled are not loaded.

The configuration loads files from /etc/apache2/mods-enabled and etc/apache2/conf-enabled are loaded prior to loading sites from sites-enabled.

If you enable the info module, you should be able to review the configuration by navigating to https://www.example.com/server-info. Check the order of the virtual hosts on this page.

It is also possible to place Redirects in .htaccess file located in the document directory. It is also possible to place redirection directives inside containers other than a Virtualhost container.

You may want to verify which redirections are occurring by dumping the server headers. I use a command like wget -qSO /dev/null http://192.0.2.22. This will show the headers from each redirection.

6
  • I'm using Ubuntu 16. Both conf are in sites-available and linked in sites-enabled.
    – Gustavo
    May 31, 2017 at 1:23
  • @Gustavo What order are they in sites-enabled?
    – BillThor
    May 31, 2017 at 1:34
  • When I ls -la, 000-default.conf is the first in the list.
    – Gustavo
    May 31, 2017 at 1:39
  • @Gustavo I've updated my response.You may also want to investigate how to log redirections.
    – BillThor
    May 31, 2017 at 2:00
  • server-info showed the order I expected. The redirection: wget -qSO /dev/null http://123.45.67.89 HTTP/1.1 301 Moved Permanently Date: Wed, 31 May 2017 19:19:58 GMT Server: Apache/2.4.18 (Ubuntu) Location: https://example.com/ Content-Length: 308 Keep-Alive: timeout=5, max=100 Connection: Keep-Alive Content-Type: text/html; charset=iso-8859-1
    – Gustavo
    May 31, 2017 at 19:24

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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