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

Gustavo
  • 147
  • 1
  • 8

2 Answers2

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.

BillThor
  • 27,737
  • 3
  • 37
  • 69
  • I'm using Ubuntu 16. Both conf are in sites-available and linked in sites-enabled. – Gustavo May 31 '17 at 01:23
  • @Gustavo What order are they in sites-enabled? – BillThor May 31 '17 at 01:34
  • When I `ls -la`, `000-default.conf` is the first in the list. – Gustavo May 31 '17 at 01:39
  • @Gustavo I've updated my response.You may also want to investigate how to log redirections. – BillThor May 31 '17 at 02: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 '17 at 19:24
  • @Gustavo See https://serverfault.com/questions/10796/apache-where-to-examine-the-redirection-logs for details on logging rewrites. Try temporarily modifying the rewrite in the site file, or even disabling it to test that that is the the redirect that is invoked. – BillThor Jun 03 '17 at 00:12
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
Esa Jokinen
  • 46,944
  • 3
  • 83
  • 129
  • 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 '17 at 11:34
  • [Here](https://httpd.apache.org/docs/2.4/dns-caveats.html#tips), 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 '17 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. – Esa Jokinen May 31 '17 at 13:11