7

I thought I'd followed the accepted wisdom in redirecting HTTP traffic to HTTPS, but following a DNS issue today, and having to use an IP address instead of the URL, I realise something's amiss.

Apache.conf:

<VirtualHost *:80>
   ServerName 127.0.0.1

   DocumentRoot /var/www/web
</VirtualHost>

<VirtualHost _default_:443>
   ServerName example.com

   DocumentRoot /var/www/web
   SSLEngine On
   SSLCertificateFile      /etc/ssl/local_certs/example.com.pem
   SSLCertificateKeyFile /etc/ssl/local_certs/example.com.pem.key
   Header set Access-Control-Allow-Origin "*"
</VirtualHost>

<VirtualHost *:80>
   ServerName example.com

   Redirect permanent "/" "https://example.com/"
</VirtualHost> 

Given the above I'm confused by several points:

1) If we're now using an IP address, why are any of the above ServerName specific virtual hosts serving a page? This would confuse me less if the IP address I'm using currently corresponded to the domain name (it should, but today it doesn't, DNS issue).

2) Given the IP address I'm using isn't 127.0.0.1, why am I allowed access on port 80?

To explain the 127.0.0.1 host, this is a convenience for a local apt repository. I'm aware ServerName isn't 100% secure, but that's not an immediate concern.

What happens when I browse to the site by IP:

In the first instance I am redirected to HTTPS on the same IP address, which is what I might expect. But, if I go back the address bar in the browser and remove the 's' from https, it navigates me to the page on port 80 without a redirect, and I'm free to continue browsing the site unsecured.

I should add that the out-of-the-box enabled/available site config files do still exist, but these have a document root of /var/www/html, which contains nothing other than the default apache index.html landing page, which isn't what I'm served.

1
  • Can you also include your Listen and NameVirtualHost directives?
    – Vilx-
    Jan 17, 2019 at 18:37

3 Answers 3

8

Quote from the documentation:

If no matching ServerName or ServerAlias is found in the set of virtual hosts containing the most specific matching IP address and port combination, then the first listed virtual host that matches that will be used.

(highlighting not by me).

In other words, Apache will always use one of the VirtualHosts, even if none of the configured VirtualHosts matches exactly. Not configuring an address does not mean that the address is not server some content.

(Note: only after posting this I realized that the question is tagged with apache-2.2, but the 2.2 documentation contains a virtually identical paragraph).

5
  • Ok, so move 443 to the top would be safest in my situation?
    – whoasked
    Jan 17, 2019 at 11:23
  • 1
    No, it would not make any difference. You will have to configure a virtualhost for the IP address, or a default virtualhost that is used for everything that isn't configured specifically. Remember, anybody can point any domain that he owns to your IP address. Jan 17, 2019 at 11:24
  • 1
    So if the bottom host became <VirtualHost *:*>? Sorry to press I'll go back to google ...
    – whoasked
    Jan 17, 2019 at 11:28
  • No, for every address that is not configured the first virtualhost (with the same port) will be used. Jan 17, 2019 at 11:29
  • 2
    You don't need Google, you need the documentation, except you don't, because the relevant part was already quoted in this answer, so you just need to read the answer. :) Jan 17, 2019 at 16:30
6

2) Given the IP address I'm using isn't 127.0.0.1, why am I allowed access on port 80?

Because you don't bind/restrict Apache httpd to the loopback interface specifically, and listen to all interfaces.

You probably have a Listen 80 directive elsewhere in your httpd.conf that allows Apache to accept traffic to port 80 on all interfaces. (You probably want to keep that to be able to continue to Redirect from HTTP to HTTPS on your internet facing website(s)).

Additionally you use <VirtualHost *:80> in your Virtual Host definitions. That makes them valid on all interfaces/ip-addresses. As Gerald Scneider already explained that then makes the first VirtualHost entry the default that will handle all requests that don't match any of your other VirtualHost entries.

Your use case is good example on when to use more specific IP-based VirtualHost definitions that will more predictably behave in the way you intend them:

<VirtualHost 127.0.0.1:80>
   ServerName 127.0.0.1
   DocumentRoot /var/www/web
</VirtualHost>


<VirtualHost example.com:80>
   ServerName example.com
   Redirect permanent "/" "https://example.com/"
</VirtualHost> 
0

Apache will look from beginning to end.

1st Case: If you call server through i.p with http ex: http://server_ip. This will match on 1st virtualHost and serve your /var/www/web folder files.

2nd Case: If you call server through domain with http ex: http://example.com. This will match on 2nd virtualHost and forcefully redirect to https://example.com

3rd Case: If you call server through domain with https ex: https://example.com. This will macth on 3rd virtualHost.

#1st Case 
    <VirtualHost *:80>
       ServerName server_ip
       DocumentRoot /var/www/web
    </VirtualHost>

#2nd Case
    <VirtualHost *:80>
       ServerName example.com
       Redirect permanent "/" "https://example.com/"
    </VirtualHost>

#3rd Case  
    <VirtualHost _default_:443>
       ServerName example.com
       DocumentRoot /var/www/web
       SSLEngine On
       SSLCertificateFile      /etc/ssl/local_certs/example.com.pem
       SSLCertificateKeyFile /etc/ssl/local_certs/example.com.pem.key
       Header set Access-Control-Allow-Origin "*"
    </VirtualHost>

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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